You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by David Maclean <da...@cm.co.za> on 2000/06/23 14:19:08 UTC
[PATCH] Using classlist and conditional compile for Rmic taskdef
Hi there
First of all I would like say that I started using Ant a few weeks ago on
a project here at work. I found that Ant was simple yet easy to use and
setup to get a compile. The use of and was for nightly builds on the CVS
tree. Ant is great and keep it up, however I discovered a limitation?? in
ant for RMI compiling classes. The project that I used it on is RMI-based
and has 60+ classes that need to be rmic'ed. Ant only allows for a single
classname hence I would have had to place 60+ rmic lines in the build.xml
file. The other thing was that the Rmic task would always compile.
The changes that I have made (see patch at the end) addresses both
issues. One may specify a filename that contains a list of classes (one
class per line) to the Rmic task and it will generate the _Stud and/or
_Skel file if it needs to. The classname argument is ignored if the
classlistFilename argument is specified.
I have tested this under WindowNT 4.0 and JDK 1.2.2 as well as HP-UX 11.0
and JDK 1.2.2
I hope this path is useful and if so you may include it into Ant.
Cheers
_________________________________________
David Maclean
david@cm.co.za
CCH Software Development
67 Old Fort Road
Durban, 4001
South Africa
Phone: +27 31 306 9777
Fax: +27 31 306 9770
Patch follows:
=========================================================================================
*** jakarta-ant-freshcvs/src/main/org/apache/tools/ant/taskdefs/Rmic.java Wed Feb 16 16:31:45 2000
--- jakarta-ant/src/main/org/apache/tools/ant/taskdefs/Rmic.java Fri Jun 23 12:49:56 2000
***************
*** 57,62 ****
--- 57,64 ----
import org.apache.tools.ant.*;
import java.io.*;
import java.util.StringTokenizer;
+ import java.util.Vector;
+ import java.util.Date;
/**
* Task to compile RMI stubs and skeletons. This task can take the following
***************
*** 67,72 ****
--- 69,75 ----
* <li>stubVersion: The version of the stub prototol to use (1.1, 1.2, compat)
* <li>sourceBase: The base directory for the generated stubs and skeletons
* <li>classpath: Additional classpath, appended before the system classpath
+ * <li>classlistFilename: A filename that contains a list of classes one on each line
* </ul>
* Of these arguments, the <b>base</b> and <b>class</b> are required.
* <p>
***************
*** 82,89 ****
--- 85,95 ----
private String sourceBase;
private String stubVersion;
private String compileClasspath;
+ private String classlistFilename;
private boolean filtering = false;
+ protected Vector compileList = new Vector();
+
public void setBase(String base) {
this.base = base;
}
***************
*** 99,104 ****
--- 105,114 ----
this.classname = classname;
}
+ public void setClasslistFilename(String filename) {
+ this.classlistFilename = filename;
+ }
+
public void setSourceBase(String sourceBase) {
this.sourceBase = sourceBase;
}
***************
*** 124,129 ****
--- 134,142 ----
if (null != sourceBase)
sourceBaseFile = project.resolveFile(sourceBase);
String classpath = getCompileClasspath(baseFile);
+ if (classlistFilename != null) {
+ scanFiles(baseFile, project.resolveFile(classlistFilename));
+ }
// XXX
// need to provide an input stream that we read in from!
***************
*** 132,143 ****
int i = 0;
if (null != stubVersion) argCount++;
if (null != sourceBase) argCount++;
String[] args = new String[argCount];
args[i++] = "-d";
args[i++] = baseFile.getAbsolutePath();
args[i++] = "-classpath";
args[i++] = classpath;
- args[i++] = classname;
if (null != stubVersion) {
if ("1.1".equals(stubVersion))
args[i++] = "-v1.1";
--- 145,156 ----
int i = 0;
if (null != stubVersion) argCount++;
if (null != sourceBase) argCount++;
+ if (compileList.size() > 0) argCount += compileList.size() - 1;
String[] args = new String[argCount];
args[i++] = "-d";
args[i++] = baseFile.getAbsolutePath();
args[i++] = "-classpath";
args[i++] = classpath;
if (null != stubVersion) {
if ("1.1".equals(stubVersion))
args[i++] = "-v1.1";
***************
*** 148,157 ****
--- 161,202 ----
}
if (null != sourceBase) args[i++] = "-keepgenerated";
+ if (classlistFilename != null) {
+ if (compileList.size() > 0) {
+ project.log("RMI Compiling " + compileList.size() +
+ " classes to " + baseFile);
+
+ for (int j = 0; j < compileList.size(); j++) {
+ args[i++] = (String) compileList.elementAt(j);
+ }
compiler.compile(args);
+ }
+ } else {
+ if (shouldCompile(baseFile, classname)) {
+ args[i++] = classname;
+ compiler.compile(args);
+ }
+ }
// Move the generated source file to the base directory
if (null != sourceBase) {
+ if (classlistFilename != null) {
+ for (int j = 0; j < compileList.size(); j++) {
+ moveGeneratedFile(baseFile, sourceBaseFile, (String) compileList.elementAt(j));
+ }
+ } else {
+ moveGeneratedFile(baseFile, sourceBaseFile, classname);
+ }
+ }
+ }
+
+ /**
+ * Move the generated source file(s) to the base directory
+ *
+ * @exception org.apache.tools.ant.BuildException When error copying/removing files.
+ */
+ private void moveGeneratedFile (File baseFile, File sourceBaseFile, String classname)
+ throws BuildException {
String stubFileName = classname.replace('.', '/') + "_Stub.java";
File oldStubFile = new File(baseFile, stubFileName);
File newStubFile = new File(sourceBaseFile, stubFileName);
***************
*** 177,182 ****
--- 222,305 ----
}
}
}
+
+ /**
+ * Checks all the classes listed in classlistFilename to determine whether it needs
+ * to be rmic'd. It assumes that the baseFile is where the classes are generated.
+ *
+ * @exception org.apache.tools.ant.BuildException if the classlistFilename could not
+ * be found.
+ */
+ private void scanFiles(File baseFile, File classlistFile) throws BuildException {
+ if (! classlistFile.exists()) {
+ throw new BuildException("The classlist file " + classlistFilename + " does not exist.");
+ }
+ compileList.removeAllElements();
+ BufferedReader classlist = null;
+ try {
+ classlist = new BufferedReader(new FileReader(classlistFile));
+ String line = null;
+ while ((line = classlist.readLine()) != null) {
+ StringTokenizer st = new StringTokenizer(line);
+ if (st.hasMoreTokens()) {
+ String classname = st.nextToken();
+ if (shouldCompile(baseFile, classname)) {
+ compileList.addElement(classname);
+ }
+ }
+ }
+ } catch (IOException ie) {
+ throw new BuildException(ie.getMessage());
+ } finally {
+ if (classlist != null) {
+ try {
+ classlist.close();
+ } catch (IOException e) {
+ project.log("Unable to close classlist file", Project.MSG_WARN);
+ }
+ }
+ }
+ }
+
+ /**
+ * Determine whether the class needs to be RMI compiled. It looks at the _Stub.class
+ * and _Skel.class files' last modification date and compares it with the class' class file.
+ */
+ private boolean shouldCompile (File baseFile, String classname) {
+ long now = (new Date()).getTime();
+ File classfile = new File(baseFile, translateClassToFilename(classname));
+ File stubFile = new File(classfile.getAbsolutePath().substring(0,
+ classfile.getAbsolutePath().indexOf(".class")) + "_Stub.class");
+ File skelFile = new File(classfile.getAbsolutePath().substring(0,
+ classfile.getAbsolutePath().indexOf(".class")) + "_Skel.class");
+ if (classfile.exists()) {
+ if (classfile.lastModified() > now) {
+ project.log("Warning: file modified in the future: " +
+ classfile, project.MSG_WARN);
+ }
+
+ if (classfile.lastModified() > stubFile.lastModified()) {
+ return true;
+ } else if (classfile.lastModified() > skelFile.lastModified()) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private String translateClassToFilename(String classname) {
+ StringTokenizer st = new StringTokenizer(classname, ".");
+ StringBuffer classFilename = new StringBuffer(classname.length());
+ while (st.hasMoreTokens()) {
+ classFilename.append(st.nextToken());
+ if (st.hasMoreTokens()) {
+ classFilename.append(File.separator);
+ }
+ }
+ classFilename.append(".class");
+ return classFilename.toString();
}
/**