git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@796188 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -784,6 +784,11 @@ Other changes: | |||||
| different executable. | different executable. | ||||
| Bugzilla Report 42132. | Bugzilla Report 42132. | ||||
| * <javac>, <rmic>, <javah> and <native2ascci> now provide a nested | |||||
| element to specify a classpath that will be used when loading the | |||||
| task's (compiler) adapter class. | |||||
| Bugzilla Issue 11143. | |||||
| Changes from Ant 1.7.0 TO Ant 1.7.1 | Changes from Ant 1.7.0 TO Ant 1.7.1 | ||||
| ============================================= | ============================================= | ||||
| @@ -509,6 +509,14 @@ used.</p> | |||||
| </tr> | </tr> | ||||
| </table> | </table> | ||||
| <h4>compilerclasspath <em>since Ant 1.8.0</em></h4> | |||||
| <p>A <a href="../using.html#path">PATH like structure</a> holding the | |||||
| classpath to use when loading the compiler implementation if a | |||||
| custom class has been specified. Doesn't have any effect when | |||||
| using one of the built-in compilers.</p> | |||||
| <h3>Examples</h3> | <h3>Examples</h3> | ||||
| <pre> <javac srcdir="${src}" | <pre> <javac srcdir="${src}" | ||||
| destdir="${build}" | destdir="${build}" | ||||
| @@ -276,6 +276,13 @@ used.</p> | |||||
| </tr> | </tr> | ||||
| </table> | </table> | ||||
| <h4>compilerclasspath <em>since Ant 1.8.0</em></h4> | |||||
| <p>A <a href="../using.html#path">PATH like structure</a> holding the | |||||
| classpath to use when loading the compiler implementation if a | |||||
| custom class has been specified. Doesn't have any effect when | |||||
| using one of the built-in compilers.</p> | |||||
| <h3>Examples</h3> | <h3>Examples</h3> | ||||
| <pre> <rmic classname="com.xyz.FooBar" base="${build}/classes"/></pre> | <pre> <rmic classname="com.xyz.FooBar" base="${build}/classes"/></pre> | ||||
| <p>runs the rmic compiler for the class <code>com.xyz.FooBar</code>. The | <p>runs the rmic compiler for the class <code>com.xyz.FooBar</code>. The | ||||
| @@ -170,6 +170,13 @@ only if a given compiler implementation will be used.</p> | |||||
| </tr> | </tr> | ||||
| </table> | </table> | ||||
| <h4>implementationclasspath <em>since Ant 1.8.0</em></h4> | |||||
| <p>A <a href="../using.html#path">PATH like structure</a> holding the | |||||
| classpath to use when loading the compiler implementation if a | |||||
| custom class has been specified. Doesn't have any effect when | |||||
| using one of the built-in compilers.</p> | |||||
| <h3>Examples</h3> | <h3>Examples</h3> | ||||
| <pre> <javah destdir="c" class="org.foo.bar.Wibble"/></pre> | <pre> <javah destdir="c" class="org.foo.bar.Wibble"/></pre> | ||||
| <p>makes a JNI header of the named class, using the JDK1.2 JNI model. Assuming | <p>makes a JNI header of the named class, using the JDK1.2 JNI model. Assuming | ||||
| @@ -183,6 +183,13 @@ only if a given converter implementation will be used.</p> | |||||
| </tr> | </tr> | ||||
| </table> | </table> | ||||
| <h4>implementationclasspath <em>since Ant 1.8.0</em></h4> | |||||
| <p>A <a href="../using.html#path">PATH like structure</a> holding the | |||||
| classpath to use when loading the converter implementation if a | |||||
| custom class has been specified. Doesn't have any effect when | |||||
| using one of the built-in converters.</p> | |||||
| <h3>Examples</h3> | <h3>Examples</h3> | ||||
| <pre> | <pre> | ||||
| @@ -859,6 +859,16 @@ public class Javac extends MatchingTask { | |||||
| return taskSuccess; | return taskSuccess; | ||||
| } | } | ||||
| /** | |||||
| * The classpath to use when loading the compiler implementation | |||||
| * if it is not a built-in one. | |||||
| * | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public Path createCompilerClasspath() { | |||||
| return facade.getImplementationClasspath(getProject()); | |||||
| } | |||||
| /** | /** | ||||
| * Executes the task. | * Executes the task. | ||||
| * @exception BuildException if an error occurs | * @exception BuildException if an error occurs | ||||
| @@ -1067,7 +1077,8 @@ public class Javac extends MatchingTask { | |||||
| } | } | ||||
| CompilerAdapter adapter = | CompilerAdapter adapter = | ||||
| CompilerAdapterFactory.getCompiler(compilerImpl, this); | |||||
| CompilerAdapterFactory.getCompiler(compilerImpl, this, | |||||
| createCompilerClasspath()); | |||||
| // now we need to populate the compiler adapter | // now we need to populate the compiler adapter | ||||
| adapter.setJavac(this); | adapter.setJavac(this); | ||||
| @@ -509,6 +509,16 @@ public class Rmic extends MatchingTask { | |||||
| return executable; | return executable; | ||||
| } | } | ||||
| /** | |||||
| * The classpath to use when loading the compiler implementation | |||||
| * if it is not a built-in one. | |||||
| * | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public Path createCompilerClasspath() { | |||||
| return facade.getImplementationClasspath(getProject()); | |||||
| } | |||||
| /** | /** | ||||
| * execute by creating an instance of an implementation | * execute by creating an instance of an implementation | ||||
| * class and getting to do the work | * class and getting to do the work | ||||
| @@ -528,7 +538,8 @@ public class Rmic extends MatchingTask { | |||||
| if (verify) { | if (verify) { | ||||
| log("Verify has been turned on.", Project.MSG_VERBOSE); | log("Verify has been turned on.", Project.MSG_VERBOSE); | ||||
| } | } | ||||
| RmicAdapter adapter = RmicAdapterFactory.getRmic(getCompiler(), this); | |||||
| RmicAdapter adapter = RmicAdapterFactory.getRmic(getCompiler(), this, | |||||
| createCompilerClasspath()); | |||||
| // now we need to populate the compiler adapter | // now we need to populate the compiler adapter | ||||
| adapter.setRmic(this); | adapter.setRmic(this); | ||||
| @@ -21,6 +21,7 @@ package org.apache.tools.ant.taskdefs.compilers; | |||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
| import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
| import org.apache.tools.ant.types.Path; | |||||
| import org.apache.tools.ant.util.ClasspathUtils; | import org.apache.tools.ant.util.ClasspathUtils; | ||||
| import org.apache.tools.ant.util.JavaEnvUtils; | import org.apache.tools.ant.util.JavaEnvUtils; | ||||
| @@ -62,6 +63,40 @@ public final class CompilerAdapterFactory { | |||||
| * a compiler adapter. | * a compiler adapter. | ||||
| */ | */ | ||||
| public static CompilerAdapter getCompiler(String compilerType, Task task) | public static CompilerAdapter getCompiler(String compilerType, Task task) | ||||
| throws BuildException { | |||||
| return getCompiler(compilerType, task, null); | |||||
| } | |||||
| /** | |||||
| * Based on the parameter passed in, this method creates the necessary | |||||
| * factory desired. | |||||
| * | |||||
| * The current mapping for compiler names are as follows: | |||||
| * <ul><li>jikes = jikes compiler | |||||
| * <li>classic, javac1.1, javac1.2 = the standard compiler from JDK | |||||
| * 1.1/1.2 | |||||
| * <li>modern, javac1.3, javac1.4, javac1.5 = the compiler of JDK 1.3+ | |||||
| * <li>jvc, microsoft = the command line compiler from Microsoft's SDK | |||||
| * for Java / Visual J++ | |||||
| * <li>kjc = the kopi compiler</li> | |||||
| * <li>gcj = the gcj compiler from gcc</li> | |||||
| * <li>sj, symantec = the Symantec Java compiler</li> | |||||
| * <li><i>a fully qualified classname</i> = the name of a compiler | |||||
| * adapter | |||||
| * </ul> | |||||
| * | |||||
| * @param compilerType either the name of the desired compiler, or the | |||||
| * full classname of the compiler's adapter. | |||||
| * @param task a task to log through. | |||||
| * @param classpath the classpath to use when looking up an | |||||
| * adapter class | |||||
| * @return the compiler adapter | |||||
| * @throws BuildException if the compiler type could not be resolved into | |||||
| * a compiler adapter. | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public static CompilerAdapter getCompiler(String compilerType, Task task, | |||||
| Path classpath) | |||||
| throws BuildException { | throws BuildException { | ||||
| boolean isClassicCompilerSupported = true; | boolean isClassicCompilerSupported = true; | ||||
| //as new versions of java come out, add them to this test | //as new versions of java come out, add them to this test | ||||
| @@ -133,7 +168,8 @@ public final class CompilerAdapterFactory { | |||||
| || compilerType.equalsIgnoreCase("symantec")) { | || compilerType.equalsIgnoreCase("symantec")) { | ||||
| return new Sj(); | return new Sj(); | ||||
| } | } | ||||
| return resolveClassName(compilerType); | |||||
| return resolveClassName(compilerType, | |||||
| task.getProject().createClassLoader(classpath)); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -163,12 +199,15 @@ public final class CompilerAdapterFactory { | |||||
| * Throws a fit if it can't. | * Throws a fit if it can't. | ||||
| * | * | ||||
| * @param className The fully qualified classname to be created. | * @param className The fully qualified classname to be created. | ||||
| * @param loader the classloader to use | |||||
| * @throws BuildException This is the fit that is thrown if className | * @throws BuildException This is the fit that is thrown if className | ||||
| * isn't an instance of CompilerAdapter. | * isn't an instance of CompilerAdapter. | ||||
| */ | */ | ||||
| private static CompilerAdapter resolveClassName(String className) | |||||
| private static CompilerAdapter resolveClassName(String className, | |||||
| ClassLoader loader) | |||||
| throws BuildException { | throws BuildException { | ||||
| return (CompilerAdapter) ClasspathUtils.newInstance(className, | return (CompilerAdapter) ClasspathUtils.newInstance(className, | ||||
| loader != null ? loader : | |||||
| CompilerAdapterFactory.class.getClassLoader(), | CompilerAdapterFactory.class.getClassLoader(), | ||||
| CompilerAdapter.class); | CompilerAdapter.class); | ||||
| } | } | ||||
| @@ -406,6 +406,16 @@ public class Javah extends Task { | |||||
| return facade.getArgs(); | return facade.getArgs(); | ||||
| } | } | ||||
| /** | |||||
| * The classpath to use when loading the javah implementation | |||||
| * if it is not a built-in one. | |||||
| * | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public Path createImplementationClasspath() { | |||||
| return facade.getImplementationClasspath(getProject()); | |||||
| } | |||||
| /** | /** | ||||
| * Execute the task | * Execute the task | ||||
| * | * | ||||
| @@ -443,7 +453,8 @@ public class Javah extends Task { | |||||
| JavahAdapter ad = | JavahAdapter ad = | ||||
| JavahAdapterFactory.getAdapter(facade.getImplementation(), | JavahAdapterFactory.getAdapter(facade.getImplementation(), | ||||
| this); | |||||
| this, | |||||
| createImplementationClasspath()); | |||||
| if (!ad.compile(this)) { | if (!ad.compile(this)) { | ||||
| throw new BuildException("compilation failed"); | throw new BuildException("compilation failed"); | ||||
| } | } | ||||
| @@ -26,6 +26,7 @@ import org.apache.tools.ant.taskdefs.MatchingTask; | |||||
| import org.apache.tools.ant.taskdefs.optional.native2ascii.Native2AsciiAdapter; | import org.apache.tools.ant.taskdefs.optional.native2ascii.Native2AsciiAdapter; | ||||
| import org.apache.tools.ant.taskdefs.optional.native2ascii.Native2AsciiAdapterFactory; | import org.apache.tools.ant.taskdefs.optional.native2ascii.Native2AsciiAdapterFactory; | ||||
| import org.apache.tools.ant.types.Mapper; | import org.apache.tools.ant.types.Mapper; | ||||
| import org.apache.tools.ant.types.Path; | |||||
| import org.apache.tools.ant.util.FileNameMapper; | import org.apache.tools.ant.util.FileNameMapper; | ||||
| import org.apache.tools.ant.util.IdentityMapper; | import org.apache.tools.ant.util.IdentityMapper; | ||||
| import org.apache.tools.ant.util.SourceFileScanner; | import org.apache.tools.ant.util.SourceFileScanner; | ||||
| @@ -173,6 +174,16 @@ public class Native2Ascii extends MatchingTask { | |||||
| return arg; | return arg; | ||||
| } | } | ||||
| /** | |||||
| * The classpath to use when loading the native2ascii | |||||
| * implementation if it is not a built-in one. | |||||
| * | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public Path createImplementationClasspath() { | |||||
| return facade.getImplementationClasspath(getProject()); | |||||
| } | |||||
| /** | /** | ||||
| * Execute the task | * Execute the task | ||||
| * | * | ||||
| @@ -264,7 +275,8 @@ public class Native2Ascii extends MatchingTask { | |||||
| log("converting " + srcName, Project.MSG_VERBOSE); | log("converting " + srcName, Project.MSG_VERBOSE); | ||||
| Native2AsciiAdapter ad = | Native2AsciiAdapter ad = | ||||
| Native2AsciiAdapterFactory.getAdapter(facade.getImplementation(), | Native2AsciiAdapterFactory.getAdapter(facade.getImplementation(), | ||||
| this); | |||||
| this, | |||||
| createImplementationClasspath()); | |||||
| if (!ad.convert(this, srcFile, destFile)) { | if (!ad.convert(this, srcFile, destFile)) { | ||||
| throw new BuildException("conversion failed"); | throw new BuildException("conversion failed"); | ||||
| } | } | ||||
| @@ -19,6 +19,7 @@ package org.apache.tools.ant.taskdefs.optional.javah; | |||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| import org.apache.tools.ant.ProjectComponent; | import org.apache.tools.ant.ProjectComponent; | ||||
| import org.apache.tools.ant.types.Path; | |||||
| import org.apache.tools.ant.util.ClasspathUtils; | import org.apache.tools.ant.util.ClasspathUtils; | ||||
| import org.apache.tools.ant.util.JavaEnvUtils; | import org.apache.tools.ant.util.JavaEnvUtils; | ||||
| @@ -58,13 +59,35 @@ public class JavahAdapterFactory { | |||||
| public static JavahAdapter getAdapter(String choice, | public static JavahAdapter getAdapter(String choice, | ||||
| ProjectComponent log) | ProjectComponent log) | ||||
| throws BuildException { | throws BuildException { | ||||
| return getAdapter(choice, log, null); | |||||
| } | |||||
| /** | |||||
| * Creates the JavahAdapter based on the user choice and | |||||
| * potentially the VM vendor. | |||||
| * | |||||
| * @param choice the user choice (if any). | |||||
| * @param log a ProjectComponent instance used to access Ant's | |||||
| * logging system. | |||||
| * @param classpath the classpath to use when looking up an | |||||
| * adapter class | |||||
| * @return The adapter to use. | |||||
| * @throws BuildException if there is an error. | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public static JavahAdapter getAdapter(String choice, | |||||
| ProjectComponent log, | |||||
| Path classpath) | |||||
| throws BuildException { | |||||
| if ((JavaEnvUtils.isKaffe() && choice == null) | if ((JavaEnvUtils.isKaffe() && choice == null) | ||||
| || Kaffeh.IMPLEMENTATION_NAME.equals(choice)) { | || Kaffeh.IMPLEMENTATION_NAME.equals(choice)) { | ||||
| return new Kaffeh(); | return new Kaffeh(); | ||||
| } else if (SunJavah.IMPLEMENTATION_NAME.equals(choice)) { | } else if (SunJavah.IMPLEMENTATION_NAME.equals(choice)) { | ||||
| return new SunJavah(); | return new SunJavah(); | ||||
| } else if (choice != null) { | } else if (choice != null) { | ||||
| return resolveClassName(choice); | |||||
| return resolveClassName(choice, | |||||
| log.getProject() | |||||
| .createClassLoader(classpath)); | |||||
| } | } | ||||
| // This default has been good enough until Ant 1.6.3, so stick | // This default has been good enough until Ant 1.6.3, so stick | ||||
| @@ -77,12 +100,15 @@ public class JavahAdapterFactory { | |||||
| * Throws a fit if it can't. | * Throws a fit if it can't. | ||||
| * | * | ||||
| * @param className The fully qualified classname to be created. | * @param className The fully qualified classname to be created. | ||||
| * @param loader the classloader to use | |||||
| * @throws BuildException This is the fit that is thrown if className | * @throws BuildException This is the fit that is thrown if className | ||||
| * isn't an instance of JavahAdapter. | * isn't an instance of JavahAdapter. | ||||
| */ | */ | ||||
| private static JavahAdapter resolveClassName(String className) | |||||
| private static JavahAdapter resolveClassName(String className, | |||||
| ClassLoader loader) | |||||
| throws BuildException { | throws BuildException { | ||||
| return (JavahAdapter) ClasspathUtils.newInstance(className, | return (JavahAdapter) ClasspathUtils.newInstance(className, | ||||
| loader != null ? loader : | |||||
| JavahAdapterFactory.class.getClassLoader(), JavahAdapter.class); | JavahAdapterFactory.class.getClassLoader(), JavahAdapter.class); | ||||
| } | } | ||||
| } | } | ||||
| @@ -19,6 +19,7 @@ package org.apache.tools.ant.taskdefs.optional.native2ascii; | |||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| import org.apache.tools.ant.ProjectComponent; | import org.apache.tools.ant.ProjectComponent; | ||||
| import org.apache.tools.ant.types.Path; | |||||
| import org.apache.tools.ant.util.ClasspathUtils; | import org.apache.tools.ant.util.ClasspathUtils; | ||||
| import org.apache.tools.ant.util.JavaEnvUtils; | import org.apache.tools.ant.util.JavaEnvUtils; | ||||
| @@ -46,7 +47,7 @@ public class Native2AsciiAdapterFactory { | |||||
| } | } | ||||
| /** | /** | ||||
| * Creates the Native2AsciiAdapter based on the user choice and * | |||||
| * Creates the Native2AsciiAdapter based on the user choice and | |||||
| * potentially the VM vendor. | * potentially the VM vendor. | ||||
| * | * | ||||
| * @param choice the user choice (if any). | * @param choice the user choice (if any). | ||||
| @@ -58,13 +59,35 @@ public class Native2AsciiAdapterFactory { | |||||
| public static Native2AsciiAdapter getAdapter(String choice, | public static Native2AsciiAdapter getAdapter(String choice, | ||||
| ProjectComponent log) | ProjectComponent log) | ||||
| throws BuildException { | throws BuildException { | ||||
| return getAdapter(choice, log, null); | |||||
| } | |||||
| /** | |||||
| * Creates the Native2AsciiAdapter based on the user choice and | |||||
| * potentially the VM vendor. | |||||
| * | |||||
| * @param choice the user choice (if any). | |||||
| * @param log a ProjectComponent instance used to access Ant's | |||||
| * logging system. | |||||
| * @param classpath the classpath to use when looking up an | |||||
| * adapter class | |||||
| * @return The adapter to use. | |||||
| * @throws BuildException if there was a problem. | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public static Native2AsciiAdapter getAdapter(String choice, | |||||
| ProjectComponent log, | |||||
| Path classpath) | |||||
| throws BuildException { | |||||
| if ((JavaEnvUtils.isKaffe() && choice == null) | if ((JavaEnvUtils.isKaffe() && choice == null) | ||||
| || KaffeNative2Ascii.IMPLEMENTATION_NAME.equals(choice)) { | || KaffeNative2Ascii.IMPLEMENTATION_NAME.equals(choice)) { | ||||
| return new KaffeNative2Ascii(); | return new KaffeNative2Ascii(); | ||||
| } else if (SunNative2Ascii.IMPLEMENTATION_NAME.equals(choice)) { | } else if (SunNative2Ascii.IMPLEMENTATION_NAME.equals(choice)) { | ||||
| return new SunNative2Ascii(); | return new SunNative2Ascii(); | ||||
| } else if (choice != null) { | } else if (choice != null) { | ||||
| return resolveClassName(choice); | |||||
| return resolveClassName(choice, | |||||
| log.getProject() | |||||
| .createClassLoader(classpath)); | |||||
| } | } | ||||
| // This default has been good enough until Ant 1.6.3, so stick | // This default has been good enough until Ant 1.6.3, so stick | ||||
| @@ -77,12 +100,15 @@ public class Native2AsciiAdapterFactory { | |||||
| * Throws a fit if it can't. | * Throws a fit if it can't. | ||||
| * | * | ||||
| * @param className The fully qualified classname to be created. | * @param className The fully qualified classname to be created. | ||||
| * @param loader the classloader to use | |||||
| * @throws BuildException This is the fit that is thrown if className | * @throws BuildException This is the fit that is thrown if className | ||||
| * isn't an instance of Native2AsciiAdapter. | * isn't an instance of Native2AsciiAdapter. | ||||
| */ | */ | ||||
| private static Native2AsciiAdapter resolveClassName(String className) | |||||
| private static Native2AsciiAdapter resolveClassName(String className, | |||||
| ClassLoader loader) | |||||
| throws BuildException { | throws BuildException { | ||||
| return (Native2AsciiAdapter) ClasspathUtils.newInstance(className, | return (Native2AsciiAdapter) ClasspathUtils.newInstance(className, | ||||
| loader != null ? loader : | |||||
| Native2AsciiAdapterFactory.class.getClassLoader(), | Native2AsciiAdapterFactory.class.getClassLoader(), | ||||
| Native2AsciiAdapter.class); | Native2AsciiAdapter.class); | ||||
| } | } | ||||
| @@ -20,6 +20,7 @@ package org.apache.tools.ant.taskdefs.rmic; | |||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
| import org.apache.tools.ant.types.Path; | |||||
| import org.apache.tools.ant.util.ClasspathUtils; | import org.apache.tools.ant.util.ClasspathUtils; | ||||
| import java.util.Locale; | import java.util.Locale; | ||||
| @@ -66,6 +67,35 @@ public final class RmicAdapterFactory { | |||||
| */ | */ | ||||
| public static RmicAdapter getRmic(String rmicType, Task task) | public static RmicAdapter getRmic(String rmicType, Task task) | ||||
| throws BuildException { | throws BuildException { | ||||
| return getRmic(rmicType, task, null); | |||||
| } | |||||
| /** | |||||
| * Based on the parameter passed in, this method creates the necessary | |||||
| * factory desired. | |||||
| * | |||||
| * <p>The current mapping for rmic names are as follows:</p> | |||||
| * <ul><li>sun = SUN's rmic | |||||
| * <li>kaffe = Kaffe's rmic | |||||
| * <li><i>a fully qualified classname</i> = the name of a rmic | |||||
| * adapter | |||||
| * <li>weblogic = weblogic compiler | |||||
| * <li>forking = Sun's RMIC by forking a new JVM | |||||
| * </ul> | |||||
| * | |||||
| * @param rmicType either the name of the desired rmic, or the | |||||
| * full classname of the rmic's adapter. | |||||
| * @param task a task to log through. | |||||
| * @param classpath the classpath to use when looking up an | |||||
| * adapter class | |||||
| * @return the compiler adapter | |||||
| * @throws BuildException if the rmic type could not be resolved into | |||||
| * a rmic adapter. | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public static RmicAdapter getRmic(String rmicType, Task task, | |||||
| Path classpath) | |||||
| throws BuildException { | |||||
| //convert to lower case in the English locale, | //convert to lower case in the English locale, | ||||
| String compiler = rmicType.toLowerCase(Locale.ENGLISH); | String compiler = rmicType.toLowerCase(Locale.ENGLISH); | ||||
| @@ -87,7 +117,8 @@ public final class RmicAdapterFactory { | |||||
| return new XNewRmic(); | return new XNewRmic(); | ||||
| } | } | ||||
| //no match? ask for the non-lower-cased type | //no match? ask for the non-lower-cased type | ||||
| return resolveClassName(rmicType); | |||||
| return resolveClassName(rmicType, | |||||
| task.getProject().createClassLoader(classpath)); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -95,12 +126,15 @@ public final class RmicAdapterFactory { | |||||
| * Throws a fit if it can't. | * Throws a fit if it can't. | ||||
| * | * | ||||
| * @param className The fully qualified classname to be created. | * @param className The fully qualified classname to be created. | ||||
| * @param loader the classloader to use | |||||
| * @throws BuildException This is the fit that is thrown if className | * @throws BuildException This is the fit that is thrown if className | ||||
| * isn't an instance of RmicAdapter. | * isn't an instance of RmicAdapter. | ||||
| */ | */ | ||||
| private static RmicAdapter resolveClassName(String className) | |||||
| private static RmicAdapter resolveClassName(String className, | |||||
| ClassLoader loader) | |||||
| throws BuildException { | throws BuildException { | ||||
| return (RmicAdapter) ClasspathUtils.newInstance(className, | return (RmicAdapter) ClasspathUtils.newInstance(className, | ||||
| loader != null ? loader : | |||||
| RmicAdapterFactory.class.getClassLoader(), RmicAdapter.class); | RmicAdapterFactory.class.getClassLoader(), RmicAdapter.class); | ||||
| } | } | ||||
| } | } | ||||
| @@ -21,6 +21,8 @@ package org.apache.tools.ant.util.facade; | |||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||
| import java.util.Iterator; | import java.util.Iterator; | ||||
| import java.util.List; | import java.util.List; | ||||
| import org.apache.tools.ant.Project; | |||||
| import org.apache.tools.ant.types.Path; | |||||
| /** | /** | ||||
| * Helper class for facade implementations - encapsulates treatment of | * Helper class for facade implementations - encapsulates treatment of | ||||
| @@ -52,6 +54,11 @@ public class FacadeTaskHelper { | |||||
| */ | */ | ||||
| private String defaultValue; | private String defaultValue; | ||||
| /** | |||||
| * User specified path used as classpath when loading the implementation. | |||||
| */ | |||||
| private Path implementationClasspath; | |||||
| /** | /** | ||||
| * @param defaultValue The default value for the implementation. | * @param defaultValue The default value for the implementation. | ||||
| * Must not be null. | * Must not be null. | ||||
| @@ -141,4 +148,18 @@ public class FacadeTaskHelper { | |||||
| public boolean hasBeenSet() { | public boolean hasBeenSet() { | ||||
| return userChoice != null || magicValue != null; | return userChoice != null || magicValue != null; | ||||
| } | } | ||||
| /** | |||||
| * The classpath to use when loading the implementation. | |||||
| * | |||||
| * @param project the current project | |||||
| * @return a Path instance that may be appended to | |||||
| * @since Ant 1.8.0 | |||||
| */ | |||||
| public Path getImplementationClasspath(Project project) { | |||||
| if (implementationClasspath == null) { | |||||
| implementationClasspath = new Path(project); | |||||
| } | |||||
| return implementationClasspath; | |||||
| } | |||||
| } | } | ||||
| @@ -119,4 +119,40 @@ | |||||
| updatedProperty="third-pass"/> | updatedProperty="third-pass"/> | ||||
| <au:assertPropertyEquals name="third-pass" value="true"/> | <au:assertPropertyEquals name="third-pass" value="true"/> | ||||
| </target> | </target> | ||||
| <target name="-create-javac-adapter"> | |||||
| <property name="adapter.dir" location="${output}/adapter"/> | |||||
| <mkdir dir="${input}/org/example"/> | |||||
| <echo file="${input}/org/example/Adapter.java"><![CDATA[ | |||||
| package org.example; | |||||
| import org.apache.tools.ant.taskdefs.compilers.CompilerAdapter; | |||||
| import org.apache.tools.ant.taskdefs.Javac; | |||||
| public class Adapter implements CompilerAdapter { | |||||
| public void setJavac(Javac attributes) {} | |||||
| public boolean execute() { | |||||
| System.err.println("adapter called"); | |||||
| return true; | |||||
| } | |||||
| }]]></echo> | |||||
| <mkdir dir="${adapter.dir}"/> | |||||
| <javac srcdir="${input}" destdir="${adapter.dir}"/> | |||||
| </target> | |||||
| <target name="testCompilerNotFound" depends="-create-javac-adapter"> | |||||
| <au:expectfailure> | |||||
| <javac srcdir="${input}" destdir="${output}" | |||||
| compiler="org.example.Adapter"/> | |||||
| </au:expectfailure> | |||||
| <au:assertLogDoesntContain text="adapter called"/> | |||||
| </target> | |||||
| <target name="testCompilerClasspath" depends="-create-javac-adapter" | |||||
| description="https://issues.apache.org/bugzilla/show_bug.cgi?id=11143"> | |||||
| <javac srcdir="${input}" destdir="${output}" | |||||
| compiler="org.example.Adapter"> | |||||
| <compilerclasspath location="${adapter.dir}"/> | |||||
| </javac> | |||||
| <au:assertLogContains text="adapter called"/> | |||||
| </target> | |||||
| </project> | </project> | ||||
| @@ -0,0 +1,55 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project default="antunit" xmlns:au="antlib:org.apache.ant.antunit"> | |||||
| <import file="../../antunit-base.xml" /> | |||||
| <target name="-create-javah-adapter"> | |||||
| <property name="adapter.dir" location="${output}/adapter"/> | |||||
| <mkdir dir="${input}/org/example"/> | |||||
| <echo file="${input}/org/example/Adapter.java"><![CDATA[ | |||||
| package org.example; | |||||
| import org.apache.tools.ant.taskdefs.optional.javah.JavahAdapter; | |||||
| import org.apache.tools.ant.taskdefs.optional.Javah; | |||||
| public class Adapter implements JavahAdapter { | |||||
| public boolean compile(Javah javah) { | |||||
| System.err.println("adapter called"); | |||||
| return true; | |||||
| } | |||||
| }]]></echo> | |||||
| <mkdir dir="${adapter.dir}"/> | |||||
| <javac srcdir="${input}" destdir="${adapter.dir}"/> | |||||
| </target> | |||||
| <target name="testAdapterNotFound" depends="-create-javah-adapter"> | |||||
| <au:expectfailure> | |||||
| <javah class="org.example.Adapter" destdir="${output}" | |||||
| implementation="org.example.Adapter"/> | |||||
| </au:expectfailure> | |||||
| <au:assertLogDoesntContain text="adapter called"/> | |||||
| </target> | |||||
| <target name="testImplementationClasspath" depends="-create-javah-adapter" | |||||
| description="https://issues.apache.org/bugzilla/show_bug.cgi?id=11143"> | |||||
| <javah class="org.example.Adapter" destdir="${output}" | |||||
| implementation="org.example.Adapter"> | |||||
| <implementationclasspath location="${adapter.dir}"/> | |||||
| </javah> | |||||
| <au:assertLogContains text="adapter called"/> | |||||
| </target> | |||||
| </project> | |||||
| @@ -0,0 +1,56 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project default="antunit" xmlns:au="antlib:org.apache.ant.antunit"> | |||||
| <import file="../../antunit-base.xml" /> | |||||
| <target name="-create-native2ascii-adapter"> | |||||
| <property name="adapter.dir" location="${output}/adapter"/> | |||||
| <mkdir dir="${input}/org/example"/> | |||||
| <echo file="${input}/org/example/Adapter.java"><![CDATA[ | |||||
| package org.example; | |||||
| import java.io.File; | |||||
| import org.apache.tools.ant.taskdefs.optional.native2ascii.Native2AsciiAdapter; | |||||
| import org.apache.tools.ant.taskdefs.optional.Native2Ascii; | |||||
| public class Adapter implements Native2AsciiAdapter { | |||||
| public boolean convert(Native2Ascii native2ascii, File f1, File f2) { | |||||
| System.err.println("adapter called"); | |||||
| return true; | |||||
| } | |||||
| }]]></echo> | |||||
| <mkdir dir="${adapter.dir}"/> | |||||
| <javac srcdir="${input}" destdir="${adapter.dir}"/> | |||||
| </target> | |||||
| <target name="testAdapterNotFound" depends="-create-native2ascii-adapter"> | |||||
| <au:expectfailure> | |||||
| <native2ascii src="${input}" dest="${output}" includes="**/*.java" | |||||
| implementation="org.example.Adapter"/> | |||||
| </au:expectfailure> | |||||
| <au:assertLogDoesntContain text="adapter called"/> | |||||
| </target> | |||||
| <target name="testImplementationClasspath" depends="-create-native2ascii-adapter" | |||||
| description="https://issues.apache.org/bugzilla/show_bug.cgi?id=11143"> | |||||
| <native2ascii src="${input}" dest="${output}" includes="**/*.java" | |||||
| implementation="org.example.Adapter"> | |||||
| <implementationclasspath location="${adapter.dir}"/> | |||||
| </native2ascii> | |||||
| <au:assertLogContains text="adapter called"/> | |||||
| </target> | |||||
| </project> | |||||
| @@ -0,0 +1,69 @@ | |||||
| <?xml version="1.0"?> | |||||
| <!-- | |||||
| Licensed to the Apache Software Foundation (ASF) under one or more | |||||
| contributor license agreements. See the NOTICE file distributed with | |||||
| this work for additional information regarding copyright ownership. | |||||
| The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
| (the "License"); you may not use this file except in compliance with | |||||
| the License. You may obtain a copy of the License at | |||||
| http://www.apache.org/licenses/LICENSE-2.0 | |||||
| Unless required by applicable law or agreed to in writing, software | |||||
| distributed under the License is distributed on an "AS IS" BASIS, | |||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| See the License for the specific language governing permissions and | |||||
| limitations under the License. | |||||
| --> | |||||
| <project default="antunit" xmlns:au="antlib:org.apache.ant.antunit"> | |||||
| <import file="../antunit-base.xml" /> | |||||
| <target name="-create-rmic-adapter"> | |||||
| <property name="adapter.dir" location="${output}/adapter"/> | |||||
| <mkdir dir="${input}/org/example"/> | |||||
| <echo file="${input}/org/example/Adapter.java"><![CDATA[ | |||||
| package org.example; | |||||
| import org.apache.tools.ant.taskdefs.rmic.RmicAdapter; | |||||
| import org.apache.tools.ant.taskdefs.Rmic; | |||||
| import org.apache.tools.ant.types.Path; | |||||
| import org.apache.tools.ant.util.FileNameMapper; | |||||
| import org.apache.tools.ant.util.GlobPatternMapper; | |||||
| public class Adapter implements RmicAdapter { | |||||
| public void setRmic(Rmic attributes) {} | |||||
| public boolean execute() { | |||||
| System.err.println("adapter called"); | |||||
| return true; | |||||
| } | |||||
| public FileNameMapper getMapper() { | |||||
| GlobPatternMapper m = new GlobPatternMapper(); | |||||
| m.setFrom("*.class"); | |||||
| m.setTo("*_foo.class"); | |||||
| return m; | |||||
| } | |||||
| public Path getClasspath() { | |||||
| return new Path(null); | |||||
| } | |||||
| }]]></echo> | |||||
| <mkdir dir="${adapter.dir}"/> | |||||
| <javac srcdir="${input}" destdir="${adapter.dir}"/> | |||||
| </target> | |||||
| <target name="testCompilerNotFound" depends="-create-rmic-adapter"> | |||||
| <au:expectfailure> | |||||
| <rmic base="${adapter.dir}" includes="**/*.class" | |||||
| compiler="org.example.Adapter"/> | |||||
| </au:expectfailure> | |||||
| <au:assertLogDoesntContain text="adapter called"/> | |||||
| </target> | |||||
| <target name="testCompilerClasspath" depends="-create-rmic-adapter" | |||||
| description="https://issues.apache.org/bugzilla/show_bug.cgi?id=11143"> | |||||
| <rmic base="${adapter.dir}" includes="**/*.class" | |||||
| compiler="org.example.Adapter"> | |||||
| <compilerclasspath location="${adapter.dir}"/> | |||||
| </rmic> | |||||
| <au:assertLogContains text="adapter called"/> | |||||
| </target> | |||||
| </project> | |||||