different times since they have a mutual dependency. I have introduced a 100 millisecond tolerance to catch this situation PR: 7529 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272303 13f79535-47bb-0310-9956-ffa450edef68master
@@ -4,13 +4,15 @@ | |||
<property name="src1.dir" value="src1"/> | |||
<property name="src2.dir" value="src2"/> | |||
<property name="src3.dir" value="src3"/> | |||
<property name="src4.dir" value="src4"/> | |||
<property name="tempsrc.dir" value="working"/> | |||
<property name="classes.dir" value="classes"/> | |||
<target name="help"> | |||
<echo>This buildfile is used as part of Ant's test suite.</echo> | |||
</target> | |||
<target name="basesetup"> | |||
<target name="basesetup" depends="clean"> | |||
<mkdir dir="${tempsrc.dir}"/> | |||
</target> | |||
@@ -32,6 +34,12 @@ | |||
</copy> | |||
</target> | |||
<target name="src4setup" depends="basesetup"> | |||
<copy todir="${tempsrc.dir}"> | |||
<fileset dir="${src4.dir}"/> | |||
</copy> | |||
</target> | |||
<target name="compile"> | |||
<mkdir dir="${classes.dir}"/> | |||
<javac srcdir="${tempsrc.dir}" destdir="${classes.dir}"/> | |||
@@ -96,4 +104,29 @@ | |||
<depend srcdir="${tempsrc.dir}" destdir="${classes.dir}" closure="yes"/> | |||
<fileset id="result" dir="${classes.dir}"/> | |||
</target> | |||
<target name="testnosource" depends="src1setup, compile"> | |||
<depend destdir="${classes.dir}" closure="yes"/> | |||
</target> | |||
<target name="testemptysource" depends="src1setup, compile"> | |||
<depend srcdir="" destdir="${classes.dir}" closure="yes"/> | |||
</target> | |||
<target name="testinnerclosure" depends="src4setup"> | |||
<mkdir dir="${classes.dir}"/> | |||
<path id="path.compile"> | |||
<pathelement location="${classes.dir}"/> | |||
</path> | |||
<javac srcdir="${tempsrc.dir}" destdir="${classes.dir}" | |||
classpathref="path.compile"/> | |||
<sleep seconds="3"/> | |||
<depend srcdir="${tempsrc.dir}" destdir="${classes.dir}" | |||
closure="yes" dump="yes" | |||
classpathref="path.compile"/> | |||
<fileset id="result" dir="${classes.dir}"/> | |||
</target> | |||
</project> |
@@ -0,0 +1,7 @@ | |||
package test; | |||
public class Outer { | |||
static class Inner { | |||
} | |||
} | |||
@@ -79,6 +79,11 @@ import org.apache.tools.ant.types.Reference; | |||
* @author Conor MacNeill | |||
*/ | |||
public class Depend extends MatchingTask { | |||
/** Tolerance on time checks to take into account inner to outer class dependencies when | |||
* the classes are written at slightly different times | |||
*/ | |||
static private final int TIME_TOLERANCE = 100; | |||
/** | |||
* A class (struct) user to manage information about a class | |||
* | |||
@@ -484,9 +489,14 @@ public class Depend extends MatchingTask { | |||
public void execute() throws BuildException { | |||
try { | |||
long start = System.currentTimeMillis(); | |||
if (srcPath == null) { | |||
throw new BuildException("srcdir attribute must be set", | |||
location); | |||
} | |||
String[] srcPathList = srcPath.list(); | |||
if (srcPathList.length == 0) { | |||
throw new BuildException("srcdir attribute must be set!", | |||
throw new BuildException("srcdir attribute must be non-empty", | |||
location); | |||
} | |||
@@ -559,7 +569,8 @@ public class Depend extends MatchingTask { | |||
Hashtable dependencies = (Hashtable)classpathDependencies.get(className); | |||
for (Enumeration e2 = dependencies.elements(); e2.hasMoreElements(); ) { | |||
File classpathFile = (File)e2.nextElement(); | |||
if (classpathFile.lastModified() > info.absoluteFile.lastModified()) { | |||
if (classpathFile.lastModified() | |||
> (info.absoluteFile.lastModified() + TIME_TOLERANCE)) { | |||
log("Class " + className + | |||
" is out of date with respect to " + classpathFile, Project.MSG_DEBUG); | |||
outOfDateClasses.put(className, className); | |||
@@ -607,7 +618,8 @@ public class Depend extends MatchingTask { | |||
// there was no class file. add this class to the list | |||
outOfDateClasses.put(className, className); | |||
} else { | |||
if (srcFile.lastModified() > info.absoluteFile.lastModified()) { | |||
if (srcFile.lastModified() | |||
> (info.absoluteFile.lastModified() + TIME_TOLERANCE)) { | |||
outOfDateClasses.put(className, className); | |||
} | |||
} | |||
@@ -92,13 +92,7 @@ public class DependTest extends BuildFileTest { | |||
public void testDirect() { | |||
Project project = getProject(); | |||
executeTarget("testdirect"); | |||
FileSet resultFileSet = (FileSet)project.getReference(RESULT_FILESET); | |||
DirectoryScanner scanner = resultFileSet.getDirectoryScanner(project); | |||
String[] scannedFiles = scanner.getIncludedFiles(); | |||
Hashtable files = new Hashtable(); | |||
for (int i = 0; i < scannedFiles.length; ++i) { | |||
files.put(scannedFiles[i], scannedFiles[i]); | |||
} | |||
Hashtable files = getResultFiles(); | |||
assertEquals("Depend did not leave correct number of files", 2, | |||
files.size()); | |||
assertTrue("Result did not contain A.class", | |||
@@ -113,13 +107,7 @@ public class DependTest extends BuildFileTest { | |||
public void testClosure() { | |||
Project project = getProject(); | |||
executeTarget("testclosure"); | |||
FileSet resultFileSet = (FileSet)project.getReference(RESULT_FILESET); | |||
DirectoryScanner scanner = resultFileSet.getDirectoryScanner(project); | |||
String[] scannedFiles = scanner.getIncludedFiles(); | |||
Hashtable files = new Hashtable(); | |||
for (int i = 0; i < scannedFiles.length; ++i) { | |||
files.put(scannedFiles[i], scannedFiles[i]); | |||
} | |||
Hashtable files = getResultFiles(); | |||
assertEquals("Depend did not leave correct number of files", 1, | |||
files.size()); | |||
assertTrue("Result did not contain D.class", | |||
@@ -132,15 +120,8 @@ public class DependTest extends BuildFileTest { | |||
public void testInner() { | |||
Project project = getProject(); | |||
executeTarget("testinner"); | |||
FileSet resultFileSet = (FileSet)project.getReference(RESULT_FILESET); | |||
DirectoryScanner scanner = resultFileSet.getDirectoryScanner(project); | |||
String[] scannedFiles = scanner.getIncludedFiles(); | |||
Hashtable files = new Hashtable(); | |||
for (int i = 0; i < scannedFiles.length; ++i) { | |||
files.put(scannedFiles[i], scannedFiles[i]); | |||
} | |||
assertEquals("Depend did not leave correct number of files", 0, | |||
files.size()); | |||
getResultFiles().size()); | |||
} | |||
/** | |||
@@ -150,6 +131,27 @@ public class DependTest extends BuildFileTest { | |||
public void testInnerInner() { | |||
Project project = getProject(); | |||
executeTarget("testinnerinner"); | |||
assertEquals("Depend did not leave correct number of files", 0, | |||
getResultFiles().size()); | |||
} | |||
/** | |||
* Test that an exception is thrown when there is no source | |||
*/ | |||
public void testNoSource() { | |||
expectBuildExceptionContaining("testnosource", | |||
"No source specified", "srcdir attribute must be set"); | |||
} | |||
/** | |||
* Test that an exception is thrown when the source attribute is empty | |||
*/ | |||
public void testEmptySource() { | |||
expectBuildExceptionContaining("testemptysource", | |||
"No source specified", "srcdir attribute must be non-empty"); | |||
} | |||
private Hashtable getResultFiles() { | |||
FileSet resultFileSet = (FileSet)project.getReference(RESULT_FILESET); | |||
DirectoryScanner scanner = resultFileSet.getDirectoryScanner(project); | |||
String[] scannedFiles = scanner.getIncludedFiles(); | |||
@@ -157,7 +159,18 @@ public class DependTest extends BuildFileTest { | |||
for (int i = 0; i < scannedFiles.length; ++i) { | |||
files.put(scannedFiles[i], scannedFiles[i]); | |||
} | |||
assertEquals("Depend did not leave correct number of files", 0, | |||
files.size()); | |||
return files; | |||
} | |||
/** | |||
* Test mutual dependency between inner and outer do not cause both to be | |||
* deleted | |||
*/ | |||
public void testInnerClosure() { | |||
Project project = getProject(); | |||
executeTarget("testinnerclosure"); | |||
assertEquals("Depend did not leave correct number of files", 2, | |||
getResultFiles().size()); | |||
} | |||
} |