git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@276757 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -32,12 +32,18 @@ supports all attributes of <code><fileset></code> | |||||
| <code><patternset></code> elements.</p> | <code><patternset></code> elements.</p> | ||||
| <p>It is possible to use different compilers. This can be selected | <p>It is possible to use different compilers. This can be selected | ||||
| with the "build.rmic" property or the <code>compiler</code> | with the "build.rmic" property or the <code>compiler</code> | ||||
| attribute. <a name="compilervalues">There are three choices</a>:</p> | |||||
| attribute. | |||||
| <a name="compilervalues">Here are the choices</a>:</p> | |||||
| <ul> | <ul> | ||||
| <li>default -the default compiler (kaffe or sun) for the platform. | |||||
| <li>sun (the standard compiler of the JDK)</li> | <li>sun (the standard compiler of the JDK)</li> | ||||
| <li>kaffe (the standard compiler of <a href="http://www.kaffe.org" target="_top">Kaffe</a>)</li> | <li>kaffe (the standard compiler of <a href="http://www.kaffe.org" target="_top">Kaffe</a>)</li> | ||||
| <li>weblogic</li> | <li>weblogic</li> | ||||
| <li>forking - the sun compiler forked into a separate process</li> | <li>forking - the sun compiler forked into a separate process</li> | ||||
| <li> "" (empty string). This has the same behaviour as not setting the compiler attribute. | |||||
| First the value of <tt>build.rmic<tt> is used if defined, and if not, the default | |||||
| for the platform is chosen. If build.rmic is set to this, you get the default. | |||||
| </ul> | </ul> | ||||
| <p>The <a href="http://dione.zcu.cz/~toman40/miniRMI/">miniRMI</a> | <p>The <a href="http://dione.zcu.cz/~toman40/miniRMI/">miniRMI</a> | ||||
| @@ -15,7 +15,8 @@ | |||||
| <javac | <javac | ||||
| destdir="${build.dir}" | destdir="${build.dir}" | ||||
| srcdir="${src.dir}" > | |||||
| srcdir="${src.dir}" | |||||
| includes="Remote*.java"> | |||||
| </javac> | </javac> | ||||
| <presetdef name="base-rmic"> | <presetdef name="base-rmic"> | ||||
| @@ -24,6 +25,38 @@ | |||||
| verify="true" | verify="true" | ||||
| includes="**/*.class"/> | includes="**/*.class"/> | ||||
| </presetdef> | </presetdef> | ||||
| <presetdef name="rmic-bad-class"> | |||||
| <rmic | |||||
| base="${build.dir}" | |||||
| verify="false" | |||||
| classname="unimplemented.class" | |||||
| /> | |||||
| </presetdef> | |||||
| <macrodef name="assertFileCreated"> | |||||
| <attribute name="file" /> | |||||
| <sequential> | |||||
| <property name="file.to.find" location="${build.dir}/@{file}" /> | |||||
| <available property="file.found" file="${file.to.find}"/> | |||||
| <fail unless="file.found">Not found : ${file.to.find}</fail> | |||||
| </sequential> | |||||
| </macrodef> | |||||
| <macrodef name="assertBaseCompiled"> | |||||
| <sequential> | |||||
| <assertFileCreated file="RemoteTimestampImpl_Stub.class" /> | |||||
| <assertFileCreated file="RemoteTimestampImpl_Skel.class"/> | |||||
| </sequential> | |||||
| </macrodef> | |||||
| <macrodef name="assertAntCompiled"> | |||||
| <sequential> | |||||
| <assertFileCreated file="AntTimestamp_Stub.class"/> | |||||
| <assertFileCreated file="AntTimestamp_Skel.class"/> | |||||
| </sequential> | |||||
| </macrodef> | |||||
| </target> | </target> | ||||
| <target name="probe-rmic"> | <target name="probe-rmic"> | ||||
| @@ -31,15 +64,27 @@ | |||||
| <available property="rmic.present" classname="sun.rmi.rmic.Main"/> | <available property="rmic.present" classname="sun.rmi.rmic.Main"/> | ||||
| <available property="wlrmic.present" classname="weblogic.rmic"/> | <available property="wlrmic.present" classname="weblogic.rmic"/> | ||||
| </target> | </target> | ||||
| <target name="testDefault" depends="init"> | |||||
| <base-rmic compiler="default"/> | |||||
| <assertBaseCompiled/> | |||||
| </target> | |||||
| <target name="testEmpty" depends="init"> | |||||
| <base-rmic compiler=""/> | |||||
| <assertBaseCompiled/> | |||||
| </target> | |||||
| <target name="testRmic" if="rmic.present" depends="init"> | <target name="testRmic" if="rmic.present" depends="init"> | ||||
| <base-rmic /> | |||||
| <base-rmic compiler="sun"/> | |||||
| <assertBaseCompiled/> | |||||
| </target> | </target> | ||||
| <target name="testKaffe" if="kaffe.present" depends="init"> | <target name="testKaffe" if="kaffe.present" depends="init"> | ||||
| <base-rmic | <base-rmic | ||||
| compiler="kaffe" | compiler="kaffe" | ||||
| /> | /> | ||||
| <assertBaseCompiled/> | |||||
| </target> | </target> | ||||
| <target name="testWlrmic" if="wlrmic.present" depends="init"> | <target name="testWlrmic" if="wlrmic.present" depends="init"> | ||||
| @@ -52,6 +97,7 @@ | |||||
| <base-rmic | <base-rmic | ||||
| compiler="forking" | compiler="forking" | ||||
| /> | /> | ||||
| <assertBaseCompiled/> | |||||
| </target> | </target> | ||||
| <target name="testBadName" if="rmic.present" depends="init"> | <target name="testBadName" if="rmic.present" depends="init"> | ||||
| @@ -86,4 +132,54 @@ | |||||
| includes="**/*.class"/> | includes="**/*.class"/> | ||||
| </target> | </target> | ||||
| <target name="testFailingAdapter" depends="init"> | |||||
| <base-rmic | |||||
| compiler="org.apache.tools.ant.taskdefs.rmic.RmicAdvancedTest$FailingRmicAdapter" | |||||
| /> | |||||
| </target> | |||||
| <target name="compileAntTimestamp" depends="init"> | |||||
| <javac | |||||
| destdir="${build.dir}" | |||||
| srcdir="${src.dir}" | |||||
| includes="Ant*.java"> | |||||
| </javac> | |||||
| </target> | |||||
| <target name="testAntClasspath" depends="compileAntTimestamp"> | |||||
| <base-rmic | |||||
| compiler="default" | |||||
| /> | |||||
| <assertAntCompiled/> | |||||
| </target> | |||||
| <target name="testForkingAntClasspath" if="rmic.present" depends="compileAntTimestamp"> | |||||
| <base-rmic | |||||
| compiler="forking" | |||||
| /> | |||||
| <assertAntCompiled /> | |||||
| </target> | |||||
| <target name="testDefaultBadClass" depends="init"> | |||||
| <rmic-bad-class compiler="default"/> | |||||
| </target> | |||||
| <target name="testMagicProperty" depends="init"> | |||||
| <property name="build.rmic" value="no-such-adapter"/> | |||||
| <base-rmic | |||||
| /> | |||||
| </target> | |||||
| <target name="testMagicPropertyOverridesEmptyString" depends="init"> | |||||
| <property name="build.rmic" value="no-such-adapter"/> | |||||
| <base-rmic compiler="" | |||||
| /> | |||||
| </target> | |||||
| <target name="testMagicPropertyIsEmptyString" depends="init"> | |||||
| <property name="build.rmic" value=""/> | |||||
| <base-rmic /> | |||||
| <assertBaseCompiled/> | |||||
| </target> | |||||
| </project> | </project> | ||||
| @@ -0,0 +1,29 @@ | |||||
| import java.rmi.Remote; | |||||
| import java.rmi.RemoteException; | |||||
| import java.util.Calendar; | |||||
| import org.apache.tools.ant.BuildException; | |||||
| import org.apache.tools.ant.util.DateUtils; | |||||
| /** | |||||
| * This class imports a dependency on the Ant runtime classes, | |||||
| * so tests that classpath setup include them | |||||
| */ | |||||
| public class AntTimestamp implements RemoteTimestamp { | |||||
| /** | |||||
| * return the phase of the moon. | |||||
| * Note the completely different semantics of the other implementation, | |||||
| * which goes to show why signature is an inadeuqate way of verifying | |||||
| * how well an interface is implemented. | |||||
| * | |||||
| * @return | |||||
| * @throws RemoteException | |||||
| */ | |||||
| public long when() throws RemoteException { | |||||
| Calendar cal=Calendar.getInstance(); | |||||
| return DateUtils.getPhaseOfMoon(cal); | |||||
| } | |||||
| } | |||||
| @@ -80,7 +80,7 @@ import org.apache.tools.ant.util.facade.FacadeTaskHelper; | |||||
| public class Rmic extends MatchingTask { | public class Rmic extends MatchingTask { | ||||
| private static final String FAIL_MSG | |||||
| public static final String ERROR_RMIC_FAILED | |||||
| = "Rmic failed; see the compiler error output for details."; | = "Rmic failed; see the compiler error output for details."; | ||||
| private File baseDir; | private File baseDir; | ||||
| @@ -116,8 +116,7 @@ public class Rmic extends MatchingTask { | |||||
| public static final String ERROR_BASE_NOT_SET = "base attribute must be set!"; | public static final String ERROR_BASE_NOT_SET = "base attribute must be set!"; | ||||
| public Rmic() { | public Rmic() { | ||||
| String facadeName=KaffeRmic.isAvailable()?"kaffe":"sun"; | |||||
| facade = new FacadeTaskHelper(facadeName); | |||||
| facade = new FacadeTaskHelper(RmicAdapterFactory.DEFAULT_COMPILER); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -398,7 +397,9 @@ public class Rmic extends MatchingTask { | |||||
| * @since Ant 1.5 | * @since Ant 1.5 | ||||
| */ | */ | ||||
| public void setCompiler(String compiler) { | public void setCompiler(String compiler) { | ||||
| facade.setImplementation(compiler); | |||||
| if(compiler.length()>0) { | |||||
| facade.setImplementation(compiler); | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -481,7 +482,7 @@ public class Rmic extends MatchingTask { | |||||
| // finally, lets execute the compiler!! | // finally, lets execute the compiler!! | ||||
| if (!adapter.execute()) { | if (!adapter.execute()) { | ||||
| throw new BuildException(FAIL_MSG, getLocation()); | |||||
| throw new BuildException(ERROR_RMIC_FAILED, getLocation()); | |||||
| } | } | ||||
| } | } | ||||
| @@ -583,9 +584,9 @@ public class Rmic extends MatchingTask { | |||||
| } | } | ||||
| for (int i = 0; i < newFiles.length; i++) { | for (int i = 0; i < newFiles.length; i++) { | ||||
| String classname = newFiles[i].replace(File.separatorChar, '.'); | |||||
| classname = classname.substring(0, classname.lastIndexOf(".class")); | |||||
| compileList.addElement(classname); | |||||
| String name = newFiles[i].replace(File.separatorChar, '.'); | |||||
| name = name.substring(0, name.lastIndexOf(".class")); | |||||
| compileList.addElement(name); | |||||
| } | } | ||||
| } | } | ||||
| @@ -41,6 +41,11 @@ import java.io.IOException; | |||||
| */ | */ | ||||
| public class ForkingSunRmic extends DefaultRmicAdapter { | public class ForkingSunRmic extends DefaultRmicAdapter { | ||||
| /** | |||||
| * the name of this adapter for users to select | |||||
| */ | |||||
| public static final String COMPILER_NAME = "forking"; | |||||
| /** | /** | ||||
| * exec by creating a new command | * exec by creating a new command | ||||
| * @return | * @return | ||||
| @@ -63,6 +68,7 @@ public class ForkingSunRmic extends DefaultRmicAdapter { | |||||
| exe.setAntRun(project); | exe.setAntRun(project); | ||||
| exe.setWorkingDirectory(project.getBaseDir()); | exe.setWorkingDirectory(project.getBaseDir()); | ||||
| exe.setCommandline(args); | exe.setCommandline(args); | ||||
| exe.execute(); | exe.execute(); | ||||
| return exe.getExitValue()==0; | return exe.getExitValue()==0; | ||||
| } catch (IOException exception) { | } catch (IOException exception) { | ||||
| @@ -21,7 +21,6 @@ import java.lang.reflect.Constructor; | |||||
| import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||
| 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.util.facade.FacadeTaskHelper; | |||||
| import org.apache.tools.ant.types.Commandline; | import org.apache.tools.ant.types.Commandline; | ||||
| /** | /** | ||||
| @@ -31,6 +30,11 @@ import org.apache.tools.ant.types.Commandline; | |||||
| */ | */ | ||||
| public class KaffeRmic extends DefaultRmicAdapter { | public class KaffeRmic extends DefaultRmicAdapter { | ||||
| public static final String RMIC_CLASSNAME = "kaffe.rmi.rmic.RMIC"; | public static final String RMIC_CLASSNAME = "kaffe.rmi.rmic.RMIC"; | ||||
| /** | |||||
| * the name of this adapter for users to select | |||||
| */ | |||||
| public static final String COMPILER_NAME = "kaffe"; | |||||
| public boolean execute() throws BuildException { | public boolean execute() throws BuildException { | ||||
| getRmic().log("Using Kaffe rmic", Project.MSG_VERBOSE); | getRmic().log("Using Kaffe rmic", Project.MSG_VERBOSE); | ||||
| @@ -51,19 +55,19 @@ public class KaffeRmic extends DefaultRmicAdapter { | |||||
| + "set the environment variable " | + "set the environment variable " | ||||
| + "JAVA_HOME or CLASSPATH.", | + "JAVA_HOME or CLASSPATH.", | ||||
| getRmic().getLocation()); | getRmic().getLocation()); | ||||
| } catch (BuildException ex) { | |||||
| //rethrow | |||||
| throw ex; | |||||
| } catch (Exception ex) { | } catch (Exception ex) { | ||||
| if (ex instanceof BuildException) { | |||||
| throw (BuildException) ex; | |||||
| } else { | |||||
| throw new BuildException("Error starting Kaffe rmic: ", | |||||
| //wrap | |||||
| throw new BuildException("Error starting Kaffe rmic: ", | |||||
| ex, getRmic().getLocation()); | ex, getRmic().getLocation()); | ||||
| } | |||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * test for kaffe being on the system | * test for kaffe being on the system | ||||
| * @return | |||||
| * @return true if kaffe is on the current classpath | |||||
| */ | */ | ||||
| public static boolean isAvailable() { | public static boolean isAvailable() { | ||||
| try { | try { | ||||
| @@ -29,6 +29,7 @@ import org.apache.tools.ant.Task; | |||||
| public class RmicAdapterFactory { | public class RmicAdapterFactory { | ||||
| public static final String ERROR_UNKNOWN_COMPILER = "Cannot find the compiler or class: "; | public static final String ERROR_UNKNOWN_COMPILER = "Cannot find the compiler or class: "; | ||||
| public static final String ERROR_NOT_RMIC_ADAPTER = "Not an rmic adapter: "; | public static final String ERROR_NOT_RMIC_ADAPTER = "Not an rmic adapter: "; | ||||
| public static final String DEFAULT_COMPILER = "default"; | |||||
| /** This is a singleton -- can't create instances!! */ | /** This is a singleton -- can't create instances!! */ | ||||
| private RmicAdapterFactory() { | private RmicAdapterFactory() { | ||||
| @@ -55,13 +56,22 @@ public class RmicAdapterFactory { | |||||
| */ | */ | ||||
| public static RmicAdapter getRmic(String rmicType, Task task) | public static RmicAdapter getRmic(String rmicType, Task task) | ||||
| throws BuildException { | throws BuildException { | ||||
| if (rmicType.equalsIgnoreCase("sun")) { | |||||
| //handle default specially. | |||||
| if(DEFAULT_COMPILER.equalsIgnoreCase(rmicType) || rmicType.length()==0) { | |||||
| String adapter = KaffeRmic.isAvailable() ? | |||||
| KaffeRmic.COMPILER_NAME | |||||
| :SunRmic.COMPILER_NAME; | |||||
| return getRmic(adapter,task); | |||||
| } | |||||
| if (SunRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) { | |||||
| return new SunRmic(); | return new SunRmic(); | ||||
| } else if (rmicType.equalsIgnoreCase("kaffe")) { | |||||
| } else if (KaffeRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) { | |||||
| return new KaffeRmic(); | return new KaffeRmic(); | ||||
| } else if (rmicType.equalsIgnoreCase("weblogic")) { | |||||
| } else if (WLRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) { | |||||
| return new WLRmic(); | return new WLRmic(); | ||||
| } else if (rmicType.equalsIgnoreCase("forking")) { | |||||
| } else if (ForkingSunRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) { | |||||
| return new ForkingSunRmic(); | return new ForkingSunRmic(); | ||||
| } | } | ||||
| return resolveClassName(rmicType); | return resolveClassName(rmicType); | ||||
| @@ -38,6 +38,11 @@ public class SunRmic extends DefaultRmicAdapter { | |||||
| */ | */ | ||||
| public static final String RMIC_CLASSNAME = "sun.rmi.rmic.Main"; | public static final String RMIC_CLASSNAME = "sun.rmi.rmic.Main"; | ||||
| /** | |||||
| * the name of this adapter for users to select | |||||
| */ | |||||
| public static final String COMPILER_NAME = "sun"; | |||||
| /** | /** | ||||
| * name of the executable | * name of the executable | ||||
| */ | */ | ||||
| @@ -30,6 +30,11 @@ import org.apache.tools.ant.types.Commandline; | |||||
| */ | */ | ||||
| public class WLRmic extends DefaultRmicAdapter { | public class WLRmic extends DefaultRmicAdapter { | ||||
| public static final String WLRMIC_CLASSNAME = "weblogic.rmic"; | public static final String WLRMIC_CLASSNAME = "weblogic.rmic"; | ||||
| /** | |||||
| * the name of this adapter for users to select | |||||
| */ | |||||
| public static final String COMPILER_NAME = "weblogic"; | |||||
| public static final String ERROR_NO_WLRMIC_ON_CLASSPATH = "Cannot use WebLogic rmic, as it is not " | public static final String ERROR_NO_WLRMIC_ON_CLASSPATH = "Cannot use WebLogic rmic, as it is not " | ||||
| + "available. A common solution is to " | + "available. A common solution is to " | ||||
| + "set the environment variable " | + "set the environment variable " | ||||
| @@ -19,7 +19,9 @@ | |||||
| package org.apache.tools.ant.taskdefs; | package org.apache.tools.ant.taskdefs; | ||||
| import org.apache.tools.ant.BuildFileTest; | import org.apache.tools.ant.BuildFileTest; | ||||
| import org.apache.tools.ant.BuildException; | |||||
| import org.apache.tools.ant.taskdefs.rmic.RmicAdapterFactory; | import org.apache.tools.ant.taskdefs.rmic.RmicAdapterFactory; | ||||
| import org.apache.tools.ant.taskdefs.rmic.DefaultRmicAdapter; | |||||
| /** | /** | ||||
| * Date: 04-Aug-2004 | * Date: 04-Aug-2004 | ||||
| @@ -47,6 +49,19 @@ public class RmicAdvancedTest extends BuildFileTest { | |||||
| executeTarget("teardown"); | executeTarget("teardown"); | ||||
| } | } | ||||
| /** | |||||
| * verify that "default" binds us to the default compiler | |||||
| */ | |||||
| public void testDefault() throws Exception { | |||||
| executeTarget("testDefault"); | |||||
| } | |||||
| /** | |||||
| * verify that "" binds us to the default compiler | |||||
| */ | |||||
| public void testEmpty() throws Exception { | |||||
| executeTarget("testEmpty"); | |||||
| } | |||||
| /** | /** | ||||
| * A unit test for JUnit | * A unit test for JUnit | ||||
| */ | */ | ||||
| @@ -68,12 +83,26 @@ public class RmicAdvancedTest extends BuildFileTest { | |||||
| } | } | ||||
| /** | /** | ||||
| * A unit test for JUnit | |||||
| * test the forking compiler | |||||
| */ | */ | ||||
| public void testForking() throws Exception { | |||||
| public void NotestForking() throws Exception { | |||||
| executeTarget("testForking"); | executeTarget("testForking"); | ||||
| } | } | ||||
| /** | |||||
| * test the forking compiler | |||||
| */ | |||||
| public void NotestForkingAntClasspath() throws Exception { | |||||
| executeTarget("testForkingAntClasspath"); | |||||
| } | |||||
| /** | |||||
| * test the forking compiler | |||||
| */ | |||||
| public void testAntClasspath() throws Exception { | |||||
| executeTarget("testAntClasspath"); | |||||
| } | |||||
| /** | /** | ||||
| * A unit test for JUnit | * A unit test for JUnit | ||||
| */ | */ | ||||
| @@ -91,5 +120,70 @@ public class RmicAdvancedTest extends BuildFileTest { | |||||
| "class not an RMIC adapter", | "class not an RMIC adapter", | ||||
| RmicAdapterFactory.ERROR_NOT_RMIC_ADAPTER); | RmicAdapterFactory.ERROR_NOT_RMIC_ADAPTER); | ||||
| } | } | ||||
| /** | |||||
| * A unit test for JUnit | |||||
| */ | |||||
| public void testDefaultBadClass() throws Exception { | |||||
| expectBuildExceptionContaining("testDefaultBadClass", | |||||
| "expected the class to fail", | |||||
| Rmic.ERROR_RMIC_FAILED); | |||||
| //dont look for much text here as it is vendor and version dependent | |||||
| assertLogContaining("unimplemented.class"); | |||||
| } | |||||
| /** | |||||
| * A unit test for JUnit | |||||
| */ | |||||
| public void testMagicProperty() throws Exception { | |||||
| expectBuildExceptionContaining("testMagicProperty", | |||||
| "magic property not working", | |||||
| RmicAdapterFactory.ERROR_UNKNOWN_COMPILER); | |||||
| } | |||||
| /** | |||||
| * A unit test for JUnit | |||||
| */ | |||||
| public void testMagicPropertyOverridesEmptyString() throws Exception { | |||||
| expectBuildExceptionContaining("testMagicPropertyOverridesEmptyString", | |||||
| "magic property not working", | |||||
| RmicAdapterFactory.ERROR_UNKNOWN_COMPILER); | |||||
| } | |||||
| /** | |||||
| * test the forking compiler | |||||
| */ | |||||
| public void testMagicPropertyIsEmptyString() throws Exception { | |||||
| executeTarget("testMagicPropertyIsEmptyString"); | |||||
| } | |||||
| public void NotestFailingAdapter() throws Exception { | |||||
| expectBuildExceptionContaining("testFailingAdapter", | |||||
| "expected failures to propagate", | |||||
| Rmic.ERROR_RMIC_FAILED); | |||||
| } | |||||
| /** | |||||
| * this little bunny verifies that we can load stuff, and that | |||||
| * a failure to execute is turned into a fault | |||||
| */ | |||||
| public static class FailingRmicAdapter extends DefaultRmicAdapter { | |||||
| public static final String LOG_MESSAGE = "hello from FailingRmicAdapter"; | |||||
| /** | |||||
| * Executes the task. | |||||
| * | |||||
| * @return false -always | |||||
| */ | |||||
| public boolean execute() throws BuildException { | |||||
| getRmic().log(LOG_MESSAGE); | |||||
| return false; | |||||
| } | |||||
| } | |||||
| } | } | ||||