Author: peterreilly
Date: Wed Aug 22 01:25:58 2007
New Revision: 568503

URL: http://svn.apache.org/viewvc?rev=568503&view=rev
Log:
Bugzilla 43114:  package-info.java repeatedly compiled

Modified:
    ant/core/trunk/WHATSNEW
    ant/core/trunk/docs/manual/CoreTasks/javac.html
    ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Javac.java

Modified: ant/core/trunk/WHATSNEW
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/WHATSNEW?rev=568503&r1=568502&r2=568503&view=diff
==============================================================================
--- ant/core/trunk/WHATSNEW (original)
+++ ant/core/trunk/WHATSNEW Wed Aug 22 01:25:58 2007
@@ -226,6 +226,9 @@
 * <fileset> has a new attribute - errorOnMissingDir.
   Bugzilla 11270.
 
+* <javac> handles package-info.java files, there were repeatedly compiled.
+  Bugzilla 43114.
+
 Changes from Ant 1.6.5 to Ant 1.7.0
 ===================================
 

Modified: ant/core/trunk/docs/manual/CoreTasks/javac.html
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/docs/manual/CoreTasks/javac.html?rev=568503&r1=568502&r2=568503&view=diff
==============================================================================
--- ant/core/trunk/docs/manual/CoreTasks/javac.html (original)
+++ ant/core/trunk/docs/manual/CoreTasks/javac.html Wed Aug 22 01:25:58 2007
@@ -761,6 +761,36 @@
                  debug="yes"/&gt;
 </pre></blockquote>
 
+  <h3>Note on package-info.java</h3>
+  <p>
+    <code>package-info.java</code> files were introduced in Java5 to
+    allow package level annotations. On compilation, if the java file
+    does not contain runtime annotations, there will be no .class file
+    for the java file. Up to <b>Ant 1.7.1</b>, when the &lt;javac&gt;
+    task is run again, the
+    task will try to compile the package-info java files again.
+  </p>
+  <p>
+    In <b>Ant 1.7.1</b> the package-info.java will only be compiled if:
+    <ol>
+      <li>
+        If a <code>package-info.class</code> file exists and is older than
+        the <code>package-info.java</code> file.
+      </li>
+      <li>
+        If the directory for the 
+        <code>package-info.class</code> file does not exist.
+      </li>
+      <li>
+        If the directory for the
+        <code>package-info.class</code> file exists, and has an older
+        modification time than the
+        the <code>package-info.java</code> file. In this case
+        &lt;javac&gt; will touch the corresponding .class directory
+        on successful compilation.
+      </li>
+    </ol>
+  </p>
 
 </body>
 </html>

Modified: ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Javac.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Javac.java?rev=568503&r1=568502&r2=568503&view=diff
==============================================================================
--- ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Javac.java (original)
+++ ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/Javac.java Wed Aug 22 
01:25:58 2007
@@ -20,6 +20,10 @@
 
 import java.io.File;
 
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.DirectoryScanner;
 import org.apache.tools.ant.MagicNames;
@@ -82,6 +86,9 @@
     private static final String CLASSIC = "classic";
     private static final String EXTJAVAC = "extJavac";
 
+    private static final String PACKAGE_INFO_JAVA = "package-info.java";
+    private static final String PACKAGE_INFO_CLASS = "package-info.class";
+
     private Path src;
     private File destDir;
     private Path compileClasspath;
@@ -117,6 +124,7 @@
     private String errorProperty;
     private boolean taskSuccess = true; // assume the best
     private boolean includeDestClasses = true;
+    private List    updateDirList = new ArrayList();
 
     /**
      * Javac task for compilation of Java files.
@@ -901,6 +909,7 @@
         SourceFileScanner sfs = new SourceFileScanner(this);
         File[] newFiles = sfs.restrictAsFiles(files, srcDir, destDir, m);
 
+        newFiles = removePackageInfoFiles(newFiles, srcDir, destDir);
         if (newFiles.length > 0) {
             File[] newCompileList
                 = new File[compileList.length + newFiles.length];
@@ -1053,7 +1062,14 @@
             adapter.setJavac(this);
 
             // finally, lets execute the compiler!!
-            if (!adapter.execute()) {
+            if (adapter.execute()) {
+                // Success - check
+                for (Iterator i = updateDirList.iterator(); i.hasNext();) {
+                    File file = (File) i.next();
+                    file.setLastModified(System.currentTimeMillis());
+                }
+            } else {
+                // Fail path
                 this.taskSuccess = false;
                 if (errorProperty != null) {
                     getProject().setNewProperty(
@@ -1084,4 +1100,75 @@
         }
     }
 
+    // ----------------------------------------------------------------
+    //  Code to remove package-info.java files from compilation
+    //  Since Ant 1.7.1.
+    //
+    //    package-info.java are files that contain package level
+    //    annotations. They may or may not have corresponding .class
+    //    files.
+    //
+    //    The following code uses the algorithm:
+    //     * on entry we have the files that need to be compiled
+    //     * if the filename is not package-info.java compile it
+    //     * if a corresponding .class file exists compile it
+    //     * if the corresponding class directory does not exist compile it
+    //     * if the corresponding directory lastmodifed time is
+    //       older than the java file, compile the java file and
+    //       touch the corresponding class directory (on successful
+    //       compilation).
+    //    
+    // ----------------------------------------------------------------
+    private File[] removePackageInfoFiles(
+        File[] newFiles, File srcDir, File destDir) {
+        if (!hasPackageInfo(newFiles)) {
+            return newFiles;
+        }
+        List ret = new ArrayList();
+        for (int i = 0; i < newFiles.length; ++i) {
+            if (needsCompilePackageFile(newFiles[i], srcDir, destDir)) {
+                ret.add(newFiles[i]);
+            }
+        }
+        return (File[]) ret.toArray(new File[0]);
+    }
+
+    private boolean hasPackageInfo(File[] newFiles) {
+        for (int i = 0; i < newFiles.length; ++i) {
+            if (newFiles[i].getName().equals(PACKAGE_INFO_JAVA)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean needsCompilePackageFile(
+        File file, File srcDir, File destDir) {
+        if (!file.getName().equals(PACKAGE_INFO_JAVA)) {
+            return true;
+        }
+        // return true if destDir contains the file
+        String rel = relativePath(srcDir, file);
+        File destFile = new File(destDir, rel);
+        File parent = destFile.getParentFile();
+        destFile = new File(parent, PACKAGE_INFO_CLASS);
+        File sourceFile = new File(srcDir, rel);
+        if (destFile.exists()) {
+            return true;
+        }
+        // Dest file does not exist
+        // Compile Source file if sourceFile is newer that destDir
+        // TODO - use fs
+        if (sourceFile.lastModified()
+            > destFile.getParentFile().lastModified()) {
+            updateDirList.add(destFile.getParentFile());
+            return true;
+        }
+        return false;
+    }
+
+    private String relativePath(File src, File file) {
+        return file.getAbsolutePath().substring(
+            src.getAbsolutePath().length() + 1);
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to