Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-7573

Groovyc ant task does not release file handles

    XMLWordPrintableJSON

Details

    Description

      Jars used by the classpath in the groovyc ant task are not released during the ant execution. The following build.xml demonstrates this problem. Please have a copy of the groovy library (groovy-all-2.x.x.jar) in the same directory of the build.xml file in order to work. (See comments within xml for more details.)

      Running ant results in a failure, but running ant update_java succeeds. I would presume that running ant should behave more like ant update_java and succeed every time.

      <project name="GroovycFailure" default="build">
          <path id="groovy.classpath">
              <fileset dir="." includes="groovy*.jar" />
          </path>
      
          <taskdef name="groovyc"
                   classname="org.codehaus.groovy.ant.Groovyc"
                   classpathref="groovy.classpath" />
      
          <target name="build" description="Cleans, inits, builds, then updates the jar">
              <antcall target="clean" />
              <antcall target="init" />
              <antcall target="update_groovy" />
          </target>
      
          <target name="clean" description="Deletes source, classes, and jar files">
              <delete dir="src" />
              <delete dir="java_classes" />
              <delete dir="groovy_classes" />
              <delete>
                  <fileset dir="." includes="java_files.jar" />
              </delete>
          </target>
      
          <target name="init" description="Create the source folders and some Java and Groovy source files">
              <mkdir dir="src" />
              <mkdir dir="src/example" />
      
              <echo file="src/example/JavaFile.java">package example;
      public class JavaFile {
          public static void main(String[] args) {
              System.out.println("Hello, Java.");
          }
      }
              </echo>
              <echo file="src/example/GroovyFile.groovy">package example;
      class GroovyFile {
          static def main() {
              JavaFile jf = new JavaFile()
              println "Hello, Groovy."
          }
      }
              </echo>
          </target>
      
          <target name="compile_java" description="Compiles the first generated Java file">
              <mkdir dir="java_classes" />
              <javac srcdir="src" destdir="java_classes" />
          </target>
      
          <target name="compile_groovy" depends="jar" description="Compiles the Groovy file using the generated jar file">
              <mkdir dir="groovy_classes" />
              <!--
              ******************************************************************************************
                This is where the problem is: when the groovyc task compiles, it puts the jar on the classpath
                but never releases the file handle for the remainder of this ant execution.
              ******************************************************************************************
              -->
              <groovyc srcdir="src" destdir="groovy_classes" classpath="java_files.jar" />
          </target>
      
          <target name="jar" depends="compile_java">
              <jar jarfile="java_files.jar">
                  <fileset dir="java_classes">
                      <include name="**/*.class" />
                  </fileset>
              </jar>
          </target>
      
          <target name="update_groovy" depends="compile_groovy">
              <!-- Since this depends on compile_groovy, it will run the groovyc task -->
              <!-- Unfortunately, the groovyc is still holding onto the java_files.jar
                   file handle, so this fails on the first attempt.  If you re-run this
                   ant task all by itself, it succeeds because the compiler skips the
                   compilation because it detects there are no new files to compile. -->
              <jar update="true" jarfile="java_files.jar">
                  <fileset dir="groovy_classes">
                      <include name="**/*.class" />
                  </fileset>
              </jar>
          </target>
      
          <target name="update_java" depends="jar">
              <!-- Add another plain Java file that requires the java_files.jar on the classpath -->
              <echo file="src/example/AnotherJavaFile.java">package example;
      public class AnotherJavaFile {
          public static void main(String[] args) {
              JavaFile jf = new JavaFile();
              System.out.println("Hello, Another Java");
          }
      }
              </echo>
      
              <!-- Compile and update the jar with this new file -->
              <javac srcdir="src" destdir="java_classes" classpath="java_files.jar" />
      
              <!-- The javac task compiles, just like the groovyc task, except it releases the
                   file handle for java_files.jar after it completes, which allows us to update
                   the jar. -->
              <jar update="true" jarfile="java_files.jar">
                  <fileset dir="java_classes">
                      <include name="**/*.class" />
                  </fileset>
              </jar>
          </target>
      </project>
      

      Attachments

        Activity

          People

            daniel_sun Daniel Sun
            jigawot James Hoffman
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: