How to start and stop Jetty from Ant

This example is a bit more complex than the one in this previous post How to start and stop Tomcat from Ant. Here, reuse of Ant code using “macrodef” is attempted. Also the start target is smart enough to stop the server if it is already running and the “sleep” is to give enough time for the server (2 seconds) to shutdown before restarting. I am using this approach successfully for Jetty 6.X


<macrodef name="jetty-start">
    <attribute name="arg1" default=""/>
    <attribute name="arg2" default=""/>
    <sequential>
        <antcall target="jetty-stop"/>
        <java jar="${jetty.home}/start.jar" fork="true" dir="${jetty.home}">
            <jvmarg value="-Dfile.encoding=UTF-8"/>
            <jvmarg value="-DSTOP.PORT=8079"/>
            <jvmarg value="-DSTOP.KEY=secret"/>
            <jvmarg value="@{arg1}"/>
            <jvmarg value="@{arg2}"/>
        </java>
    </sequential>
</macrodef>

<target name="jetty-check-status">
    <condition property="jetty.started">
        <socket server="localhost" port="8080"/>
    </condition>
</target>

<target name="jetty-start" depends="my-deploy-target">
    <jetty-start/>
</target>

<target name="jetty-start-debug" depends="my-deploy-target">
    <jetty-start
        arg1="-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"
        arg2="-Xdebug"/>
</target> 

<target name="jetty-stop" depends="jetty-check-status" if="jetty.started">
    <java jar="${jetty.home}/start.jar" fork="true" dir="${jetty.home}">
        <jvmarg value="-DSTOP.PORT=8079"/>
        <jvmarg value="-DSTOP.KEY=secret"/>
        <arg value="--stop"/>
    </java>
    <sleep seconds="2"/>
</target>

Enforcing dependencies like performing an incremental compile & deploy before re-starting the server is IMHO much easier with Ant than using things like an IDE plugin, Cargo or Maven. Things like starting in debug mode are easy. Need to add a few more JVM parameters? No problem. Ant rulez :)

About Peter Thomas
https://twitter.com/ptrthomas

