|
Martin Matejovic |
b9042c |
--- src/main/org/apache/tools/ant/taskdefs/Javac.java.orig 2009/01/29 05:23:52 738761
|
|
Martin Matejovic |
b9042c |
+++ src/main/org/apache/tools/ant/taskdefs/Javac.java 2009/02/12 22:35:18 743910
|
|
Martin Matejovic |
b9042c |
@@ -20,9 +20,12 @@
|
|
Martin Matejovic |
b9042c |
|
|
Martin Matejovic |
b9042c |
import java.io.File;
|
|
Martin Matejovic |
b9042c |
|
|
Martin Matejovic |
b9042c |
-import java.util.ArrayList;
|
|
Martin Matejovic |
b9042c |
+import java.io.FileOutputStream;
|
|
Martin Matejovic |
b9042c |
+import java.io.IOException;
|
|
Martin Matejovic |
b9042c |
+import java.io.OutputStream;
|
|
Martin Matejovic |
b9042c |
+import java.util.HashMap;
|
|
Martin Matejovic |
b9042c |
import java.util.Iterator;
|
|
Martin Matejovic |
b9042c |
-import java.util.List;
|
|
Martin Matejovic |
b9042c |
+import java.util.Map;
|
|
Martin Matejovic |
b9042c |
|
|
Martin Matejovic |
b9042c |
import org.apache.tools.ant.BuildException;
|
|
Martin Matejovic |
b9042c |
import org.apache.tools.ant.DirectoryScanner;
|
|
Martin Matejovic |
b9042c |
@@ -32,6 +35,7 @@
|
|
Martin Matejovic |
b9042c |
import org.apache.tools.ant.taskdefs.compilers.CompilerAdapterFactory;
|
|
Martin Matejovic |
b9042c |
import org.apache.tools.ant.types.Path;
|
|
Martin Matejovic |
b9042c |
import org.apache.tools.ant.types.Reference;
|
|
Martin Matejovic |
b9042c |
+import org.apache.tools.ant.util.FileUtils;
|
|
Martin Matejovic |
b9042c |
import org.apache.tools.ant.util.GlobPatternMapper;
|
|
Martin Matejovic |
b9042c |
import org.apache.tools.ant.util.JavaEnvUtils;
|
|
Martin Matejovic |
b9042c |
import org.apache.tools.ant.util.SourceFileScanner;
|
|
Martin Matejovic |
b9042c |
@@ -86,8 +90,7 @@
|
|
Martin Matejovic |
b9042c |
private static final String CLASSIC = "classic";
|
|
Martin Matejovic |
b9042c |
private static final String EXTJAVAC = "extJavac";
|
|
Martin Matejovic |
b9042c |
|
|
Martin Matejovic |
b9042c |
- private static final String PACKAGE_INFO_JAVA = "package-info.java";
|
|
Martin Matejovic |
b9042c |
- private static final String PACKAGE_INFO_CLASS = "package-info.class";
|
|
Martin Matejovic |
b9042c |
+ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
|
|
Martin Matejovic |
b9042c |
|
|
Martin Matejovic |
b9042c |
private Path src;
|
|
Martin Matejovic |
b9042c |
private File destDir;
|
|
Martin Matejovic |
b9042c |
@@ -115,6 +118,7 @@
|
|
Martin Matejovic |
b9042c |
protected boolean failOnError = true;
|
|
Martin Matejovic |
b9042c |
protected boolean listFiles = false;
|
|
Martin Matejovic |
b9042c |
protected File[] compileList = new File[0];
|
|
Martin Matejovic |
b9042c |
+ private Map/*<String,Long>*/ packageInfos = new HashMap();
|
|
Martin Matejovic |
b9042c |
// CheckStyle:VisibilityModifier ON
|
|
Martin Matejovic |
b9042c |
|
|
Martin Matejovic |
b9042c |
private String source;
|
|
Martin Matejovic |
b9042c |
@@ -124,7 +128,6 @@
|
|
Martin Matejovic |
b9042c |
private String errorProperty;
|
|
Martin Matejovic |
b9042c |
private boolean taskSuccess = true; // assume the best
|
|
Martin Matejovic |
b9042c |
private boolean includeDestClasses = true;
|
|
Martin Matejovic |
b9042c |
- private List updateDirList = new ArrayList();
|
|
Martin Matejovic |
b9042c |
|
|
Martin Matejovic |
b9042c |
/**
|
|
Martin Matejovic |
b9042c |
* Javac task for compilation of Java files.
|
|
Martin Matejovic |
b9042c |
@@ -892,6 +895,7 @@
|
|
Martin Matejovic |
b9042c |
*/
|
|
Martin Matejovic |
b9042c |
protected void resetFileLists() {
|
|
Martin Matejovic |
b9042c |
compileList = new File[0];
|
|
Martin Matejovic |
b9042c |
+ packageInfos = new HashMap();
|
|
Martin Matejovic |
b9042c |
}
|
|
Martin Matejovic |
b9042c |
|
|
Martin Matejovic |
b9042c |
/**
|
|
Martin Matejovic |
b9042c |
@@ -909,8 +913,8 @@
|
|
Martin Matejovic |
b9042c |
SourceFileScanner sfs = new SourceFileScanner(this);
|
|
Martin Matejovic |
b9042c |
File[] newFiles = sfs.restrictAsFiles(files, srcDir, destDir, m);
|
|
Martin Matejovic |
b9042c |
|
|
Martin Matejovic |
b9042c |
- newFiles = removePackageInfoFiles(newFiles, srcDir, destDir);
|
|
Martin Matejovic |
b9042c |
if (newFiles.length > 0) {
|
|
Martin Matejovic |
b9042c |
+ lookForPackageInfos(srcDir, newFiles);
|
|
Martin Matejovic |
b9042c |
File[] newCompileList
|
|
Martin Matejovic |
b9042c |
= new File[compileList.length + newFiles.length];
|
|
Martin Matejovic |
b9042c |
System.arraycopy(compileList, 0, newCompileList, 0,
|
|
Martin Matejovic |
b9042c |
@@ -1063,10 +1067,12 @@
|
|
Martin Matejovic |
b9042c |
|
|
Martin Matejovic |
b9042c |
// finally, lets execute the compiler!!
|
|
Martin Matejovic |
b9042c |
if (adapter.execute()) {
|
|
Martin Matejovic |
b9042c |
- // Success - check
|
|
Martin Matejovic |
b9042c |
- for (Iterator i = updateDirList.iterator(); i.hasNext();) {
|
|
Martin Matejovic |
b9042c |
- File file = (File) i.next();
|
|
Martin Matejovic |
b9042c |
- file.setLastModified(System.currentTimeMillis());
|
|
Martin Matejovic |
b9042c |
+ // Success
|
|
Martin Matejovic |
b9042c |
+ try {
|
|
Martin Matejovic |
b9042c |
+ generateMissingPackageInfoClasses();
|
|
Martin Matejovic |
b9042c |
+ } catch (IOException x) {
|
|
Martin Matejovic |
b9042c |
+ // Should this be made a nonfatal warning?
|
|
Martin Matejovic |
b9042c |
+ throw new BuildException(x, getLocation());
|
|
Martin Matejovic |
b9042c |
}
|
|
Martin Matejovic |
b9042c |
} else {
|
|
Martin Matejovic |
b9042c |
// Fail path
|
|
Martin Matejovic |
b9042c |
@@ -1100,75 +1106,74 @@
|
|
Martin Matejovic |
b9042c |
}
|
|
Martin Matejovic |
b9042c |
}
|
|
Martin Matejovic |
b9042c |
|
|
Martin Matejovic |
b9042c |
- // ----------------------------------------------------------------
|
|
Martin Matejovic |
b9042c |
- // Code to remove package-info.java files from compilation
|
|
Martin Matejovic |
b9042c |
- // Since Ant 1.7.1.
|
|
Martin Matejovic |
b9042c |
- //
|
|
Martin Matejovic |
b9042c |
- // package-info.java are files that contain package level
|
|
Martin Matejovic |
b9042c |
- // annotations. They may or may not have corresponding .class
|
|
Martin Matejovic |
b9042c |
- // files.
|
|
Martin Matejovic |
b9042c |
- //
|
|
Martin Matejovic |
b9042c |
- // The following code uses the algorithm:
|
|
Martin Matejovic |
b9042c |
- // * on entry we have the files that need to be compiled
|
|
Martin Matejovic |
b9042c |
- // * if the filename is not package-info.java compile it
|
|
Martin Matejovic |
b9042c |
- // * if a corresponding .class file exists compile it
|
|
Martin Matejovic |
b9042c |
- // * if the corresponding class directory does not exist compile it
|
|
Martin Matejovic |
b9042c |
- // * if the corresponding directory lastmodifed time is
|
|
Martin Matejovic |
b9042c |
- // older than the java file, compile the java file and
|
|
Martin Matejovic |
b9042c |
- // touch the corresponding class directory (on successful
|
|
Martin Matejovic |
b9042c |
- // compilation).
|
|
Martin Matejovic |
b9042c |
- //
|
|
Martin Matejovic |
b9042c |
- // ----------------------------------------------------------------
|
|
Martin Matejovic |
b9042c |
- private File[] removePackageInfoFiles(
|
|
Martin Matejovic |
b9042c |
- File[] newFiles, File srcDir, File destDir) {
|
|
Martin Matejovic |
b9042c |
- if (!hasPackageInfo(newFiles)) {
|
|
Martin Matejovic |
b9042c |
- return newFiles;
|
|
Martin Matejovic |
b9042c |
- }
|
|
Martin Matejovic |
b9042c |
- List ret = new ArrayList();
|
|
Martin Matejovic |
b9042c |
- for (int i = 0; i < newFiles.length; ++i) {
|
|
Martin Matejovic |
b9042c |
- if (needsCompilePackageFile(newFiles[i], srcDir, destDir)) {
|
|
Martin Matejovic |
b9042c |
- ret.add(newFiles[i]);
|
|
Martin Matejovic |
b9042c |
+ private void lookForPackageInfos(File srcDir, File[] newFiles) {
|
|
Martin Matejovic |
b9042c |
+ for (int i = 0; i < newFiles.length; i++) {
|
|
Martin Matejovic |
b9042c |
+ File f = newFiles[i];
|
|
Martin Matejovic |
b9042c |
+ if (!f.getName().equals("package-info.java")) {
|
|
Martin Matejovic |
b9042c |
+ continue;
|
|
Martin Matejovic |
b9042c |
}
|
|
Martin Matejovic |
b9042c |
- }
|
|
Martin Matejovic |
b9042c |
- return (File[]) ret.toArray(new File[0]);
|
|
Martin Matejovic |
b9042c |
- }
|
|
Martin Matejovic |
b9042c |
-
|
|
Martin Matejovic |
b9042c |
- private boolean hasPackageInfo(File[] newFiles) {
|
|
Martin Matejovic |
b9042c |
- for (int i = 0; i < newFiles.length; ++i) {
|
|
Martin Matejovic |
b9042c |
- if (newFiles[i].getName().equals(PACKAGE_INFO_JAVA)) {
|
|
Martin Matejovic |
b9042c |
- return true;
|
|
Martin Matejovic |
b9042c |
+ String path = FILE_UTILS.removeLeadingPath(srcDir, f).
|
|
Martin Matejovic |
b9042c |
+ replace(File.separatorChar, '/');
|
|
Martin Matejovic |
b9042c |
+ String suffix = "/package-info.java";
|
|
Martin Matejovic |
b9042c |
+ if (!path.endsWith(suffix)) {
|
|
Martin Matejovic |
b9042c |
+ continue;
|
|
Martin Matejovic |
b9042c |
}
|
|
Martin Matejovic |
b9042c |
+ String pkg = path.substring(0, path.length() - suffix.length());
|
|
Martin Matejovic |
b9042c |
+ packageInfos.put(pkg, Long.valueOf(f.lastModified()));
|
|
Martin Matejovic |
b9042c |
}
|
|
Martin Matejovic |
b9042c |
- return false;
|
|
Martin Matejovic |
b9042c |
}
|
|
Martin Matejovic |
b9042c |
|
|
Martin Matejovic |
b9042c |
- private boolean needsCompilePackageFile(
|
|
Martin Matejovic |
b9042c |
- File file, File srcDir, File destDir) {
|
|
Martin Matejovic |
b9042c |
- if (!file.getName().equals(PACKAGE_INFO_JAVA)) {
|
|
Martin Matejovic |
b9042c |
- return true;
|
|
Martin Matejovic |
b9042c |
- }
|
|
Martin Matejovic |
b9042c |
- // return true if destDir contains the file
|
|
Martin Matejovic |
b9042c |
- String rel = relativePath(srcDir, file);
|
|
Martin Matejovic |
b9042c |
- File destFile = new File(destDir, rel);
|
|
Martin Matejovic |
b9042c |
- File parent = destFile.getParentFile();
|
|
Martin Matejovic |
b9042c |
- destFile = new File(parent, PACKAGE_INFO_CLASS);
|
|
Martin Matejovic |
b9042c |
- File sourceFile = new File(srcDir, rel);
|
|
Martin Matejovic |
b9042c |
- if (destFile.exists()) {
|
|
Martin Matejovic |
b9042c |
- return true;
|
|
Martin Matejovic |
b9042c |
- }
|
|
Martin Matejovic |
b9042c |
- // Dest file does not exist
|
|
Martin Matejovic |
b9042c |
- // Compile Source file if sourceFile is newer that destDir
|
|
Martin Matejovic |
b9042c |
- // TODO - use fs
|
|
Martin Matejovic |
b9042c |
- if (sourceFile.lastModified()
|
|
Martin Matejovic |
b9042c |
- > destFile.getParentFile().lastModified()) {
|
|
Martin Matejovic |
b9042c |
- updateDirList.add(destFile.getParentFile());
|
|
Martin Matejovic |
b9042c |
- return true;
|
|
Martin Matejovic |
b9042c |
+ /**
|
|
Martin Matejovic |
b9042c |
+ * Ensure that every {@code package-info.java} produced a {@code package-info.class}.
|
|
Martin Matejovic |
b9042c |
+ * Otherwise this task's up-to-date tracking mechanisms do not work.
|
|
Martin Matejovic |
b9042c |
+ * @see Bug #43114
|
|
Martin Matejovic |
b9042c |
+ */
|
|
Martin Matejovic |
b9042c |
+ private void generateMissingPackageInfoClasses() throws IOException {
|
|
Martin Matejovic |
b9042c |
+ for (Iterator i = packageInfos.entrySet().iterator(); i.hasNext(); ) {
|
|
Martin Matejovic |
b9042c |
+ Map.Entry entry = (Map.Entry) i.next();
|
|
Martin Matejovic |
b9042c |
+ String pkg = (String) entry.getKey();
|
|
Martin Matejovic |
b9042c |
+ Long sourceLastMod = (Long) entry.getValue();
|
|
Martin Matejovic |
b9042c |
+ File pkgBinDir = new File(destDir, pkg.replace('/', File.separatorChar));
|
|
Martin Matejovic |
b9042c |
+ pkgBinDir.mkdirs();
|
|
Martin Matejovic |
b9042c |
+ File pkgInfoClass = new File(pkgBinDir, "package-info.class");
|
|
Martin Matejovic |
b9042c |
+ if (pkgInfoClass.isFile() && pkgInfoClass.lastModified() >= sourceLastMod.longValue()) {
|
|
Martin Matejovic |
b9042c |
+ continue;
|
|
Martin Matejovic |
b9042c |
+ }
|
|
Martin Matejovic |
b9042c |
+ log("Creating empty " + pkgInfoClass);
|
|
Martin Matejovic |
b9042c |
+ OutputStream os = new FileOutputStream(pkgInfoClass);
|
|
Martin Matejovic |
b9042c |
+ try {
|
|
Martin Matejovic |
b9042c |
+ os.write(PACKAGE_INFO_CLASS_HEADER);
|
|
Martin Matejovic |
b9042c |
+ byte[] name = pkg.getBytes("UTF-8");
|
|
Martin Matejovic |
b9042c |
+ int length = name.length + /* "/package-info" */ 13;
|
|
Martin Matejovic |
b9042c |
+ os.write((byte) length / 256);
|
|
Martin Matejovic |
b9042c |
+ os.write((byte) length % 256);
|
|
Martin Matejovic |
b9042c |
+ os.write(name);
|
|
Martin Matejovic |
b9042c |
+ os.write(PACKAGE_INFO_CLASS_FOOTER);
|
|
Martin Matejovic |
b9042c |
+ } finally {
|
|
Martin Matejovic |
b9042c |
+ os.close();
|
|
Martin Matejovic |
b9042c |
+ }
|
|
Martin Matejovic |
b9042c |
}
|
|
Martin Matejovic |
b9042c |
- return false;
|
|
Martin Matejovic |
b9042c |
}
|
|
Martin Matejovic |
b9042c |
|
|
Martin Matejovic |
b9042c |
private String relativePath(File src, File file) {
|
|
Martin Matejovic |
b9042c |
return file.getAbsolutePath().substring(
|
|
Martin Matejovic |
b9042c |
src.getAbsolutePath().length() + 1);
|
|
Martin Matejovic |
b9042c |
}
|
|
Martin Matejovic |
b9042c |
+
|
|
Martin Matejovic |
b9042c |
+ private static final byte[] PACKAGE_INFO_CLASS_HEADER = {
|
|
Martin Matejovic |
b9042c |
+ (byte) 0xca, (byte) 0xfe, (byte) 0xba, (byte) 0xbe, 0x00, 0x00, 0x00,
|
|
Martin Matejovic |
b9042c |
+ 0x31, 0x00, 0x07, 0x07, 0x00, 0x05, 0x07, 0x00, 0x06, 0x01, 0x00, 0x0a,
|
|
Martin Matejovic |
b9042c |
+ 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x01, 0x00,
|
|
Martin Matejovic |
b9042c |
+ 0x11, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x2d, 0x69, 0x6e, 0x66,
|
|
Martin Matejovic |
b9042c |
+ 0x6f, 0x2e, 0x6a, 0x61, 0x76, 0x61, 0x01
|
|
Martin Matejovic |
b9042c |
+ };
|
|
Martin Matejovic |
b9042c |
+ private static final byte[] PACKAGE_INFO_CLASS_FOOTER = {
|
|
Martin Matejovic |
b9042c |
+ 0x2f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x2d, 0x69, 0x6e, 0x66,
|
|
Martin Matejovic |
b9042c |
+ 0x6f, 0x01, 0x00, 0x10, 0x6a, 0x61, 0x76, 0x61, 0x2f, 0x6c, 0x61, 0x6e,
|
|
Martin Matejovic |
b9042c |
+ 0x67, 0x2f, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x02, 0x00, 0x00, 0x01,
|
|
Martin Matejovic |
b9042c |
+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03,
|
|
Martin Matejovic |
b9042c |
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x04
|
|
Martin Matejovic |
b9042c |
+ };
|
|
Martin Matejovic |
b9042c |
+
|
|
Martin Matejovic |
b9042c |
}
|
|
Martin Matejovic |
b9042c |
+
|