// Navneet Shrivastava,31/10/2003
?h Case
?h Common way...
?h Need for Dynamic Compilation
?h Pros & Cons
Case:
client sends a request with amount as a parameter.Depending on the type of client.. we have diferent logic to process the request.
Common way...
Approach 1:
1) we havw one source file (source.java) ...this file has our logic
2) we compile this file using java compiler...will have 'source.class' file
3 )we run the java prog. and have our task done
client sends a request with amount as a parameter.Depending on the type of client.. we have diferent logic to process the request.....but wht if you have got huge codes(logical part) to be embedded within...it increases maintenance
...so we opt for modular approach
lets say we have
1)source.java...invokes methods from 'client_logic1.java' and 'client_logic2.java'...depending on type of client.
2)client_logic1.java...having logic for processing request from client of type1
3)client_logic2.java...having logic for processing request from client of type2
Improved Approach...
Approach 2:
1) we have source.java ...this file is creating objects from class defined in 'client_logic1.java' and 'client_logic2.java'
2) we compile these files using java compiler...will have 'source.class' , 'client_logic1.class' and 'client_logic2.class' .
3 )we run 'source' , this at runtime determines the type of client , on basis of type of client it invokes method from corresponding file...... and have our task done
but what if processing logics are very unstable and needs to be updated frequently.....we need to update 'client_logic1.java' and 'client_logic2.java'...and recompile them .....automating these task will facilitate the admin to be concerned about updating logic.....everything else(recompiling the updated files will be taken care by application itself)....
Advanced Approach...
Approach 3:
1) we have source.java ...this file is determines the type of client.....
2) checks for any updation in logic file for corresponding client...
3) recompiles the logic files if any updation is detected in corresponding file....
4) invokes the method required..and get the task done
//////////////////sample code/////////////////////////////////////////////////////////////////
/* this sample code works in the following manner
it reads the property file gets the key values.....
determines if .java file needs to be recompiled...
recompiles the .java file at runtime if required....
invokes the eerquired method ...and get or task done */
//----------------------------------------------------------------------------------------------------------------------------------
/* Class PhilePhilter */
import java.util.*;
import java.io.*;
import java.lang.*;
import java.lang.reflect.*;
public class PhilePhilter {
public static void main(String args[]) {
Properties prop1=new Properties();
/* =========== Using Property file============== */
//property file must be in your working dir.
String file_property = "test.properties";
FileInputStream fStream1 = null;
try{
fStream1 = new FileInputStream(file_property);
prop1.load(fStream1);
}catch(Exception e){
System.out.println("Error in creating object for FileInputStream ");
}
String key1 = "fJava_Path";
String key2 = "fClass_Path";
String key3 = "fDir_Path";
/* ==get file paths from property file== */
String fJavaPath = prop1.getProperty(key1);
String fClassPath = prop1.getProperty(key2);
String fDirPath = prop1.getProperty(key3);
System.out.println("\npath of .java file = " + fJavaPath);
System.out.println("path of .class file = " + fClassPath );
System.out.println("fDirPath = " + fDirPath +"\n");
/* ======calculating last modified time of .java file=====*/
File fJava = new File(fJavaPath);
if(fJava.exists()) {
System.out.println("Java file exists");
System.out.println("Java file was last modified at : " + fJava.lastModified()+"\n");
}
else{System.out.println("Java file does not exists");}
/* =====calculating last modified time of .class file=====*/
File fClass = new File(fClassPath);
if(fClass.exists()) {
System.out.println("Class file exists");
System.out.println("Class file was last modified at : " + fClass.lastModified()+"\n");
}
else{
System.out.println("Class file does not exists");
}
try {
Runtime r = Runtime.getRuntime();
/* =====checking for modification in b.java file after last compilation===== */
if(fJava.lastModified() > fClass.lastModified())
{
/* ====compiling file b.java==== */
Process p1 = r.exec(new String[] {"javac",fJavaPath});
while (p1.waitFor() != 0) { }
System.out.println("b.java has been modified after last compilation....thus is recompiled\n ");
}
else
{
System.out.println("b.java has not been modified after last compilation....thus is NOT recompiled\n");
}
/* ===== invoking method 'print' from 'b' ===== */
Method m = Class.forName("b").getDeclaredMethod("print", new Class[]{});
m.invoke(null, null);
} catch (Exception e) {
System.out.println("Error: " + e);
}
}
}
//----------------------------------------------------------------------------------------------------------------------------------
/* Class b */
public class b {
public static void print() {
System.out.println("Hi it's 'b'again");
}
}
//----------------------------------------------------------------------------------------------------------------------------------
rem ***test.properties***
rem path for java file to be compiled
fJava_Path=C:\\Eclipse\\eclipse\\workspace\\J2EE_Basics\\Dynamic_Compilation\\b.java
rem path for class file
fClass_Path=C:\\Eclipse\\eclipse\\workspace\\J2EE_Basics\\Dynamic_Compilation\\b.class
rem path of directory containing files
fDir_Path=C:\\Eclipse\\eclipse\\workspace\\J2EE_Basics\\Dynamic_Compilation
//----------------------------------------------------------------------------------------------------------------------------------
//////////////////sample code/////////////////////////////////////////////////////////////////
Pros & Cons:
Pros
?h to be modular,
?h to be efficient, and
?h to be easy to use(maintenance)
Cons
?h This method tends user to sacrifice platform independence. By this we lose the portability, but achieve the result.
?h In this way we satisfy the programming needs by executing external utilities and applications from within a Java program. In Java, this means employing the Runtime class exec() method. Runtime.exec() allows you to execute a program; but it does not allow us to directly control the environment (we can't set the classpath for further processing).
?h " In an environment where Java applications must coexist with other non-Java applications this will often be a valid trade-off."
In its simplest form, exec() is quite easy to use:
/* ==============L/Unix envoirnment specific command============== */
Process p = Runtime.getRuntime().exec("/bin/ls");
this won't run on other OS
?h Also the problem with this form is that it gets you nowhere. When Java spans a new process it redirects STDIN, STDOUT and STDERR. Therefore the results of "/bin/ls" do not go to the screen.
?h Also we need to supply a complete path to whatever it is that you are executing.
?h Also .class files being used by system must be kept in same folder....we can't access file from aremote location(except kept in CLASSPATH).