5

My team currently use an Ant script to execute various Java programs.

Note that I am not asking about managing the build/deployment cycle for which we are already using Maven (quite happily).

For example, we use something like the following:

<path id="lib">
  <fileset dir="path/to/lib" />
</path>

<path id="run" >
  <path refid="lib" />
</path>

<target name="aJavaProgram" >
  <java classname="path.to.AJavaProgam" 
        classpathref="run" fork="yes" failonerror="false" append="true" />
</target>

<target name="anotherJavaProgram" depends="aJavaProgram" >
  <java classname="path.to.AnotherJavaProgam" 
        classpathref="run" fork="yes" failonerror="false" append="true" />
</target>

We originally chose Ant for the following reasons (or rather I didn't choose Ant, it was that way when I joined, but I think these are good reasons for the choice):

  • it was an easy way of managing dependencies (although we now pick up these from Maven)
  • it allows us to easily build/maintain dependencies between particular jobs
  • we can deploy the Ant script, and the Java libraries, and easily run particular jobs - i.e.
    • we don't have to worry about classpaths (configured in the Ant script)
    • we don't have to worry about building jars with main classes specified in the manifest
    • we can use Ant to create / store / manage arguments passed to main() methods
  • we can plug these ant scripts into our IDEs and run the jobs from there.

Generally speaking, we have been very happy with this.

However, an increasing issue is the ant-java-shutdown hook issue - this means that if one of these Java programs fails but doesn't finish, terminating the Ant process from which it was started doesn't terminate the Java process - which then has to be done manually, and is a real bind.

Also, I'm conscious of two other (possible) factors:

So, to clarify:

  • I want a flexible approach to execute various Java programs
  • the approach that we have been using was to do this via Ant scripts, but this had the following problems:
    • terminating the Ant task does not kill the Java program
    • this "feels" like Ant is not the right tool for the job
  • how might we meet the needs specified above?
    • if not Ant, the solution should not face the termination / shutdown hook issue
  • @downvoter - I don't mind criticism, but I prefer it be constructive. Could you elaborate on why you downvoted? – amaidment Nov 29 '13 at 11:33
  • Questions asking us to recommend a tool, library or favorite off-site resource are off-topic for Programmers as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it. – gnat Nov 29 '13 at 12:03
  • 4
    @gnat - the question does specify a problem (how to easily execute a bunch of Java programs) and what has been done (we've used Ant, but this is the problem we've had...). I've rephrased the final question to ask about 'approaches' to solve this problem rather than specific 'tools' - but I suspect that any suggested 'approach' is going to recommend a 'tool'. – amaidment Nov 29 '13 at 12:38
  • What OS are you using, and which of the benefits are you willing to give up? – kdgregory Nov 29 '13 at 13:46
  • @kdgregory - should be platform independent (Windows & Unix - currently predominately Windows, but increasingly Unix). Re trade-offs - not sure, but I'll try to add some priorities on the needs above. – amaidment Nov 29 '13 at 13:54
2
+25

It sound like you are running some Java programs in a sequence and basically you were using Ant to call java as java -jar myApplication.jar ...

Normally, I see this done using shell scripts. They are simple, small, and very good for redirecting output to files, other programs, etc...

If you want something that is more cross-platform compatible, you could look into using a scripting language such as Perl or Ruby or Python, they all allow you to call java -jar myApplication.jar and it could be as simple as 1 or 2 lines to run your Java program. There are versions of all of these that are available for Windows, OS X, Linux and Unix. And you get the full flexibility of these languages, should you actually need them.

Additionally, most IDEs support launching "external"/"3rd party" tools from within the IDE, so you can write a shell (or Perl or whatever) script to launch your Java programs, and then in your IDE, it should be possible to create a link/button/whatever to launch myJavaAppRunner.ksh at the click of a button.

0

In a perfect world shutting down your Ant program would also shut down your Java programs. It sounds like you need an explicit shutdown procedure.

Ant is great for writing platform-independent scripts. I've never heard of a long-lived Ant process before. In my experience the Ant program runs, does its job, and exits. I would suggest setting spawn=true when you fire up the Java programs so they will continue after Ant dies, then allowing Ant to exit as quickly as possible.

You should make an explicit Ant task whose job it is to shut down the system. The quick-and-dirty way is to find those Java programs and kill them. Assuming these are programs that you wrote, you'll be able to incorporate explicit shutdown hooks. For example, have each program listen on a predefined port and when someone connects to that port and issues the right instructions the program will initiate a graceful shutdown.

This suggestion comes with security risks -- what if a malicious program initiates the shutdown sequence? You'll have to make sure your firewall is configured appropriately so that only trusted processes or machines can access the shutdown port. That part is left as an exercise for the reader. :)

Edit: Make sure your Ant task and/or the Java program do appropriate error checking on any parameters that are passed in. Otherwise you could have a situation that is really challenging to debug. (Thanks to @randomA)

  • This is an excellent answer. I think before thinking about how to run and terminate the Java programs, the asker should make sure that there is a basic protection for the running Java programs. It's not just the firewall to prevent shutdown, there are various other malicious things that can be injected into the running Java program. It's true that the ant program should have admin control over the running Java programs, but it shouldn't allow just about anything to do what they want to the Java programs. – InformedA Jul 4 '14 at 20:29
  • Thanks @randomA. Any program running on any machine is going to have security risks. My main concern is that if I'm going to suggest something that potentially opens up a new security hole then it's important to be explicit about that. – Matthew Jacobs Jul 4 '14 at 20:33
  • I previously ran into an issue where in the end, it turns out that the fault was not at all that of the ant program. The ant program and the admin console were nothing but exemplary. It was the java program that causes the problem, the java program was configured with a lot of incorrect parameters. I don't quite remember what I did to the java program to make sure things get fixed though, but I didn't do anything to the ant and the admin console. They work as they are supposed to. – InformedA Jul 4 '14 at 20:59
0

Two options that I used in my last project:

  • maven assembly plugin: this plugin can generate for you a "package" that contains the libraries you need and a generated shell script to execute the program. Another option I like a lot is to generate a "fat jar" with all the libs merged in a big .jar. This simplifies a lot the distribution and executing of java programs and you can simple execute with java <class_name> -jar <ftr-jar.jar>

  • Use groovy: I like a lot this option because gives me a lot of freedom. You can have .groovy script that simply calls your classes. Inside this scripts you can use "grab" to declare your dependencies (more info in this link: http://groovy.codehaus.org/Grapes+and+grab()).

0

Since you are already using Maven, you may consider giving the Exec Plugin a shot.

I would rather avoid custom runs scripts if I were you unless the startup and shutdown logic is really complex, since writing them properly may be much harder than it seems, and you can run into issues with cross-platform or even cross-machine compatibility.

If you need lots of custom logic in the build or run process but prefer to stay within the bounds of a build system, you might want to have a look at Gradle which allows you more customization than Maven in some cases since you can add almost any Groovy code into your build process. This approach allows for better integration and may be more portable than writing custom scripts independent of the build system.

  • "Gradle allows you more customization than Maven in some cases since you can add almost any Groovy code into your build process" - Would be nice if we could add almost any Scala or Clojure or JRuby or other code into our build process too. – Vorg van Geir Sep 21 '14 at 11:51
-1

Most of the larger java tooling like Maven and Ant have batch/shell script wrappers.

So if you want to be cross platform you need to have both. http://www.mojohaus.org/appassembler/appassembler-maven-plugin/assemble-mojo.html tries to automate the creation of those scripts for you for both Windows and Unix.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.