[GRADLE-1048] Provide nailgun integration for greater command-line responsiveness Created: 22/Jul/10  Updated: 04/Jan/13  Resolved: 03/Dec/10

Status: Resolved
Project: Gradle
Affects Version/s: 0.9
Fix Version/s: 0.9-rc-3

Type: Improvement
Reporter: Chris Beams Assignee: Adam Murdoch
Resolution: Won't Fix Votes: 0


 Description   

I've done an initial investigation on integrating Gradle with Nailgun. Nailgun does in fact work as advertised, and though it hasn't had a release since 2005, there is activity on the mailing list and reason to believe there will be a new release in the near future.

There are specific issues getting Gradle to work with Nailgun. The easiest way to explain this is probably to have you simply repeat the process I went through. It doesn't take long, but you will need Make installed on your machine:

  1. svn co https://nailgun.svn.sourceforge.net/svnroot/nailgun/trunk nailgun
  2. cd nailgun
  3. make
  4. you should now have an 'ng' binary. let's call this $NG_BINARY_PATH for purposes below
  5. Import nailgun's java sources as an Ant project into your IDE
  6. Add all jars in your Gradle distribution's lib/ directory to the classpath of the nailgun project
  7. Run the main method in com.martiansoftware.nailgun.NGServer, with the following:
    1. -Dgradle.home=/opt/gradle/current
    2. the working directory should be the root of a gradle-based project
  8. You should see the following output from NGServer
    NGServer started on all interfaces, port 2113.
    
  9. Just to prove everything is working as expected, issue the following:
    cbeams@anakata:~/Work/nailgun[home]>$ ./ng com.martiansoftware.nailgun.examples.HelloWorld
    Hello, world!
    

    in this case, the running NGServer accepted the request to execute HelloWorld's main method, and it did so. Keep in mind that HelloWorld is part of the nailgun-examples jar, and is on the classpath of the NGServer you just started up. Now let's get gradle to communicate with running NGServer in a similar fashion.

  10. Modify your Gradle distribution's 'gradle' script as follows:
    STARTER_MAIN_CLASS=org.gradle.launcher.GradleMain
    
    # Start the Profiler or the JVM
    if $useprofiler ; then
        runProfiler
    else
        exec $NAILGUN_BINARY_PATH \
            $STARTER_MAIN_CLASS \
            "$@"
    #    echo "$JAVACMD" $JAVA_OPTS $GRADLE_OPTS \
    #        -classpath "$CLASSPATH" \
    #        -Dgradle.home="$GRADLE_HOME" \
    #        $STARTER_MAIN_CLASS \
    #        "$@"
    fi
    

    You now have a working test environment.

  11. cd into the same working directory that you gave NGServer above, and run 'gradle clean'. This will probably execute without problems.
  12. run 'gradle clean' again. Notice that it hangs.
  13. switch back to your IDE console and notice this stack trace:

    java.lang.ClassCastException: org.gradle.util.LinePerThreadBufferingOutputStream cannot be cast to com.martiansoftware.nailgun.ThreadLocalPrintStream
    at com.martiansoftware.nailgun.NGSession.run(NGSession.java:246)
    Exception in thread "NGSession 2: 127.0.0.1: org.gradle.launcher.GradleMain" java.lang.ClassCastException: org.gradle.util.LinePerThreadBufferingOutputStream cannot be cast tocom.martiansoftware.nailgun.ThreadLocalPrintStream
    at com.martiansoftware.nailgun.NGSession.run(NGSession.java:320)

  14. Take a look at the code per the line numbers above, and you'll see that Nailgun does stdout/stderr capturing, but does so in a way that is at odds with Gradle's own stdout/err redirection. This is problem #1.
  15. Hack around, try commenting out the places where class casts are made, and run again.
  16. Notice that once you get past the classcastexceptions, you can only run gradle a few times before PermGen errors start cropping up (especially true if you're doing full 'gradle build' runs).

Nailgun seems like it has promising potential for speeding up command line performance in gradle, which I think for many is a 'first impression' issue that could make or break looking at Gradle any further. These issues would obviously need to be worked out first, however.



 Comments   
Comment by Chris Beams [ 03/Dec/10 ]

This issue is obsolete given the Gradle daemon support now integrated in 0.9-rc3

Generated at Wed Jun 30 11:45:35 CDT 2021 using Jira 8.4.2#804003-sha1:d21414fc212e3af190e92c2d2ac41299b89402cf.