Kaffe's rmic. Submitted by: Takashi Okamoto <toraneko@kun.ne.jp> Catch arbitrary Exceptions thrown when trying to verify a class. PR: 222 Support extdirs. PR: 893 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268852 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -6,11 +6,19 @@ Changes that could break older environments: | |||||
| * Zip.setWhenempty() has changed its signature. | * Zip.setWhenempty() has changed its signature. | ||||
| * <rmic> is now implemented using a factory. This makes extending | |||||
| rmic to use a new compiler a lot easier but may break custom | |||||
| versions of this task that rely on the old implementation. | |||||
| Other changes: | Other changes: | ||||
| -------------- | -------------- | ||||
| * Ant now uses JAXP 1.1 | * Ant now uses JAXP 1.1 | ||||
| * rmic now supports Kaffe's version of rmic. | |||||
| * new magic property build.rmic to chose the rmic implementation | |||||
| Fixed bugs: | Fixed bugs: | ||||
| ----------- | ----------- | ||||
| @@ -27,6 +27,12 @@ supports all attributes of <code><fileset></code> | |||||
| (<code>dir</code> becomes <code>base</code>) as well as the nested | (<code>dir</code> becomes <code>base</code>) as well as the nested | ||||
| <code><include></code>, <code><exclude></code> and | <code><include></code>, <code><exclude></code> and | ||||
| <code><patternset></code> elements.</p> | <code><patternset></code> elements.</p> | ||||
| <p>It is possible to use different compilers. This can be selected with the | |||||
| "build.rmic" property. There are two choices:</p> | |||||
| <ul> | |||||
| <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> | |||||
| </ul> | |||||
| <h3>Parameters</h3> | <h3>Parameters</h3> | ||||
| <table border="1" cellpadding="2" cellspacing="0"> | <table border="1" cellpadding="2" cellspacing="0"> | ||||
| <tr> | <tr> | ||||
| @@ -133,12 +139,29 @@ supports all attributes of <code><fileset></code> | |||||
| <td valign="top">generate debug info (passes -g to rmic). Defaults to false.</td> | <td valign="top">generate debug info (passes -g to rmic). Defaults to false.</td> | ||||
| <td align="center" valign="top">No</td> | <td align="center" valign="top">No</td> | ||||
| </tr> | </tr> | ||||
| <tr> | |||||
| <td valign="top">includeAntRuntime</td> | |||||
| <td valign="top">whether to include the Ant run-time libraries; | |||||
| defaults to <code>yes</code>.</td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">includeJavaRuntime</td> | |||||
| <td valign="top">whether to include the default run-time | |||||
| libraries from the executing VM; defaults to <code>no</code>.</td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| <tr> | |||||
| <td valign="top">extdirs</td> | |||||
| <td valign="top">location of installed extensions.</td> | |||||
| <td align="center" valign="top">No</td> | |||||
| </tr> | |||||
| </table> | </table> | ||||
| <h3>Parameters specified as nested elements</h3> | <h3>Parameters specified as nested elements</h3> | ||||
| <h4>classpath</h4> | |||||
| <p><code>Rmic</code>'s <i>classpath</i> attribute is a <a | |||||
| <h4>classpath and extdirs</h4> | |||||
| <p><code>Rmic</code>'s <i>classpath</i> and <i>extdirs</i> attributes are <a | |||||
| href="../using.html#path">PATH like structure</a> and can also be set via a nested | href="../using.html#path">PATH like structure</a> and can also be set via a nested | ||||
| <i>classpath</i> elements.</p> | |||||
| <i>classpath</i> and <i>extdirs</i> elements.</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 | ||||
| @@ -58,15 +58,14 @@ import org.apache.tools.ant.AntClassLoader; | |||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| import org.apache.tools.ant.DirectoryScanner; | import org.apache.tools.ant.DirectoryScanner; | ||||
| import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
| import org.apache.tools.ant.types.Commandline; | |||||
| import org.apache.tools.ant.taskdefs.rmic.*; | |||||
| import org.apache.tools.ant.types.Path; | import org.apache.tools.ant.types.Path; | ||||
| import org.apache.tools.ant.types.Reference; | import org.apache.tools.ant.types.Reference; | ||||
| import org.apache.tools.ant.util.*; | import org.apache.tools.ant.util.*; | ||||
| import java.io.*; | |||||
| import java.util.StringTokenizer; | |||||
| import java.io.File; | |||||
| import java.io.IOException; | |||||
| import java.util.Vector; | import java.util.Vector; | ||||
| import java.util.Date; | |||||
| /** | /** | ||||
| * Task to compile RMI stubs and skeletons. This task can take the following | * Task to compile RMI stubs and skeletons. This task can take the following | ||||
| @@ -81,6 +80,9 @@ import java.util.Date; | |||||
| * <li>iiopopts: Include IIOP options | * <li>iiopopts: Include IIOP options | ||||
| * <li>idl: Generate IDL output | * <li>idl: Generate IDL output | ||||
| * <li>idlopts: Include IDL options | * <li>idlopts: Include IDL options | ||||
| * <li>includeantruntime | |||||
| * <li>includejavaruntime | |||||
| * <li>extdirs | |||||
| * </ul> | * </ul> | ||||
| * Of these arguments, <b>base</b> is required. | * Of these arguments, <b>base</b> is required. | ||||
| * <p> | * <p> | ||||
| @@ -92,15 +94,20 @@ import java.util.Date; | |||||
| * @author ludovic.claude@websitewatchers.co.uk | * @author ludovic.claude@websitewatchers.co.uk | ||||
| * @author David Maclean <a href="mailto:david@cm.co.za">david@cm.co.za</a> | * @author David Maclean <a href="mailto:david@cm.co.za">david@cm.co.za</a> | ||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | ||||
| * @author Takashi Okamoto tokamoto@rd.nttdata.co.jp | |||||
| */ | */ | ||||
| public class Rmic extends MatchingTask { | public class Rmic extends MatchingTask { | ||||
| private static final String FAIL_MSG | |||||
| = "Rmic failed, messages should have been provided."; | |||||
| private File baseDir; | private File baseDir; | ||||
| private String classname; | private String classname; | ||||
| private File sourceBase; | private File sourceBase; | ||||
| private String stubVersion; | private String stubVersion; | ||||
| private Path compileClasspath; | private Path compileClasspath; | ||||
| private Path extdirs; | |||||
| private boolean verify = false; | private boolean verify = false; | ||||
| private boolean filtering = false; | private boolean filtering = false; | ||||
| @@ -109,35 +116,70 @@ public class Rmic extends MatchingTask { | |||||
| private boolean idl = false; | private boolean idl = false; | ||||
| private String idlopts; | private String idlopts; | ||||
| private boolean debug = false; | private boolean debug = false; | ||||
| private boolean includeAntRuntime = true; | |||||
| private boolean includeJavaRuntime = false; | |||||
| private Vector compileList = new Vector(); | private Vector compileList = new Vector(); | ||||
| private ClassLoader loader = null; | private ClassLoader loader = null; | ||||
| /** Sets the base directory to output generated class. */ | |||||
| public void setBase(File base) { | public void setBase(File base) { | ||||
| this.baseDir = base; | this.baseDir = base; | ||||
| } | } | ||||
| /** Gets the base directory to output generated class. */ | |||||
| public File getBase() { | |||||
| return this.baseDir; | |||||
| } | |||||
| /** Sets the class name to compile. */ | |||||
| public void setClassname(String classname) { | public void setClassname(String classname) { | ||||
| this.classname = classname; | this.classname = classname; | ||||
| } | } | ||||
| /** Gets the class name to compile. */ | |||||
| public String getClassname() { | |||||
| return classname; | |||||
| } | |||||
| /** Sets the source dirs to find the source java files. */ | |||||
| public void setSourceBase(File sourceBase) { | public void setSourceBase(File sourceBase) { | ||||
| this.sourceBase = sourceBase; | this.sourceBase = sourceBase; | ||||
| } | } | ||||
| /** Gets the source dirs to find the source java files. */ | |||||
| public File getSourceBase() { | |||||
| return sourceBase; | |||||
| } | |||||
| /** Sets the stub version. */ | |||||
| public void setStubVersion(String stubVersion) { | public void setStubVersion(String stubVersion) { | ||||
| this.stubVersion = stubVersion; | this.stubVersion = stubVersion; | ||||
| } | } | ||||
| public String getStubVersion() { | |||||
| return stubVersion; | |||||
| } | |||||
| public void setFiltering(boolean filter) { | public void setFiltering(boolean filter) { | ||||
| filtering = filter; | filtering = filter; | ||||
| } | } | ||||
| public boolean getFiltering() { | |||||
| return filtering; | |||||
| } | |||||
| /** Sets the debug flag. */ | |||||
| public void setDebug(boolean debug) { | public void setDebug(boolean debug) { | ||||
| this.debug = debug; | this.debug = debug; | ||||
| } | } | ||||
| /** Gets the debug flag. */ | |||||
| public boolean getDebug() { | |||||
| return debug; | |||||
| } | |||||
| /** | /** | ||||
| * Set the classpath to be used for this compilation. | * Set the classpath to be used for this compilation. | ||||
| */ | */ | ||||
| @@ -166,6 +208,13 @@ public class Rmic extends MatchingTask { | |||||
| createClasspath().setRefid(r); | createClasspath().setRefid(r); | ||||
| } | } | ||||
| /** | |||||
| * Gets the classpath. | |||||
| */ | |||||
| public Path getClasspath() { | |||||
| return compileClasspath; | |||||
| } | |||||
| /** | /** | ||||
| * Indicates that the classes found by the directory match should be | * Indicates that the classes found by the directory match should be | ||||
| * checked to see if they implement java.rmi.Remote. | * checked to see if they implement java.rmi.Remote. | ||||
| @@ -174,6 +223,11 @@ public class Rmic extends MatchingTask { | |||||
| this.verify = verify; | this.verify = verify; | ||||
| } | } | ||||
| /** Get verify flag. */ | |||||
| public boolean getVerify() { | |||||
| return verify; | |||||
| } | |||||
| /** | /** | ||||
| * Indicates that IIOP compatible stubs should | * Indicates that IIOP compatible stubs should | ||||
| * be generated. This defaults to false | * be generated. This defaults to false | ||||
| @@ -183,6 +237,11 @@ public class Rmic extends MatchingTask { | |||||
| this.iiop = iiop; | this.iiop = iiop; | ||||
| } | } | ||||
| /** Gets iiop flags. */ | |||||
| public boolean getIiop() { | |||||
| return iiop; | |||||
| } | |||||
| /** | /** | ||||
| * pass additional arguments for iiop | * pass additional arguments for iiop | ||||
| */ | */ | ||||
| @@ -190,6 +249,11 @@ public class Rmic extends MatchingTask { | |||||
| this.iiopopts = iiopopts; | this.iiopopts = iiopopts; | ||||
| } | } | ||||
| /** Gets additional arguments for iiop. */ | |||||
| public String getIiopopts() { | |||||
| return iiopopts; | |||||
| } | |||||
| /** | /** | ||||
| * Indicates that IDL output should be | * Indicates that IDL output should be | ||||
| * generated. This defaults to false | * generated. This defaults to false | ||||
| @@ -199,6 +263,11 @@ public class Rmic extends MatchingTask { | |||||
| this.idl = idl; | this.idl = idl; | ||||
| } | } | ||||
| /* Gets IDL flags. */ | |||||
| public boolean getIdl() { | |||||
| return idl; | |||||
| } | |||||
| /** | /** | ||||
| * pass additional arguments for idl compile | * pass additional arguments for idl compile | ||||
| */ | */ | ||||
| @@ -206,6 +275,83 @@ public class Rmic extends MatchingTask { | |||||
| this.idlopts = idlopts; | this.idlopts = idlopts; | ||||
| } | } | ||||
| /** | |||||
| * Gets additional arguments for idl compile. | |||||
| */ | |||||
| public String getIdlopts() { | |||||
| return idlopts; | |||||
| } | |||||
| /** Gets file list to compile. */ | |||||
| public Vector getFileList() { | |||||
| return compileList; | |||||
| } | |||||
| /** | |||||
| * Include ant's own classpath in this task's classpath? | |||||
| */ | |||||
| public void setIncludeantruntime( boolean include ) { | |||||
| includeAntRuntime = include; | |||||
| } | |||||
| /** | |||||
| * Gets whether or not the ant classpath is to be included in the | |||||
| * task's classpath. | |||||
| */ | |||||
| public boolean getIncludeantruntime() { | |||||
| return includeAntRuntime; | |||||
| } | |||||
| /** | |||||
| * Sets whether or not to include the java runtime libraries to this | |||||
| * task's classpath. | |||||
| */ | |||||
| public void setIncludejavaruntime( boolean include ) { | |||||
| includeJavaRuntime = include; | |||||
| } | |||||
| /** | |||||
| * Gets whether or not the java runtime should be included in this | |||||
| * task's classpath. | |||||
| */ | |||||
| public boolean getIncludejavaruntime() { | |||||
| return includeJavaRuntime; | |||||
| } | |||||
| /** | |||||
| * Sets the extension directories that will be used during the | |||||
| * compilation. | |||||
| */ | |||||
| public void setExtdirs(Path extdirs) { | |||||
| if (this.extdirs == null) { | |||||
| this.extdirs = extdirs; | |||||
| } else { | |||||
| this.extdirs.append(extdirs); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Maybe creates a nested extdirs element. | |||||
| */ | |||||
| public Path createExtdirs() { | |||||
| if (extdirs == null) { | |||||
| extdirs = new Path(project); | |||||
| } | |||||
| return extdirs.createPath(); | |||||
| } | |||||
| /** | |||||
| * Gets the extension directories that will be used during the | |||||
| * compilation. | |||||
| */ | |||||
| public Path getExtdirs() { | |||||
| return extdirs; | |||||
| } | |||||
| public Vector getCompileList() { | |||||
| return compileList; | |||||
| } | |||||
| public void execute() throws BuildException { | public void execute() throws BuildException { | ||||
| if (baseDir == null) { | if (baseDir == null) { | ||||
| throw new BuildException("base attribute must be set!", location); | throw new BuildException("base attribute must be set!", location); | ||||
| @@ -217,20 +363,11 @@ public class Rmic extends MatchingTask { | |||||
| if (verify) { | if (verify) { | ||||
| log("Verify has been turned on.", Project.MSG_INFO); | log("Verify has been turned on.", Project.MSG_INFO); | ||||
| } | } | ||||
| if (iiop) { | |||||
| log("IIOP has been turned on.", Project.MSG_INFO); | |||||
| if( iiopopts != null ) { | |||||
| log("IIOP Options: " + iiopopts, Project.MSG_INFO ); | |||||
| } | |||||
| } | |||||
| if (idl) { | |||||
| log("IDL has been turned on.", Project.MSG_INFO); | |||||
| if( idlopts != null ) { | |||||
| log("IDL Options: " + idlopts, Project.MSG_INFO ); | |||||
| } | |||||
| } | |||||
| Path classpath = getCompileClasspath(baseDir); | |||||
| String compiler = project.getProperty("build.rmic"); | |||||
| RmicAdapter adapter = RmicAdapterFactory.getRmic(compiler, this ); | |||||
| Path classpath = adapter.getClasspath(); | |||||
| loader = new AntClassLoader(project, classpath); | loader = new AntClassLoader(project, classpath); | ||||
| // scan base dirs to build up compile lists only if a | // scan base dirs to build up compile lists only if a | ||||
| @@ -238,61 +375,27 @@ public class Rmic extends MatchingTask { | |||||
| if (classname == null) { | if (classname == null) { | ||||
| DirectoryScanner ds = this.getDirectoryScanner(baseDir); | DirectoryScanner ds = this.getDirectoryScanner(baseDir); | ||||
| String[] files = ds.getIncludedFiles(); | String[] files = ds.getIncludedFiles(); | ||||
| scanDir(baseDir, files); | |||||
| scanDir(baseDir, files, adapter.getMapper()); | |||||
| } else { | } else { | ||||
| // otherwise perform a timestamp comparison - at least | // otherwise perform a timestamp comparison - at least | ||||
| scanDir(baseDir, | scanDir(baseDir, | ||||
| new String[] {classname.replace('.', File.separatorChar) + ".class"}); | |||||
| new String[] {classname.replace('.', File.separatorChar) + ".class"}, | |||||
| adapter.getMapper()); | |||||
| } | } | ||||
| // XXX | |||||
| // need to provide an input stream that we read in from! | |||||
| OutputStream logstr = new LogOutputStream(this, Project.MSG_WARN); | |||||
| sun.rmi.rmic.Main compiler = new sun.rmi.rmic.Main(logstr, "rmic"); | |||||
| Commandline cmd = new Commandline(); | |||||
| cmd.createArgument().setValue("-d"); | |||||
| cmd.createArgument().setFile(baseDir); | |||||
| cmd.createArgument().setValue("-classpath"); | |||||
| cmd.createArgument().setPath(classpath); | |||||
| if (null != stubVersion) { | |||||
| if ("1.1".equals(stubVersion)) | |||||
| cmd.createArgument().setValue("-v1.1"); | |||||
| else if ("1.2".equals(stubVersion)) | |||||
| cmd.createArgument().setValue("-v1.2"); | |||||
| else | |||||
| cmd.createArgument().setValue("-vcompat"); | |||||
| } | |||||
| if (null != sourceBase) | |||||
| cmd.createArgument().setValue("-keepgenerated"); | |||||
| if( iiop ) { | |||||
| cmd.createArgument().setValue("-iiop"); | |||||
| if( iiopopts != null ) | |||||
| cmd.createArgument().setValue(iiopopts); | |||||
| } | |||||
| if( idl ) { | |||||
| cmd.createArgument().setValue("-idl"); | |||||
| if( idlopts != null ) | |||||
| cmd.createArgument().setValue(idlopts); | |||||
| } | |||||
| if( debug ) { | |||||
| cmd.createArgument().setValue("-g"); | |||||
| } | |||||
| int fileCount = compileList.size(); | int fileCount = compileList.size(); | ||||
| if (fileCount > 0) { | if (fileCount > 0) { | ||||
| log("RMI Compiling " + fileCount + | log("RMI Compiling " + fileCount + | ||||
| " class"+ (fileCount > 1 ? "es" : "")+" to " + baseDir, | " class"+ (fileCount > 1 ? "es" : "")+" to " + baseDir, | ||||
| Project.MSG_INFO); | Project.MSG_INFO); | ||||
| for (int j = 0; j < fileCount; j++) { | |||||
| cmd.createArgument().setValue((String) compileList.elementAt(j)); | |||||
| // now we need to populate the compiler adapter | |||||
| adapter.setRmic( this ); | |||||
| // finally, lets execute the compiler!! | |||||
| if (!adapter.execute()) { | |||||
| throw new BuildException(FAIL_MSG, location); | |||||
| } | } | ||||
| log("Compilation args: " + cmd.toString(), Project.MSG_VERBOSE); | |||||
| compiler.compile(cmd.getArguments()); | |||||
| } | } | ||||
| // Move the generated source file to the base directory | // Move the generated source file to the base directory | ||||
| @@ -310,7 +413,7 @@ public class Rmic extends MatchingTask { | |||||
| * @exception org.apache.tools.ant.BuildException When error copying/removing files. | * @exception org.apache.tools.ant.BuildException When error copying/removing files. | ||||
| */ | */ | ||||
| private void moveGeneratedFile (File baseDir, File sourceBaseFile, String classname) | private void moveGeneratedFile (File baseDir, File sourceBaseFile, String classname) | ||||
| throws BuildException { | |||||
| throws BuildException { | |||||
| String stubFileName = classname.replace('.', File.separatorChar) + "_Stub.java"; | String stubFileName = classname.replace('.', File.separatorChar) + "_Stub.java"; | ||||
| File oldStubFile = new File(baseDir, stubFileName); | File oldStubFile = new File(baseDir, stubFileName); | ||||
| File newStubFile = new File(sourceBaseFile, stubFileName); | File newStubFile = new File(sourceBaseFile, stubFileName); | ||||
| @@ -331,7 +434,7 @@ public class Rmic extends MatchingTask { | |||||
| oldSkelFile.delete(); | oldSkelFile.delete(); | ||||
| } catch (IOException ioe) { | } catch (IOException ioe) { | ||||
| String msg = "Failed to copy " + oldSkelFile + " to " + | String msg = "Failed to copy " + oldSkelFile + " to " + | ||||
| newSkelFile + " due to " + ioe.getMessage(); | |||||
| newSkelFile + " due to " + ioe.getMessage(); | |||||
| throw new BuildException(msg, ioe, location); | throw new BuildException(msg, ioe, location); | ||||
| } | } | ||||
| } | } | ||||
| @@ -341,144 +444,68 @@ public class Rmic extends MatchingTask { | |||||
| * Scans the directory looking for class files to be compiled. | * Scans the directory looking for class files to be compiled. | ||||
| * The result is returned in the class variable compileList. | * The result is returned in the class variable compileList. | ||||
| */ | */ | ||||
| protected void scanDir(File baseDir, String files[]) { | |||||
| protected void scanDir(File baseDir, String files[], | |||||
| FileNameMapper mapper) { | |||||
| SourceFileScanner sfs = new SourceFileScanner(this); | SourceFileScanner sfs = new SourceFileScanner(this); | ||||
| String[] newFiles = sfs.restrict(files, baseDir, baseDir, | |||||
| new RmicFileNameMapper()); | |||||
| String[] newFiles = sfs.restrict(files, baseDir, baseDir, mapper); | |||||
| for (int i = 0; i < newFiles.length; i++) { | for (int i = 0; i < newFiles.length; i++) { | ||||
| String classname = newFiles[i].replace(File.separatorChar, '.'); | String classname = newFiles[i].replace(File.separatorChar, '.'); | ||||
| classname = classname.substring(0, classname.indexOf(".class")); | classname = classname.substring(0, classname.indexOf(".class")); | ||||
| compileList.addElement(classname); | compileList.addElement(classname); | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * Builds the compilation classpath. | |||||
| * Load named class and test whether it can be rmic'ed | |||||
| */ | */ | ||||
| // XXX | |||||
| // we need a way to not use the current classpath. | |||||
| private Path getCompileClasspath(File baseFile) { | |||||
| // add dest dir to classpath so that previously compiled and | |||||
| // untouched classes are on classpath | |||||
| Path classpath = new Path(project, baseFile.getAbsolutePath()); | |||||
| // Combine the build classpath with the system classpath, in an | |||||
| // order determined by the value of build.classpath | |||||
| if (compileClasspath == null) { | |||||
| classpath.addExisting(Path.systemClasspath); | |||||
| } else { | |||||
| classpath.addExisting(compileClasspath.concatSystemClasspath()); | |||||
| } | |||||
| // in jdk 1.2, the system classes are not on the visible classpath. | |||||
| if (Project.getJavaVersion().startsWith("1.2")) { | |||||
| String bootcp = System.getProperty("sun.boot.class.path"); | |||||
| if (bootcp != null) { | |||||
| classpath.addExisting(new Path(project, bootcp)); | |||||
| public boolean isValidRmiRemote(String classname) { | |||||
| try { | |||||
| Class testClass = loader.loadClass(classname); | |||||
| // One cannot RMIC an interface | |||||
| if (testClass.isInterface()) { | |||||
| return false; | |||||
| } | } | ||||
| return isValidRmiRemote(testClass); | |||||
| } catch (ClassNotFoundException e) { | |||||
| log("Unable to verify class " + classname + | |||||
| ". It could not be found.", Project.MSG_WARN); | |||||
| } catch (NoClassDefFoundError e) { | |||||
| log("Unable to verify class " + classname + | |||||
| ". It is not defined.", Project.MSG_WARN); | |||||
| } catch (Throwable t) { | |||||
| log("Unable to verify class " + classname + | |||||
| ". Loading caused Exception: " + | |||||
| t.getMessage(), Project.MSG_WARN); | |||||
| } | } | ||||
| return classpath; | |||||
| // we only get here if an exception has been thrown | |||||
| return false; | |||||
| } | } | ||||
| /** | /** | ||||
| * Mapper that possibly returns two file names, *_Stub and *_Skel. | |||||
| * Check to see if the class or (super)interfaces implement | |||||
| * java.rmi.Remote. | |||||
| */ | */ | ||||
| private class RmicFileNameMapper implements FileNameMapper { | |||||
| private GlobPatternMapper stubMapper; | |||||
| private GlobPatternMapper skelMapper; | |||||
| RmicFileNameMapper() { | |||||
| stubMapper = new GlobPatternMapper(); | |||||
| stubMapper.setFrom("*.class"); | |||||
| stubMapper.setTo("*_Stub.class"); | |||||
| // no _Skel file in stub version 1.2 | |||||
| if (!"1.2".equals(stubVersion)) { | |||||
| skelMapper = new GlobPatternMapper(); | |||||
| skelMapper.setFrom("*.class"); | |||||
| skelMapper.setTo("*_Skel.class"); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Empty implementation. | |||||
| */ | |||||
| public void setFrom(String s) {} | |||||
| /** | |||||
| * Empty implementation. | |||||
| */ | |||||
| public void setTo(String s) {} | |||||
| public String[] mapFileName(String name) { | |||||
| String[] stubName = stubMapper.mapFileName(name); | |||||
| if (stubName == null || name.endsWith("_Stub.class") | |||||
| || name.endsWith("_Skel.class")) { | |||||
| // Not a .class file | |||||
| return null; | |||||
| } | |||||
| String classname = name.replace(File.separatorChar, '.'); | |||||
| classname = classname.substring(0, classname.indexOf(".class")); | |||||
| if (verify) { | |||||
| try { | |||||
| Class testClass = loader.loadClass(classname); | |||||
| // One cannot RMIC an interface | |||||
| if (testClass.isInterface() || | |||||
| !isValidRmiRemote(testClass)) { | |||||
| return null; | |||||
| } | |||||
| } catch (ClassNotFoundException e) { | |||||
| log("Unable to verify class " + classname + | |||||
| ". It could not be found.", Project.MSG_WARN); | |||||
| } catch (NoClassDefFoundError e) { | |||||
| log("Unable to verify class " + classname + | |||||
| ". It is not defined.", Project.MSG_WARN); | |||||
| } | |||||
| } | |||||
| if (skelMapper != null) { | |||||
| return new String[] { | |||||
| stubName[0], | |||||
| skelMapper.mapFileName(name)[0] | |||||
| }; | |||||
| } else { | |||||
| return stubName; | |||||
| } | |||||
| private boolean isValidRmiRemote (Class testClass) { | |||||
| Class rmiRemote = java.rmi.Remote.class; | |||||
| if (rmiRemote.equals(testClass)) { | |||||
| // This class is java.rmi.Remote | |||||
| return true; | |||||
| } | } | ||||
| /** | |||||
| * Check to see if the class or superclasses/interfaces implement | |||||
| * java.rmi.Remote. | |||||
| */ | |||||
| private boolean isValidRmiRemote (Class testClass) { | |||||
| Class rmiRemote = java.rmi.Remote.class; | |||||
| if (rmiRemote.equals(testClass)) { | |||||
| // This class is java.rmi.Remote | |||||
| return true; | |||||
| } | |||||
| Class [] interfaces = testClass.getInterfaces(); | |||||
| if (interfaces != null) { | |||||
| for (int i = 0; i < interfaces.length; i++) { | |||||
| if (rmiRemote.equals(interfaces[i])) { | |||||
| // This class directly implements java.rmi.Remote | |||||
| return true; | |||||
| } | |||||
| if (isValidRmiRemote(interfaces[i])) { | |||||
| return true; | |||||
| } | |||||
| Class [] interfaces = testClass.getInterfaces(); | |||||
| if (interfaces != null) { | |||||
| for (int i = 0; i < interfaces.length; i++) { | |||||
| if (rmiRemote.equals(interfaces[i])) { | |||||
| // This class directly implements java.rmi.Remote | |||||
| return true; | |||||
| } | |||||
| if (isValidRmiRemote(interfaces[i])) { | |||||
| return true; | |||||
| } | } | ||||
| } | } | ||||
| return false; | |||||
| } | } | ||||
| return false; | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,345 @@ | |||||
| /* | |||||
| * The Apache Software License, Version 1.1 | |||||
| * | |||||
| * Copyright (c) 2001 The Apache Software Foundation. All rights | |||||
| * reserved. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in | |||||
| * the documentation and/or other materials provided with the | |||||
| * distribution. | |||||
| * | |||||
| * 3. The end-user documentation included with the redistribution, if | |||||
| * any, must include the following acknowlegement: | |||||
| * "This product includes software developed by the | |||||
| * Apache Software Foundation (http://www.apache.org/)." | |||||
| * Alternately, this acknowlegement may appear in the software itself, | |||||
| * if and wherever such third-party acknowlegements normally appear. | |||||
| * | |||||
| * 4. The names "The Jakarta Project", "Ant", and "Apache Software | |||||
| * Foundation" must not be used to endorse or promote products derived | |||||
| * from this software without prior written permission. For written | |||||
| * permission, please contact apache@apache.org. | |||||
| * | |||||
| * 5. Products derived from this software may not be called "Apache" | |||||
| * nor may "Apache" appear in their names without prior written | |||||
| * permission of the Apache Group. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * ==================================================================== | |||||
| * | |||||
| * This software consists of voluntary contributions made by many | |||||
| * individuals on behalf of the Apache Software Foundation. For more | |||||
| * information on the Apache Software Foundation, please see | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| package org.apache.tools.ant.taskdefs.rmic; | |||||
| import org.apache.tools.ant.*; | |||||
| import org.apache.tools.ant.taskdefs.*; | |||||
| import org.apache.tools.ant.types.*; | |||||
| import org.apache.tools.ant.util.*; | |||||
| import java.io.File; | |||||
| import java.util.Vector; | |||||
| /** | |||||
| * This is the default implementation for the RmicAdapter interface. | |||||
| * Currently, this is a cut-and-paste of the original rmic task and | |||||
| * DefaultCopmpilerAdapter. | |||||
| * | |||||
| * @author duncan@x180.com | |||||
| * @author ludovic.claude@websitewatchers.co.uk | |||||
| * @author David Maclean <a href="mailto:david@cm.co.za">david@cm.co.za</a> | |||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| * @author Takashi Okamoto <tokamoto@rd.nttdata.co.jp> | |||||
| */ | |||||
| public abstract class DefaultRmicAdapter implements RmicAdapter { | |||||
| private Rmic attributes; | |||||
| public void setRmic( Rmic attributes ) { | |||||
| this.attributes = attributes; | |||||
| } | |||||
| public Rmic getRmic() { | |||||
| return attributes; | |||||
| } | |||||
| /** | |||||
| * This implementation maps *.class to *_Stub.class and - if | |||||
| * stubversion is not 1.2 - to _Skel.class. | |||||
| */ | |||||
| public FileNameMapper getMapper() { | |||||
| return new RmicFileNameMapper(); | |||||
| } | |||||
| /** | |||||
| * The CLASSPATH this rmic process will use. | |||||
| */ | |||||
| public Path getClasspath() { | |||||
| return getCompileClasspath(); | |||||
| } | |||||
| /** | |||||
| * Builds the compilation classpath. | |||||
| */ | |||||
| protected Path getCompileClasspath() { | |||||
| // add dest dir to classpath so that previously compiled and | |||||
| // untouched classes are on classpath | |||||
| Path classpath = new Path(attributes.getProject()); | |||||
| classpath.setLocation(attributes.getBase()); | |||||
| // Combine the build classpath with the system classpath, in an | |||||
| // order determined by the value of build.classpath | |||||
| if (attributes.getClasspath() == null) { | |||||
| if ( attributes.getIncludeantruntime() ) { | |||||
| classpath.addExisting(Path.systemClasspath); | |||||
| } | |||||
| } else { | |||||
| if ( attributes.getIncludeantruntime() ) { | |||||
| classpath.addExisting(attributes.getClasspath().concatSystemClasspath("last")); | |||||
| } else { | |||||
| classpath.addExisting(attributes.getClasspath().concatSystemClasspath("ignore")); | |||||
| } | |||||
| } | |||||
| if (attributes.getIncludejavaruntime()) { | |||||
| if (System.getProperty("java.vendor").toLowerCase().indexOf("microsoft") >= 0) { | |||||
| // Pull in *.zip from packages directory | |||||
| FileSet msZipFiles = new FileSet(); | |||||
| msZipFiles.setDir(new File(System.getProperty("java.home") + File.separator + "Packages")); | |||||
| msZipFiles.setIncludes("*.ZIP"); | |||||
| classpath.addFileset(msZipFiles); | |||||
| } else if (Project.getJavaVersion() == Project.JAVA_1_1) { | |||||
| classpath.addExisting(new Path(null, | |||||
| System.getProperty("java.home") | |||||
| + File.separator + "lib" | |||||
| + File.separator | |||||
| + "classes.zip")); | |||||
| } else if(System.getProperty("java.vm.name").equals("Kaffe")) { | |||||
| FileSet kaffeJarFiles = new FileSet(); | |||||
| kaffeJarFiles.setDir(new File(System.getProperty("java.home") | |||||
| + File.separator + "share" | |||||
| + File.separator + "kaffe")); | |||||
| kaffeJarFiles.setIncludes("*.jar"); | |||||
| classpath.addFileset(kaffeJarFiles); | |||||
| } else { | |||||
| // JDK > 1.1 seems to set java.home to the JRE directory. | |||||
| classpath.addExisting(new Path(null, | |||||
| System.getProperty("java.home") | |||||
| + File.separator + "lib" | |||||
| + File.separator + "rt.jar")); | |||||
| // Just keep the old version as well and let addExistingToPath | |||||
| // sort it out. | |||||
| classpath.addExisting(new Path(null, | |||||
| System.getProperty("java.home") | |||||
| + File.separator +"jre" | |||||
| + File.separator + "lib" | |||||
| + File.separator + "rt.jar")); | |||||
| } | |||||
| } | |||||
| return classpath; | |||||
| } | |||||
| /** | |||||
| * setup rmic argument for rmic. | |||||
| */ | |||||
| protected Commandline setupRmicCommand() { | |||||
| Commandline cmd = new Commandline(); | |||||
| Path classpath = getCompileClasspath(); | |||||
| cmd.createArgument().setValue("-d"); | |||||
| cmd.createArgument().setFile(attributes.getBase()); | |||||
| if (attributes.getExtdirs() != null) { | |||||
| if (Project.getJavaVersion().startsWith("1.1")) { | |||||
| /* | |||||
| * XXX - This doesn't mix very well with build.systemclasspath, | |||||
| */ | |||||
| addExtdirsToClasspath(classpath); | |||||
| } else { | |||||
| cmd.createArgument().setValue("-extdirs"); | |||||
| cmd.createArgument().setPath(attributes.getExtdirs()); | |||||
| } | |||||
| } | |||||
| cmd.createArgument().setValue("-classpath"); | |||||
| cmd.createArgument().setPath(classpath); | |||||
| String stubVersion = attributes.getStubVersion(); | |||||
| if (null != stubVersion) { | |||||
| if ("1.1".equals(stubVersion)) | |||||
| cmd.createArgument().setValue("-v1.1"); | |||||
| else if ("1.2".equals(stubVersion)) | |||||
| cmd.createArgument().setValue("-v1.2"); | |||||
| else | |||||
| cmd.createArgument().setValue("-vcompat"); | |||||
| } | |||||
| if (null != attributes.getSourceBase()) { | |||||
| cmd.createArgument().setValue("-keepgenerated"); | |||||
| } | |||||
| if( attributes.getIiop() ) { | |||||
| attributes.log("IIOP has been turned on.", Project.MSG_INFO); | |||||
| cmd.createArgument().setValue("-iiop"); | |||||
| if( attributes.getIiopopts() != null ) { | |||||
| attributes.log("IIOP Options: " + attributes.getIiopopts(), | |||||
| Project.MSG_INFO ); | |||||
| cmd.createArgument().setValue(attributes.getIiopopts()); | |||||
| } | |||||
| } | |||||
| if( attributes.getIdl() ) { | |||||
| cmd.createArgument().setValue("-idl"); | |||||
| attributes.log("IDL has been turned on.", Project.MSG_INFO); | |||||
| if( attributes.getIdlopts() != null ) { | |||||
| cmd.createArgument().setValue(attributes.getIdlopts()); | |||||
| attributes.log("IDL Options: " + attributes.getIdlopts(), | |||||
| Project.MSG_INFO ); | |||||
| } | |||||
| } | |||||
| if( attributes.getDebug()) { | |||||
| cmd.createArgument().setValue("-g"); | |||||
| } | |||||
| logAndAddFilesToCompile(cmd); | |||||
| return cmd; | |||||
| } | |||||
| /** | |||||
| * Logs the compilation parameters, adds the files to compile and logs the | |||||
| * &qout;niceSourceList" | |||||
| */ | |||||
| protected void logAndAddFilesToCompile(Commandline cmd) { | |||||
| Vector compileList = attributes.getCompileList(); | |||||
| attributes.log("Compilation args: " + cmd.toString(), | |||||
| Project.MSG_VERBOSE); | |||||
| StringBuffer niceSourceList = new StringBuffer("File"); | |||||
| if (compileList.size() != 1) { | |||||
| niceSourceList.append("s"); | |||||
| } | |||||
| niceSourceList.append(" to be compiled:"); | |||||
| for (int i=0; i < compileList.size(); i++) { | |||||
| String arg = (String)compileList.get(i); | |||||
| cmd.createArgument().setValue(arg); | |||||
| niceSourceList.append(" " + arg); | |||||
| } | |||||
| attributes.log(niceSourceList.toString(), Project.MSG_VERBOSE); | |||||
| } | |||||
| /** | |||||
| * Emulation of extdirs feature in java >= 1.2. | |||||
| * This method adds all files in the given | |||||
| * directories (but not in sub-directories!) to the classpath, | |||||
| * so that you don't have to specify them all one by one. | |||||
| * @param classpath - Path to append files to | |||||
| */ | |||||
| protected void addExtdirsToClasspath(Path classpath) { | |||||
| Path extdirs = attributes.getExtdirs(); | |||||
| if (extdirs == null) { | |||||
| String extProp = System.getProperty("java.ext.dirs"); | |||||
| if (extProp != null) { | |||||
| extdirs = new Path(attributes.getProject(), extProp); | |||||
| } else { | |||||
| return; | |||||
| } | |||||
| } | |||||
| String[] dirs = extdirs.list(); | |||||
| for (int i=0; i<dirs.length; i++) { | |||||
| if (!dirs[i].endsWith(File.separator)) { | |||||
| dirs[i] += File.separator; | |||||
| } | |||||
| File dir = attributes.getProject().resolveFile(dirs[i]); | |||||
| FileSet fs = new FileSet(); | |||||
| fs.setDir(dir); | |||||
| fs.setIncludes("*"); | |||||
| classpath.addFileset(fs); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Mapper that possibly returns two file names, *_Stub and *_Skel. | |||||
| */ | |||||
| private class RmicFileNameMapper implements FileNameMapper { | |||||
| private GlobPatternMapper stubMapper; | |||||
| private GlobPatternMapper skelMapper; | |||||
| RmicFileNameMapper() { | |||||
| stubMapper = new GlobPatternMapper(); | |||||
| stubMapper.setFrom("*.class"); | |||||
| stubMapper.setTo("*_Stub.class"); | |||||
| // no _Skel file in stub version 1.2 | |||||
| if (!"1.2".equals(attributes.getStubVersion())) { | |||||
| skelMapper = new GlobPatternMapper(); | |||||
| skelMapper.setFrom("*.class"); | |||||
| skelMapper.setTo("*_Skel.class"); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Empty implementation. | |||||
| */ | |||||
| public void setFrom(String s) {} | |||||
| /** | |||||
| * Empty implementation. | |||||
| */ | |||||
| public void setTo(String s) {} | |||||
| public String[] mapFileName(String name) { | |||||
| String[] stubName = stubMapper.mapFileName(name); | |||||
| if (stubName == null || name.endsWith("_Stub.class") | |||||
| || name.endsWith("_Skel.class")) { | |||||
| // Not a .class file | |||||
| return null; | |||||
| } | |||||
| String classname = name.replace(File.separatorChar, '.'); | |||||
| classname = classname.substring(0, classname.indexOf(".class")); | |||||
| if (attributes.getVerify() && | |||||
| !attributes.isValidRmiRemote(classname)) { | |||||
| return null; | |||||
| } | |||||
| if (skelMapper != null) { | |||||
| return new String[] { | |||||
| stubName[0], | |||||
| skelMapper.mapFileName(name)[0] | |||||
| }; | |||||
| } else { | |||||
| return stubName; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,111 @@ | |||||
| /* | |||||
| * The Apache Software License, Version 1.1 | |||||
| * | |||||
| * Copyright (c) 2001 The Apache Software Foundation. All rights | |||||
| * reserved. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in | |||||
| * the documentation and/or other materials provided with the | |||||
| * distribution. | |||||
| * | |||||
| * 3. The end-user documentation included with the redistribution, if | |||||
| * any, must include the following acknowlegement: | |||||
| * "This product includes software developed by the | |||||
| * Apache Software Foundation (http://www.apache.org/)." | |||||
| * Alternately, this acknowlegement may appear in the software itself, | |||||
| * if and wherever such third-party acknowlegements normally appear. | |||||
| * | |||||
| * 4. The names "The Jakarta Project", "Ant", and "Apache Software | |||||
| * Foundation" must not be used to endorse or promote products derived | |||||
| * from this software without prior written permission. For written | |||||
| * permission, please contact apache@apache.org. | |||||
| * | |||||
| * 5. Products derived from this software may not be called "Apache" | |||||
| * nor may "Apache" appear in their names without prior written | |||||
| * permission of the Apache Group. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * ==================================================================== | |||||
| * | |||||
| * This software consists of voluntary contributions made by many | |||||
| * individuals on behalf of the Apache Software Foundation. For more | |||||
| * information on the Apache Software Foundation, please see | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| package org.apache.tools.ant.taskdefs.rmic; | |||||
| import org.apache.tools.ant.BuildException; | |||||
| import org.apache.tools.ant.Project; | |||||
| import org.apache.tools.ant.taskdefs.LogOutputStream; | |||||
| import org.apache.tools.ant.types.Commandline; | |||||
| import java.io.*; | |||||
| import java.lang.reflect.Constructor; | |||||
| import java.lang.reflect.Method; | |||||
| /** | |||||
| * The implementation of the rmic for Kaffe | |||||
| * | |||||
| * @author Takashi Okamoto <tokamoto@rd.nttdata.co.jp> | |||||
| */ | |||||
| public class KaffeRmic extends DefaultRmicAdapter { | |||||
| public boolean execute() throws BuildException { | |||||
| getRmic().log("Using Kaffe rmic", Project.MSG_VERBOSE); | |||||
| Commandline cmd = setupRmicCommand(); | |||||
| PrintStream err = System.err; | |||||
| PrintStream out = System.out; | |||||
| try { | |||||
| // the project log | |||||
| PrintStream logstr = | |||||
| new PrintStream(new LogOutputStream(getRmic(), Project.MSG_WARN)); | |||||
| System.setOut(logstr); | |||||
| System.setErr(logstr); | |||||
| Class c = Class.forName("kaffe.rmi.rmic.RMIC"); | |||||
| Constructor cons = c.getConstructor(new Class[] { String[].class }); | |||||
| Object rmic = cons.newInstance(new Object[] { cmd.getArguments() }); | |||||
| Method doRmic = c.getMethod("run", null); | |||||
| String str[] = cmd.getArguments(); | |||||
| Boolean ok = (Boolean)doRmic.invoke(rmic, null); | |||||
| return ok.booleanValue(); | |||||
| } catch (ClassNotFoundException ex) { | |||||
| throw new BuildException("Cannot use Kaffe rmic, as it is not available"+ | |||||
| " A common solution is to set the environment variable"+ | |||||
| " JAVA_HOME or CLASSPATH.", getRmic().getLocation() ); | |||||
| } | |||||
| catch (Exception ex) { | |||||
| if (ex instanceof BuildException) { | |||||
| throw (BuildException) ex; | |||||
| } else { | |||||
| throw new BuildException("Error starting Kaffe rmic: ", ex, getRmic().getLocation()); | |||||
| } | |||||
| } finally { | |||||
| System.setErr(err); | |||||
| System.setOut(out); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,100 @@ | |||||
| /* | |||||
| * The Apache Software License, Version 1.1 | |||||
| * | |||||
| * Copyright (c) 2001 The Apache Software Foundation. All rights | |||||
| * reserved. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in | |||||
| * the documentation and/or other materials provided with the | |||||
| * distribution. | |||||
| * | |||||
| * 3. The end-user documentation included with the redistribution, if | |||||
| * any, must include the following acknowlegement: | |||||
| * "This product includes software developed by the | |||||
| * Apache Software Foundation (http://www.apache.org/)." | |||||
| * Alternately, this acknowlegement may appear in the software itself, | |||||
| * if and wherever such third-party acknowlegements normally appear. | |||||
| * | |||||
| * 4. The names "The Jakarta Project", "Ant", and "Apache Software | |||||
| * Foundation" must not be used to endorse or promote products derived | |||||
| * from this software without prior written permission. For written | |||||
| * permission, please contact apache@apache.org. | |||||
| * | |||||
| * 5. Products derived from this software may not be called "Apache" | |||||
| * nor may "Apache" appear in their names without prior written | |||||
| * permission of the Apache Group. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * ==================================================================== | |||||
| * | |||||
| * This software consists of voluntary contributions made by many | |||||
| * individuals on behalf of the Apache Software Foundation. For more | |||||
| * information on the Apache Software Foundation, please see | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| package org.apache.tools.ant.taskdefs.rmic; | |||||
| import org.apache.tools.ant.BuildException; | |||||
| import org.apache.tools.ant.taskdefs.Rmic; | |||||
| import org.apache.tools.ant.types.Path; | |||||
| import org.apache.tools.ant.util.FileNameMapper; | |||||
| /** | |||||
| * The interface that all rmic adapters must adher to. | |||||
| * | |||||
| * <p>A rmic adapter is an adapter that interprets the rmic's | |||||
| * parameters in preperation to be passed off to the compiler this | |||||
| * adapter represents. As all the necessary values are stored in the | |||||
| * Rmic task itself, the only thing all adapters need is the rmic | |||||
| * task, the execute command and a parameterless constructor (for | |||||
| * reflection).</p> | |||||
| * | |||||
| * @author Takashi Okamoto <tokamoto@rd.nttdata.co.jp> | |||||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||||
| */ | |||||
| public interface RmicAdapter { | |||||
| /** | |||||
| * Sets the rmic attributes, which are stored in the Rmic task. | |||||
| */ | |||||
| public void setRmic( Rmic attributes ); | |||||
| /** | |||||
| * Executes the task. | |||||
| * | |||||
| * @return has the compilation been successful | |||||
| */ | |||||
| public boolean execute() throws BuildException; | |||||
| /** | |||||
| * Maps source class files to the files generated by this rmic | |||||
| * implementation. | |||||
| */ | |||||
| public FileNameMapper getMapper(); | |||||
| /** | |||||
| * The CLASSPATH this rmic process will use. | |||||
| */ | |||||
| public Path getClasspath(); | |||||
| } | |||||
| @@ -0,0 +1,144 @@ | |||||
| /* | |||||
| * The Apache Software License, Version 1.1 | |||||
| * | |||||
| * Copyright (c) 2001 The Apache Software Foundation. All rights | |||||
| * reserved. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in | |||||
| * the documentation and/or other materials provided with the | |||||
| * distribution. | |||||
| * | |||||
| * 3. The end-user documentation included with the redistribution, if | |||||
| * any, must include the following acknowlegement: | |||||
| * "This product includes software developed by the | |||||
| * Apache Software Foundation (http://www.apache.org/)." | |||||
| * Alternately, this acknowlegement may appear in the software itself, | |||||
| * if and wherever such third-party acknowlegements normally appear. | |||||
| * | |||||
| * 4. The names "The Jakarta Project", "Ant", and "Apache Software | |||||
| * Foundation" must not be used to endorse or promote products derived | |||||
| * from this software without prior written permission. For written | |||||
| * permission, please contact apache@apache.org. | |||||
| * | |||||
| * 5. Products derived from this software may not be called "Apache" | |||||
| * nor may "Apache" appear in their names without prior written | |||||
| * permission of the Apache Group. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * ==================================================================== | |||||
| * | |||||
| * This software consists of voluntary contributions made by many | |||||
| * individuals on behalf of the Apache Software Foundation. For more | |||||
| * information on the Apache Software Foundation, please see | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| package org.apache.tools.ant.taskdefs.rmic; | |||||
| import org.apache.tools.ant.BuildException; | |||||
| import org.apache.tools.ant.Task; | |||||
| import org.apache.tools.ant.Project; | |||||
| /** | |||||
| * Creates the necessary rmic adapter, given basic criteria. | |||||
| * | |||||
| * @author Takashi Okamoto <tokamoto@rd.nttdata.co.jp> | |||||
| * @author <a href="mailto:jayglanville@home.com">J D Glanville</a> | |||||
| */ | |||||
| public class RmicAdapterFactory { | |||||
| /** This is a singlton -- can't create instances!! */ | |||||
| private RmicAdapterFactory() { | |||||
| } | |||||
| /** | |||||
| * Based on the parameter passed in, this method creates the necessary | |||||
| * factory desired. | |||||
| * | |||||
| * The current mapping for rmic names are as follows: | |||||
| * <ul><li>sun = SUN's rmic | |||||
| * <li>kaffe = Kaffe's rmic | |||||
| * <li><i>a fully quallified classname</i> = the name of a rmic | |||||
| * adapter | |||||
| * </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. | |||||
| * @throws BuildException if the rmic type could not be resolved into | |||||
| * a rmic adapter. | |||||
| */ | |||||
| public static RmicAdapter getRmic( String rmicType, Task task ) | |||||
| throws BuildException { | |||||
| if( rmicType == null){ | |||||
| /* | |||||
| * When not specified rmicType, search SUN's rmic and | |||||
| * Kaffe's rmic. | |||||
| */ | |||||
| try { | |||||
| Class.forName("sun.rmi.rmic.Main"); | |||||
| rmicType = "sun"; | |||||
| } catch (ClassNotFoundException cnfe) { | |||||
| try { | |||||
| Class.forName("kaffe.rmi.rmic.RMIC"); | |||||
| Class.forName("kaffe.tools.compiler.Compiler"); | |||||
| rmicType = "kaffe"; | |||||
| } catch (ClassNotFoundException cnfk) { | |||||
| throw new BuildException("Couldn\'t guess rmic implementation"); | |||||
| } | |||||
| } | |||||
| } | |||||
| if ( rmicType.equalsIgnoreCase("sun") ) { | |||||
| return new SunRmic(); | |||||
| } if ( rmicType.equalsIgnoreCase("kaffe") ) { | |||||
| return new KaffeRmic(); | |||||
| } | |||||
| return resolveClassName( rmicType ); | |||||
| } | |||||
| /** | |||||
| * Tries to resolve the given classname into a rmic adapter. | |||||
| * Throws a fit if it can't. | |||||
| * | |||||
| * @param className The fully qualified classname to be created. | |||||
| * @throws BuildException This is the fit that is thrown if className | |||||
| * isn't an instance of RmicAdapter. | |||||
| */ | |||||
| private static RmicAdapter resolveClassName( String className ) | |||||
| throws BuildException { | |||||
| try { | |||||
| Class c = Class.forName( className ); | |||||
| Object o = c.newInstance(); | |||||
| return (RmicAdapter) o; | |||||
| } catch ( ClassNotFoundException cnfe ) { | |||||
| throw new BuildException( className + " can\'t be found.", cnfe ); | |||||
| } catch ( ClassCastException cce ) { | |||||
| throw new BuildException(className + " isn\'t the classname of " | |||||
| + "a rmic adapter.", cce); | |||||
| } catch ( Throwable t ) { | |||||
| // for all other possibilities | |||||
| throw new BuildException(className + " caused an interesting " | |||||
| + "exception.", t); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,105 @@ | |||||
| /* | |||||
| * The Apache Software License, Version 1.1 | |||||
| * | |||||
| * Copyright (c) 2001 The Apache Software Foundation. All rights | |||||
| * reserved. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in | |||||
| * the documentation and/or other materials provided with the | |||||
| * distribution. | |||||
| * | |||||
| * 3. The end-user documentation included with the redistribution, if | |||||
| * any, must include the following acknowlegement: | |||||
| * "This product includes software developed by the | |||||
| * Apache Software Foundation (http://www.apache.org/)." | |||||
| * Alternately, this acknowlegement may appear in the software itself, | |||||
| * if and wherever such third-party acknowlegements normally appear. | |||||
| * | |||||
| * 4. The names "The Jakarta Project", "Ant", and "Apache Software | |||||
| * Foundation" must not be used to endorse or promote products derived | |||||
| * from this software without prior written permission. For written | |||||
| * permission, please contact apache@apache.org. | |||||
| * | |||||
| * 5. Products derived from this software may not be called "Apache" | |||||
| * nor may "Apache" appear in their names without prior written | |||||
| * permission of the Apache Group. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * ==================================================================== | |||||
| * | |||||
| * This software consists of voluntary contributions made by many | |||||
| * individuals on behalf of the Apache Software Foundation. For more | |||||
| * information on the Apache Software Foundation, please see | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| package org.apache.tools.ant.taskdefs.rmic; | |||||
| import org.apache.tools.ant.BuildException; | |||||
| import org.apache.tools.ant.Project; | |||||
| import org.apache.tools.ant.taskdefs.LogOutputStream; | |||||
| import org.apache.tools.ant.types.Commandline; | |||||
| import java.io.*; | |||||
| import java.lang.reflect.Constructor; | |||||
| import java.lang.reflect.Method; | |||||
| /** | |||||
| * The implementation of the rmic for SUN's JDK. | |||||
| * | |||||
| * @author Takashi Okamoto <tokamoto@rd.nttdata.co.jp> | |||||
| */ | |||||
| public class SunRmic extends DefaultRmicAdapter { | |||||
| public boolean execute() throws BuildException { | |||||
| getRmic().log("Using SUN rmic compiler", Project.MSG_VERBOSE); | |||||
| Commandline cmd = setupRmicCommand(); | |||||
| try { | |||||
| // Create an instance of the rmic, redirecting output to | |||||
| // the project log | |||||
| OutputStream logstr = new LogOutputStream(getRmic(), Project.MSG_WARN); | |||||
| Class c = Class.forName("sun.rmi.rmic.Main"); | |||||
| Constructor cons = c.getConstructor(new Class[] | |||||
| { OutputStream.class, String.class }); | |||||
| Object rmic = cons.newInstance(new Object[] { logstr, "rmic" }); | |||||
| Method doRmic = c.getMethod("compile", | |||||
| new Class [] { String[].class }); | |||||
| Boolean ok = (Boolean)doRmic.invoke(rmic, | |||||
| (new Object[] {cmd.getArguments()} )); | |||||
| return ok.booleanValue(); | |||||
| } catch (ClassNotFoundException ex) { | |||||
| throw new BuildException("Cannot use SUN rmic, as it is not available"+ | |||||
| " A common solution is to set the environment variable"+ | |||||
| " JAVA_HOME or CLASSPATH.", getRmic().getLocation() ); | |||||
| } | |||||
| catch (Exception ex) { | |||||
| if (ex instanceof BuildException) { | |||||
| throw (BuildException) ex; | |||||
| } else { | |||||
| throw new BuildException("Error starting SUN rmic: ", ex, getRmic().getLocation()); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||