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