19 Responses to How to start and stop Jetty from Ant

  1. peterreilly says:

    Why not use
    instead of the ?

  2. peterreilly says:

    That should be <sleep seconds=”2″>!

  3. Peter Thomas says:

    Well you learn something new everyday :)

    Thanks! I have updated the post. For the record – what I had initially was this (now painfully obvious) hack:

    <waitfor maxwait=”2″ maxwaitunit=”second”>
      <equals arg1=”true” arg2=”false”/>
    </waitfor>

  4. jdoyle says:

    I changed the jetty-start definition to look like this:

    The task was never returning for the fork in my env without the spawn.

    ~jd

  5. lindsayk says:

    Hi,

    I’m wondering if I need to specify anything in the ANT classpath element to use these tasks..?

    I’m getting this when I fire jetty-start:

    jetty-start:

    jetty-check-status:

    jetty-stop:
    [java] Exception in thread “main” java.lang.NoClassDefFoundError:
    [java] Java Result: 1

  6. Peter Thomas says:

    Nope “start.jar” is the only classpath you need. Maybe the value of “jetty.home” is not set correctly, try to print it out in Ant like <echo>${jetty.home}</echo>, remember spaces in the full path name or backslashes instead of the recommended forward-slashes may cause problems.

  7. Darryl says:

    Howzit Peter,

    These 2 post are helluva interesting, and the first one works very well. This post however I’m a little stumped. What would the target my-deploy-target look like??? Not that it really matters, cos my question could render your answer here useless. My question then…

    I am using MyEclipse running tomcat inside eclipse with the aim of debugging webapps deployed to this tomcat. and I want to ANT to stop and start this tomcat inside eclipse. Also, because the projects are in the IDE there is no physical WAR file at development time, and as such the deploy task becomes complex, cos it wants a war file destination or config or tag values?? What are those?
    “Must specify either ‘war’, ‘localWar’, ‘config’, or ‘tag’ attribute”

    This is the error I get when I run the ant task

    Short of me stopping and starting tomcat in eclipse running it in debug mode etc… I was wondering if you know of a way to get to do this for me.

    At the end of the day, the reason why I want this is that I’m working in a very outdated development environment, where we have webapps that contain other webapps. There is a massive build process that put all these little webapps into one and then we have to stop and start tomcat manually. As such making small changes to the “sub” web projects puts tomcat out of sync very easily so we have to stop tomcat, re run build process, Redeploy the web project to tomcat, and then start tomcat again to get our changes to take effect. You see why I would like ant to this for me, but it must all happen inside eclipse.

    This is actually difficult to explain in writing. Please tell me you understand and can help ;-)

    cheers
    Darryl

  8. Peter Thomas says:

    Darryl,

    Woah, that’s a lot to digest, but let me quickly link you to this Ant file:

    http://fisheye3.cenqua.com/browse/j-trac/trunk/jtrac/build.xml?r=trunk

    So the quick answer to your question is if you want to see the equivalent of “my-deploy-target” it is the “war-exploded” target – but it is a very straightforward WAR file creation target, nothing fancy. One thing that may be of interest is how I use the zip task instead of the war task, this gives you more flexibility, perhaps this is what you need?

    The build does some interesting conditional stuff, and maybe this is what you really want, have a look at this flow:

    jetty-start depends on jetty-setup which calls jetty-setup-dev (antcall) unless a “production.mode” variable is set.

    So in the jetty-setup-dev target, I do a bit of find-and-replace, copy a couple of extra files (e.g. for development mode log levels) and the jetty-start-deploymode target is a good example of how to ensure that this (conditional) stuff does not happen. You should be able to figure how to conditionally do stuff looking at this example.

    If you feel that your requirement requires more brute force, have a look at this blog post:

    How to shutdown HSQLDB from Ant

    Hope this helps!

  9. Darryl says:

    Howzit Peter,

    It is a lot to digest I agree. Let me try put it extremely simply. Let’s pretend there is no ANT.

    I am running a web app in MyEclipse using tomcat as the app server, and am able to right click on this tomcat under the servers view, and deploy my app to tomcat, and start tomcat in debug mode, or normally. I can then make code changes on the fly without stopping and starting tomcat when running in debug mode.

    Now bring ant in. Can ANT do the above with no exceptions. ie: not using another tomcat installed on the machine (although that is what MyEclipse does anyway) when I run the ant target to start tomcat, I would like to see that tomcat in eclipse status become started? I’m begining to think that it’s impossible, but really hope that it isn’t.

    cheers
    Darryl

  10. Peter Thomas says:

    Ah with the Ant approach, you really can’t have it both ways, you can’t still have the Eclipse “status” – since I haven’t used it not sure what it is, but I’m guessing it is nothing but a green-light icon somewhere?

    Why don’t you try the pure Ant approach. Eclipse has excellent Ant integration, bring up View –> Ant, then drag build.xml into this view and you are all set to fire the Ant targets by double clicking on them. Trust me, you won’t miss so-called IDE app-server integration at all. And you will be able to see the log within eclipse. And you can hyperlink to stack traces. In fact if you start Tomcat in debug mode, you can hot-deploy Java class changes also.

  11. Pingback: How to shutdown HSQLDB from Ant « Incremental Operations

  12. Pingback: How to start and stop Jetty - revisited « Incremental Operations

  13. alaminsumon says:

    Thanks, a lot, though I was looking for stopping Jetty from command prompt, your post helped me find out the solution for command prompt code which I posted on:
    http://alaminsumon.blogspot.com/2009/06/how-to-stop-and-start-jetty-server-from.html

  14. Adrian Blakey says:

    I have tried this and several other variations to start jetty 7.1.4 from ant in a NetBeans build.xml. It works fine from a command line. From ant I always get:

    Exception in thread “main” java.lang.NoClassDefFoundError:
    Caused by: java.lang.ClassNotFoundException:
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    Java Result: 1

  15. I believe this is a more correct [and complete] version of your Ant macros for Jetty: https://gist.github.com/2704730

    Notable functionality differences in my version:
    * This version can be run more than once and still work correctly as I’m not setting any immutable Ant properties.
    * If a server is already running on your port when “jetty-start” is called, it will fail the build rather than trying to stop the server. That is very easy to change for yourself, if desired.
    * This version will fail the build if the server is not successfully started and/or stopped, depending on the action attempted.

  16. P.S. Thanks for posting this, though, it was very helpful in deriving my version of it. :)

  17. Don Poulin says:

    I have tried your example (Thanks) under windows 7 and it apparently does not honor the “fork=true” becuase after invoking the marcodef ant just hangs waiting until jetty stops. It seems that this technique only works under unix?

  18. Pingback: Fix Myeclipse Error Starting Tomcat Windows XP, Vista, 7, 8 [Solved]

  19. Pingback: 如何通过命令行启动或者关闭 Jetty 服务器 转 – 1

Leave a comment