Quick Tip : Launch Java Applications From Java applications with Ant

One week ago, I searched a way to launch a Java application from an other Java application without loosing portability. And I found a post on StackOverflow explaining how achieve that goal using Apache Ant.

It's really easy. It use the Ant classes and simulate a project launching and a build task. In this post, we'll see a simple method to launch an application from Java.

Here is a simple method that launch an application using Ant :

package org.jtheque.osgi;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildLogger;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.DemuxOutputStream;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Java;
import java.io.PrintStream;

public class Launcher {
    private static int launchApplication(Class mainClass, String args) {
        int returnCode;

        Project project = new Project();

        project.setBasedir(System.getProperty("user.dir"));
        project.init();

        PrintStream out = System.out;
        PrintStream err = System.err;

        BuildLogger logger = new DefaultLogger();
        logger.setOutputPrintStream(out);
        logger.setErrorPrintStream(err);
        logger.setMessageOutputLevel(Project.MSG_INFO);

        project.addBuildListener(logger);

        System.setOut(new PrintStream(new DemuxOutputStream(project, false)));
        System.setErr(new PrintStream(new DemuxOutputStream(project, true)));

        project.fireBuildStarted();

        Throwable caught = null;
        try {
            project.log("Launch Application");

            Java javaTask = new Java();
            javaTask.setTaskName("Application Launcher");
            javaTask.setProject(project);
            javaTask.setFork(true);
            javaTask.setFailonerror(true);
            javaTask.setCloneVm(true);
            javaTask.setClassname(mainClass.getName());
            javaTask.setArgs(args);
            javaTask.init();

            returnCode = javaTask.executeJava();
        } catch (BuildException e) {
            caught = e;

            returnCode = -1;
        }

        project.fireBuildFinished(caught);

        System.setOut(out);
        System.setErr(err);

        return returnCode;
    }
}

Here are some explanations :

  • First, we create a new Project using the user directory as base directory and init it.
  • Then, we create a simple logger using the System.out and System.err streams and replace then with demux streams
  • After that, we create the Java task. By using setCloneVm(true), the new virtual machine will clone the properties of the current virtual machine. We must use a fork virtual machine to get the return code of the application. We set also the name of the class and the args of the launch. Finally we init and execute the task
  • Once the application is finished, we get the return code and restore the old System.out and System.err streams

It's extremely simple and portable and the code is, I think, very clean.

Related articles

  • Profile your applications with Java VisualVM
  • JR Virtual machines
  • Getting started with Play Framework
  • Develop a modular application – Implementation
  • Develop a modular application – Bases
  • JTheque licensed under Apache License 2.0
  • Comments

    Comments powered by Disqus