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. | |||
* <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: | |||
-------------- | |||
* 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: | |||
----------- | |||
@@ -27,6 +27,12 @@ supports all attributes of <code><fileset></code> | |||
(<code>dir</code> becomes <code>base</code>) as well as the nested | |||
<code><include></code>, <code><exclude></code> and | |||
<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> | |||
<table border="1" cellpadding="2" cellspacing="0"> | |||
<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 align="center" valign="top">No</td> | |||
</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> | |||
<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 | |||
<i>classpath</i> elements.</p> | |||
<i>classpath</i> and <i>extdirs</i> elements.</p> | |||
<h3>Examples</h3> | |||
<pre> <rmic classname="com.xyz.FooBar" base="${build}/classes"/></pre> | |||
<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.DirectoryScanner; | |||
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.Reference; | |||
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.Date; | |||
/** | |||
* 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>idl: Generate IDL output | |||
* <li>idlopts: Include IDL options | |||
* <li>includeantruntime | |||
* <li>includejavaruntime | |||
* <li>extdirs | |||
* </ul> | |||
* Of these arguments, <b>base</b> is required. | |||
* <p> | |||
@@ -92,15 +94,20 @@ import java.util.Date; | |||
* @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 class Rmic extends MatchingTask { | |||
private static final String FAIL_MSG | |||
= "Rmic failed, messages should have been provided."; | |||
private File baseDir; | |||
private String classname; | |||
private File sourceBase; | |||
private String stubVersion; | |||
private Path compileClasspath; | |||
private Path extdirs; | |||
private boolean verify = false; | |||
private boolean filtering = false; | |||
@@ -109,35 +116,70 @@ public class Rmic extends MatchingTask { | |||
private boolean idl = false; | |||
private String idlopts; | |||
private boolean debug = false; | |||
private boolean includeAntRuntime = true; | |||
private boolean includeJavaRuntime = false; | |||
private Vector compileList = new Vector(); | |||
private ClassLoader loader = null; | |||
/** Sets the base directory to output generated class. */ | |||
public void setBase(File 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) { | |||
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) { | |||
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) { | |||
this.stubVersion = stubVersion; | |||
} | |||
public String getStubVersion() { | |||
return stubVersion; | |||
} | |||
public void setFiltering(boolean filter) { | |||
filtering = filter; | |||
} | |||
public boolean getFiltering() { | |||
return filtering; | |||
} | |||
/** Sets the debug flag. */ | |||
public void setDebug(boolean debug) { | |||
this.debug = debug; | |||
} | |||
/** Gets the debug flag. */ | |||
public boolean getDebug() { | |||
return debug; | |||
} | |||
/** | |||
* Set the classpath to be used for this compilation. | |||
*/ | |||
@@ -166,6 +208,13 @@ public class Rmic extends MatchingTask { | |||
createClasspath().setRefid(r); | |||
} | |||
/** | |||
* Gets the classpath. | |||
*/ | |||
public Path getClasspath() { | |||
return compileClasspath; | |||
} | |||
/** | |||
* Indicates that the classes found by the directory match should be | |||
* checked to see if they implement java.rmi.Remote. | |||
@@ -174,6 +223,11 @@ public class Rmic extends MatchingTask { | |||
this.verify = verify; | |||
} | |||
/** Get verify flag. */ | |||
public boolean getVerify() { | |||
return verify; | |||
} | |||
/** | |||
* Indicates that IIOP compatible stubs should | |||
* be generated. This defaults to false | |||
@@ -183,6 +237,11 @@ public class Rmic extends MatchingTask { | |||
this.iiop = iiop; | |||
} | |||
/** Gets iiop flags. */ | |||
public boolean getIiop() { | |||
return iiop; | |||
} | |||
/** | |||
* pass additional arguments for iiop | |||
*/ | |||
@@ -190,6 +249,11 @@ public class Rmic extends MatchingTask { | |||
this.iiopopts = iiopopts; | |||
} | |||
/** Gets additional arguments for iiop. */ | |||
public String getIiopopts() { | |||
return iiopopts; | |||
} | |||
/** | |||
* Indicates that IDL output should be | |||
* generated. This defaults to false | |||
@@ -199,6 +263,11 @@ public class Rmic extends MatchingTask { | |||
this.idl = idl; | |||
} | |||
/* Gets IDL flags. */ | |||
public boolean getIdl() { | |||
return idl; | |||
} | |||
/** | |||
* pass additional arguments for idl compile | |||
*/ | |||
@@ -206,6 +275,83 @@ public class Rmic extends MatchingTask { | |||
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 { | |||
if (baseDir == null) { | |||
throw new BuildException("base attribute must be set!", location); | |||
@@ -217,20 +363,11 @@ public class Rmic extends MatchingTask { | |||
if (verify) { | |||
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); | |||
// scan base dirs to build up compile lists only if a | |||
@@ -238,61 +375,27 @@ public class Rmic extends MatchingTask { | |||
if (classname == null) { | |||
DirectoryScanner ds = this.getDirectoryScanner(baseDir); | |||
String[] files = ds.getIncludedFiles(); | |||
scanDir(baseDir, files); | |||
scanDir(baseDir, files, adapter.getMapper()); | |||
} else { | |||
// otherwise perform a timestamp comparison - at least | |||
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(); | |||
if (fileCount > 0) { | |||
log("RMI Compiling " + fileCount + | |||
" class"+ (fileCount > 1 ? "es" : "")+" to " + baseDir, | |||
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 | |||
@@ -310,7 +413,7 @@ public class Rmic extends MatchingTask { | |||
* @exception org.apache.tools.ant.BuildException When error copying/removing files. | |||
*/ | |||
private void moveGeneratedFile (File baseDir, File sourceBaseFile, String classname) | |||
throws BuildException { | |||
throws BuildException { | |||
String stubFileName = classname.replace('.', File.separatorChar) + "_Stub.java"; | |||
File oldStubFile = new File(baseDir, stubFileName); | |||
File newStubFile = new File(sourceBaseFile, stubFileName); | |||
@@ -331,7 +434,7 @@ public class Rmic extends MatchingTask { | |||
oldSkelFile.delete(); | |||
} catch (IOException ioe) { | |||
String msg = "Failed to copy " + oldSkelFile + " to " + | |||
newSkelFile + " due to " + ioe.getMessage(); | |||
newSkelFile + " due to " + ioe.getMessage(); | |||
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. | |||
* 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); | |||
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++) { | |||
String classname = newFiles[i].replace(File.separatorChar, '.'); | |||
classname = classname.substring(0, classname.indexOf(".class")); | |||
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()); | |||
} | |||
} | |||
} | |||
} |