I have been setting up a new project here and had been wondering how to allow antunit and ant-contrib to be added without too much messing around. I do not want to get the developers to place the antlibs in ~/.ant/lib or $ANT_HOME/lib, - different projects will use different antlibs and I do not want to pollute the project class paths with unneeded jars. Work arounds of using <typedef> in the build file is possible but ikky.
I then had a brainwave, why not have a .ant/lib directory in the project directory (defined as the directory that contains the build file). This would act in the same way as ~/.ant/lib, any jar files in this directory will be added to the Project classpath by Launcher. This would allow antlibs to be added to a project (via source code control) without configuration, it would also allow ant's optional tasks to be using with modifing ~/.ant/lib or $ANT_HOME/lib (or using the -lib command line option). The diff is: Index: src/main/org/apache/tools/ant/launch/Launcher.java =================================================================== --- src/main/org/apache/tools/ant/launch/Launcher.java (revision 478174) +++ src/main/org/apache/tools/ant/launch/Launcher.java (working copy) @@ -35,6 +35,9 @@ */ public class Launcher { + /** The default build file name. [EMAIL PROTECTED] */ + public static final String DEFAULT_BUILD_FILENAME = "build.xml"; + /** * The Ant Home (installation) Directory property. * [EMAIL PROTECTED] @@ -70,6 +73,15 @@ ANT_PRIVATEDIR + File.separatorChar + ANT_PRIVATELIB; /** + * The location of a per-project library directory. + * <p> + * This is currently the same as the [EMAIL PROTECTED] #USER_LIBDIR} + * relative to the build file. + */ + public static final String PROJECT_LIBDIR = USER_LIBDIR; + + + /** * The startup class that is to be run. * [EMAIL PROTECTED] */ @@ -157,6 +169,8 @@ throws LaunchException, MalformedURLException { String antHomeProperty = System.getProperty(ANTHOME_PROPERTY); File antHome = null; + String buildFileName = null; + String findFileName = null; File sourceJar = Locator.getClassSource(getClass()); File jarDir = sourceJar.getParentFile(); @@ -204,6 +218,28 @@ noUserLib = true; } else if (args[i].equals("--noclasspath") || args[i].equals("-noclasspath")) { noClassPath = true; + } else if (args[i].equals("-find") || args[i].equals("-s")) { + if (i == args.length - 1) { + findFileName = DEFAULT_BUILD_FILENAME; + argList.add(args[i]); + } else { + findFileName = args[i + 1]; + argList.add(args[i]); + argList.add(args[i + 1]); + i++; + } + } else if (args[i].equals("-buildfile") + || args[i].equals("-file") + || args[i].equals("-f")) { + if (i == args.length - 1) { + buildFileName = DEFAULT_BUILD_FILENAME; + argList.add(args[i]); + } else { + buildFileName = args[i + 1]; + argList.add(args[i]); + argList.add(args[i + 1]); + i++; + } } else if (args[i].equals("-main")) { if (i == args.length - 1) { throw new LaunchException("The -main argument must " @@ -252,20 +288,34 @@ System.setProperty(ANTLIBDIR_PROPERTY, antLibDir.getAbsolutePath()); } URL[] systemJars = Locator.getLocationURLs(antLibDir); - + System.out.println("HERE I AM"); File userLibDir = new File(System.getProperty(USER_HOMEDIR), USER_LIBDIR); URL[] userJars = noUserLib ? new URL[0] : Locator.getLocationURLs(userLibDir); + File projectLibDir = findProjectAntLib(buildFileName, findFileName); - int numJars = libJars.length + userJars.length + systemJars.length; + URL[] projectJars = (projectLibDir == null) + ? new URL[0] : Locator.getLocationURLs(projectLibDir); + + int numJars = libJars.length + projectJars.length + + userJars.length + systemJars.length; if (toolsJar != null) { numJars++; } URL[] jars = new URL[numJars]; System.arraycopy(libJars, 0, jars, 0, libJars.length); - System.arraycopy(userJars, 0, jars, libJars.length, userJars.length); - System.arraycopy(systemJars, 0, jars, userJars.length + libJars.length, + System.arraycopy( + projectJars, 0, jars, + libJars.length, + projectJars.length); + System.arraycopy( + userJars, 0, jars, + libJars.length + projectJars.length, + userJars.length); + System.arraycopy( + systemJars, 0, jars, + libJars.length + projectJars.length + userJars.length, systemJars.length); if (toolsJar != null) { @@ -309,4 +359,69 @@ } return exitCode; } + + /** + * Search parent directories for the build file. + * This is a near copy of same method from Main.java, + * but this method does not throw an exception if the + * build file cannot be found, instead it returns null. + * <p> + * Takes the given target as a suffix to append to each + * parent directory in search of a build file. Once the + * root of the file-system has been reached an exception + * is thrown. + * + * @param start Leaf directory of search. + * Must not be <code>null</code>. + * @param filename Suffix filename to look for in parents. + * Must not be <code>null</code>. + * + * @return A handle to the build file if one is found, null + * if not found. + * + * @exception BuildException if no build file is found + */ + private File findBuildFile(String start, String filename) { + File parent = new File(new File(start).getAbsolutePath()); + File file = new File(parent, filename); + + // check if the target file exists in the current directory + while (!file.exists()) { + // change to parent directory + parent = file.getParentFile(); + + // if parent is null, then we are at the root of the fs, + // retunr null as we cannot find the file + if (parent == null) { + return null; + } + + // refresh our file handle + file = new File(parent, filename); + } + + return file; + } + + private File findProjectAntLib(String buildName, String findName) { + File buildFile = null; + if (buildName != null) { + buildFile = new File(buildName).getAbsoluteFile(); + } else if (findName != null) { + buildFile = findBuildFile( + System.getProperty("user.dir"), findName); + } else { + buildFile = new File(DEFAULT_BUILD_FILENAME).getAbsoluteFile(); + } + File buildDir = buildFile.getParentFile(); + if (buildDir == null) { + return null; + } + File projectAntLib = new File(buildDir, PROJECT_LIBDIR); + if (projectAntLib.isDirectory()) { + return projectAntLib; + } else { + return null; + } + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]