Browse Source

Make <rmic> a factory task just like <javac> already is. Support

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-ffa450edef68
master
Stefan Bodewig 24 years ago
parent
commit
5cc29f61e6
8 changed files with 1046 additions and 183 deletions
  1. +8
    -0
      WHATSNEW
  2. +26
    -3
      docs/manual/CoreTasks/rmic.html
  3. +207
    -180
      src/main/org/apache/tools/ant/taskdefs/Rmic.java
  4. +345
    -0
      src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java
  5. +111
    -0
      src/main/org/apache/tools/ant/taskdefs/rmic/KaffeRmic.java
  6. +100
    -0
      src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapter.java
  7. +144
    -0
      src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapterFactory.java
  8. +105
    -0
      src/main/org/apache/tools/ant/taskdefs/rmic/SunRmic.java

+ 8
- 0
WHATSNEW View File

@@ -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:
-----------



+ 26
- 3
docs/manual/CoreTasks/rmic.html View File

@@ -27,6 +27,12 @@ supports all attributes of <code>&lt;fileset&gt;</code>
(<code>dir</code> becomes <code>base</code>) as well as the nested
<code>&lt;include&gt;</code>, <code>&lt;exclude&gt;</code> and
<code>&lt;patternset&gt;</code> elements.</p>
<p>It is possible to use different compilers. This can be selected with the
&quot;build.rmic&quot; 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>&lt;fileset&gt;</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> &lt;rmic classname=&quot;com.xyz.FooBar&quot; base=&quot;${build}/classes&quot;/&gt;</pre>
<p>runs the rmic compiler for the class <code>com.xyz.FooBar</code>. The


+ 207
- 180
src/main/org/apache/tools/ant/taskdefs/Rmic.java View File

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

}


+ 345
- 0
src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java View File

@@ -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&quot;
*/
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;
}
}
}

}

+ 111
- 0
src/main/org/apache/tools/ant/taskdefs/rmic/KaffeRmic.java View File

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

+ 100
- 0
src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapter.java View File

@@ -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();
}

+ 144
- 0
src/main/org/apache/tools/ant/taskdefs/rmic/RmicAdapterFactory.java View File

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

+ 105
- 0
src/main/org/apache/tools/ant/taskdefs/rmic/SunRmic.java View File

@@ -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());
}
}
}
}

Loading…
Cancel
Save