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 !!!
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 !!!