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; | |||||
} | |||||
} | |||||
} | } | ||||