Wednesday, January 22, 2014

Start a java program from another java program programmatically

That's the thing I had to perform today. Let's introduce the need : I developed last year a standalone java program that I can start from command line. Now, I want to start it from a web application. As the program is complex (some Spring Batch stuffs), I don't want to make an heavy integration. So, I decided to embed its jar in my webapp (WEB-INF/lib). All I had to do was to find an elegant way to start a dedicated java virtual machine from my webapp to run my program without consequence on my web application.

The most elegant way I found was to use ANT... programmatically. In the following example, I wrote two classes. The MainProgram represents my webapp and the ProgramToRun represents my Spring Batch application. To simplify the code,  I didn't create a specific classpath for the ANT task but keep in mind that it's possible.

Look at the code, isn't it easy and cool?


public class MainProgram {

public static void main(String[] args) {
Project project = new Project();
project.setBaseDir(new File(System.getProperty("user.dir")));
project.init();
DefaultLogger logger = new DefaultLogger();
project.addBuildListener(logger);
logger.setOutputPrintStream(System.out);
logger.setErrorPrintStream(System.err);
logger.setMessageOutputLevel(Project.MSG_INFO);
project.fireBuildStarted();
System.out.println("running");
Throwable caught = null;
try {
Echo echo = new Echo();
echo.setTaskName("Echo");
echo.setProject(project);
echo.init();
echo.setMessage("Launching Some Class");
echo.execute();

Java javaTask = new Java();
javaTask.setTaskName("runjava");
javaTask.setProject(project);
javaTask.setFork(true);
javaTask.setCloneVm(true);
javaTask.setFailonerror(true);
javaTask.setClassname(ProgramToRun.class.getName());
Variable aParam = new Variable();
aParam.setKey("myParam");
StringBuilder builder = new StringBuilder();
builder.append("Yeah!! I catched the param");
aParam.setValue(builder.toString());
javaTask.addSysproperty(aParam);
javaTask.init();
int ret = javaTask.executeJava();
System.out.println("java task return code: " + ret);

} catch (BuildException e) {
caught = e;
}
project.log("finished");
project.fireBuildFinished(caught);
}
}


public class ProgramToRun {


public static void main(String[] args) {
System.out.println("Well done!!!");
System.out.println(System.getProperty("myParam"));
}

}


Did you see the tip? No? I passed a parameter to my external program with a system property. Let's have a look to the console output :



running
     [Echo] Launching Some Class
  [runjava] Well done!!!
  [runjava] Yeah!! I catched the param
java task return code: 0
finished

BUILD SUCCESSFUL
Total time: 0 seconds




A really nice ANT use case I discovered !!!

1 comment:

simashree said...

Thanks for the great information in your blog Selenium Training in Chennai

Download Oracle JDK from command line

Found on the web. You can adapt the url with one grabbed from Oracle JDK download page. What I love here is the fact is send Oracle licence ...