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> | |||
| <p>It is possible to use different compilers. This can be selected | |||
| 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> | |||
| <li>default -the default compiler (kaffe or sun) for the platform. | |||
| <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>weblogic</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> | |||
| <p>The <a href="http://dione.zcu.cz/~toman40/miniRMI/">miniRMI</a> | |||
| @@ -15,7 +15,8 @@ | |||
| <javac | |||
| destdir="${build.dir}" | |||
| srcdir="${src.dir}" > | |||
| srcdir="${src.dir}" | |||
| includes="Remote*.java"> | |||
| </javac> | |||
| <presetdef name="base-rmic"> | |||
| @@ -24,6 +25,38 @@ | |||
| verify="true" | |||
| includes="**/*.class"/> | |||
| </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 name="probe-rmic"> | |||
| @@ -31,15 +64,27 @@ | |||
| <available property="rmic.present" classname="sun.rmi.rmic.Main"/> | |||
| <available property="wlrmic.present" classname="weblogic.rmic"/> | |||
| </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"> | |||
| <base-rmic /> | |||
| <base-rmic compiler="sun"/> | |||
| <assertBaseCompiled/> | |||
| </target> | |||
| <target name="testKaffe" if="kaffe.present" depends="init"> | |||
| <base-rmic | |||
| compiler="kaffe" | |||
| /> | |||
| <assertBaseCompiled/> | |||
| </target> | |||
| <target name="testWlrmic" if="wlrmic.present" depends="init"> | |||
| @@ -52,6 +97,7 @@ | |||
| <base-rmic | |||
| compiler="forking" | |||
| /> | |||
| <assertBaseCompiled/> | |||
| </target> | |||
| <target name="testBadName" if="rmic.present" depends="init"> | |||
| @@ -86,4 +132,54 @@ | |||
| includes="**/*.class"/> | |||
| </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> | |||
| @@ -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 { | |||
| private static final String FAIL_MSG | |||
| public static final String ERROR_RMIC_FAILED | |||
| = "Rmic failed; see the compiler error output for details."; | |||
| 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 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 | |||
| */ | |||
| 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!! | |||
| 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++) { | |||
| 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 { | |||
| /** | |||
| * the name of this adapter for users to select | |||
| */ | |||
| public static final String COMPILER_NAME = "forking"; | |||
| /** | |||
| * exec by creating a new command | |||
| * @return | |||
| @@ -63,6 +68,7 @@ public class ForkingSunRmic extends DefaultRmicAdapter { | |||
| exe.setAntRun(project); | |||
| exe.setWorkingDirectory(project.getBaseDir()); | |||
| exe.setCommandline(args); | |||
| exe.execute(); | |||
| return exe.getExitValue()==0; | |||
| } catch (IOException exception) { | |||
| @@ -21,7 +21,6 @@ import java.lang.reflect.Constructor; | |||
| import java.lang.reflect.Method; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.util.facade.FacadeTaskHelper; | |||
| import org.apache.tools.ant.types.Commandline; | |||
| /** | |||
| @@ -31,6 +30,11 @@ import org.apache.tools.ant.types.Commandline; | |||
| */ | |||
| public class KaffeRmic extends DefaultRmicAdapter { | |||
| 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 { | |||
| getRmic().log("Using Kaffe rmic", Project.MSG_VERBOSE); | |||
| @@ -51,19 +55,19 @@ public class KaffeRmic extends DefaultRmicAdapter { | |||
| + "set the environment variable " | |||
| + "JAVA_HOME or CLASSPATH.", | |||
| getRmic().getLocation()); | |||
| } catch (BuildException ex) { | |||
| //rethrow | |||
| throw 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()); | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * test for kaffe being on the system | |||
| * @return | |||
| * @return true if kaffe is on the current classpath | |||
| */ | |||
| public static boolean isAvailable() { | |||
| try { | |||
| @@ -29,6 +29,7 @@ import org.apache.tools.ant.Task; | |||
| public class RmicAdapterFactory { | |||
| 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 DEFAULT_COMPILER = "default"; | |||
| /** This is a singleton -- can't create instances!! */ | |||
| private RmicAdapterFactory() { | |||
| @@ -55,13 +56,22 @@ public class RmicAdapterFactory { | |||
| */ | |||
| public static RmicAdapter getRmic(String rmicType, Task task) | |||
| 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(); | |||
| } else if (rmicType.equalsIgnoreCase("kaffe")) { | |||
| } else if (KaffeRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) { | |||
| return new KaffeRmic(); | |||
| } else if (rmicType.equalsIgnoreCase("weblogic")) { | |||
| } else if (WLRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) { | |||
| return new WLRmic(); | |||
| } else if (rmicType.equalsIgnoreCase("forking")) { | |||
| } else if (ForkingSunRmic.COMPILER_NAME.equalsIgnoreCase(rmicType)) { | |||
| return new ForkingSunRmic(); | |||
| } | |||
| return resolveClassName(rmicType); | |||
| @@ -38,6 +38,11 @@ public class SunRmic extends DefaultRmicAdapter { | |||
| */ | |||
| 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 | |||
| */ | |||
| @@ -30,6 +30,11 @@ import org.apache.tools.ant.types.Commandline; | |||
| */ | |||
| public class WLRmic extends DefaultRmicAdapter { | |||
| 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 " | |||
| + "available. A common solution is to " | |||
| + "set the environment variable " | |||
| @@ -19,7 +19,9 @@ | |||
| package org.apache.tools.ant.taskdefs; | |||
| 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.DefaultRmicAdapter; | |||
| /** | |||
| * Date: 04-Aug-2004 | |||
| @@ -47,6 +49,19 @@ public class RmicAdvancedTest extends BuildFileTest { | |||
| 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 | |||
| */ | |||
| @@ -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"); | |||
| } | |||
| /** | |||
| * 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 | |||
| */ | |||
| @@ -91,5 +120,70 @@ public class RmicAdvancedTest extends BuildFileTest { | |||
| "class not an 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; | |||
| } | |||
| } | |||
| } | |||