Attached is an optional task that is a subclass (with too much cut and paste ;-) of the Javac task to run the Poet ptjavac external compiler to compile Java code and enhance it for use with the Poet object oriented database (OODB).
To use the task you must have Poet (of course) with the appropriate Poet jars included in your classpath, and the ptjavac compiler executable in your path. Since ptjavac actually uses the Sun compiler classes in some way, you also have to have the appropriate JDK jars in your classpath. The usage is pretty much like the Sun javac compiler with a couple of extra arguments to tell Poet where its configuration file is and what to do with the schema. -- Craig
/* * The Apache Software License, Version 1.1 * * Copyright (c) 1999 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", "Tomcat", 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 [EMAIL PROTECTED] * * 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.optional.poet; import org.apache.tools.ant.taskdefs.*; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.*; import org.apache.tools.ant.util.*; import java.lang.reflect.Method; import java.lang.reflect.Constructor; import java.io.*; import java.util.*; /** * Task to compile Java source files using Poet PTJavac compiler. * This task can take the following arguments: * <ul> * <li>sourcedir * <li>destdir * <li>deprecation * <li>classpath * <li>bootclasspath * <li>extdirs * <li>optimize * <li>debug * <li>encoding * <li>target * <li>vebose * <li>poetschemaargs * <li>poetconfigpath * </ul> * Of these arguments, the <b>poetschemaargs</b>, <b>poetconfigpath</b>, * <b>sourcedir</b> and <b>destdir</b> are required. * <p> * When this task executes, it will recursively scan the sourcedir and * destdir looking for Java source files to compile. This task makes its * compile decision based on timestamp. * * @author Craig Kelley (from Javac.java) */ public class PTJavac extends Javac { /** * Integer returned by the "Modern" jdk1.3 compiler to indicate success. */ private static final int MODERN_COMPILER_SUCCESS = 0; private static final String FAIL_MSG = "Compile failed, messages should have been provided."; private Path src; private File destDir; private Path compileClasspath; private String encoding; private boolean debug = false; private boolean optimize = false; private boolean deprecation = false; private boolean depend = false; private boolean verbose = false; private String target; private Path bootclasspath; private Path extdirs; private static String lSep = System.getProperty("line.separator"); private String poetSchemaArgs; private File poetConfigPath; /** * Create a nested <src ...> element for multiple source path * support. * * @return a nexted src element. */ public Path createSrc() { if (src == null) { src = new Path(project); } return src.createPath(); } /** * Set the source dirs to find the source Java files. */ public void setSrcdir(Path srcDir) { if (src == null) { src = srcDir; } else { src.append(srcDir); } } /** * Set the destination directory into which the Java source * files should be compiled. */ public void setDestdir(File destDir) { this.destDir = destDir; } /** * Set the classpath to be used for this compilation. */ public void setClasspath(Path classpath) { if (compileClasspath == null) { compileClasspath = classpath; } else { compileClasspath.append(classpath); } } /** * Maybe creates a nested classpath element. */ public Path createClasspath() { if (compileClasspath == null) { compileClasspath = new Path(project); } return compileClasspath.createPath(); } /** * Adds a reference to a CLASSPATH defined elsewhere. */ public void setClasspathRef(Reference r) { createClasspath().setRefid(r); } /** * Sets the bootclasspath that will be used to compile the classes * against. */ public void setBootclasspath(Path bootclasspath) { if (this.bootclasspath == null) { this.bootclasspath = bootclasspath; } else { this.bootclasspath.append(bootclasspath); } } /** * Maybe creates a nested classpath element. */ public Path createBootclasspath() { if (bootclasspath == null) { bootclasspath = new Path(project); } return bootclasspath.createPath(); } /** * Adds a reference to a CLASSPATH defined elsewhere. */ public void setBootClasspathRef(Reference r) { createBootclasspath().setRefid(r); } /** * 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 classpath element. */ public Path createExtdirs() { if (extdirs == null) { extdirs = new Path(project); } return extdirs.createPath(); } /** * Set the deprecation flag. */ public void setDeprecation(boolean deprecation) { this.deprecation = deprecation; } /** * Set the Java source file encoding name. */ public void setEncoding(String encoding) { this.encoding = encoding; } /** * Set the debug flag. */ public void setDebug(boolean debug) { this.debug = debug; } /** * Set the optimize flag. */ public void setOptimize(boolean optimize) { this.optimize = optimize; } /** * Set the depend flag. */ public void setDepend(boolean depend) { this.depend = depend; } /** * Set the verbose flag. */ public void setVerbose(boolean verbose) { this.verbose = verbose; } /** * Sets the target VM that the classes will be compiled for. Valid * strings are "1.1", "1.2", and "1.3". */ public void setTarget(String target) { this.target = target; } /** * Get the value of poetSchemaArgs. */ public String getPoetSchemaArgs() { return poetSchemaArgs; } /** * Set the value of poetSchemaArgs. * @param v Value to assign to poetSchemaArgs. */ public void setPoetSchemaArgs(String v) { this.poetSchemaArgs = v; } /** * Get the value of poetConfigPath. */ public File getPoetConfigPath() { return poetConfigPath; } /** * Set the value of poetConfigPath. * @param v Value to assign to poetConfigPath. */ public void setPoetConfigPath(File v) { this.poetConfigPath = v; } /** * Executes the task. */ public void execute() throws BuildException { // first off, make sure that we've got a srcdir if (src == null) { throw new BuildException("srcdir attribute must be set!", location); } String [] list = src.list(); if (list.length == 0) { throw new BuildException("srcdir attribute must be set!", location); } if (destDir != null && !destDir.isDirectory()) { throw new BuildException("destination directory \"" + destDir + "\" does not exist or is not a directory", location); } if (poetSchemaArgs == null) { throw new BuildException("poetschemaargs attribute must be set!"); } if (poetConfigPath == null) { throw new BuildException("poetconfigpath attribute must be set!"); } // scan source directories and dest directory to build up both copy lists and // compile lists resetFileLists(); for (int i=0; i<list.length; i++) { File srcDir = (File)project.resolveFile(list[i]); if (!srcDir.exists()) { throw new BuildException("srcdir \"" + srcDir.getPath() + "\" does not exist!", location); } DirectoryScanner ds = this.getDirectoryScanner(srcDir); String[] files = ds.getIncludedFiles(); scanDir(srcDir, destDir != null ? destDir : srcDir, files); } // compile the source files String compiler = project.getProperty("build.compiler"); if (compiler == null) { if (Project.getJavaVersion().startsWith("1.3")) { compiler = "modern"; } else { compiler = "classic"; } } if (compileList.length > 0) { log("Compiling " + compileList.length + " source file" + (compileList.length == 1 ? "" : "s") + (destDir != null ? " to " + destDir : "")); doPoetCompile(); } } /** * Performs a compile using the Poet ptjavac compiler. * Does the command line argument processing common to classic and * modern compiler, plus Poet specific. */ private void doPoetCompile() throws BuildException { log("Using POET ptjavac compiler", Project.MSG_VERBOSE); Path classpath = getCompileClasspath(false); Commandline cmd = new Commandline(); cmd.setExecutable("ptjavac"); // Take care of the POET specific flags. if (poetSchemaArgs != null) { cmd.createArgument().setValue(poetSchemaArgs); } if (poetConfigPath != null) { cmd.createArgument().setValue("-conf"); cmd.createArgument().setFile(poetConfigPath); } // Take care of the standard javac flags. if (deprecation == true) { cmd.createArgument().setValue("-deprecation"); } if (destDir != null) { cmd.createArgument().setValue("-d"); cmd.createArgument().setFile(destDir); } cmd.createArgument().setValue("-classpath"); cmd.createArgument().setPath(classpath); cmd.createArgument().setValue("-sourcepath"); cmd.createArgument().setPath(src); if (target != null) { cmd.createArgument().setValue("-target"); cmd.createArgument().setValue(target); } if (encoding != null) { cmd.createArgument().setValue("-encoding"); cmd.createArgument().setValue(encoding); } if (debug) { cmd.createArgument().setValue("-g"); } if (optimize) { cmd.createArgument().setValue("-O"); } if (bootclasspath != null) { cmd.createArgument().setValue("-bootclasspath"); cmd.createArgument().setPath(bootclasspath); } if (extdirs != null) { cmd.createArgument().setValue("-extdirs"); cmd.createArgument().setPath(extdirs); } if (verbose) { cmd.createArgument().setValue("-verbose"); } int firstFileName = cmd.size(); logAndAddFilesToCompile(cmd); if (executePoetCompile(cmd.getCommandline(), firstFileName) != 0) { throw new BuildException(FAIL_MSG, location); } } /** * Do the compile with the specified arguments. * @param args - arguments to pass to process on command line * @param firstFileName - index of the first source file in args */ protected int executePoetCompile(String[] args, int firstFileName) { String[] commandArray = null; File tmpFile = null; commandArray = args; try { Execute exe = new Execute(new LogStreamHandler(this, Project.MSG_INFO, Project.MSG_WARN)); exe.setAntRun(project); exe.setWorkingDirectory(project.getBaseDir()); exe.setCommandline(commandArray); int retValue; retValue = exe.execute(); return retValue; } catch (IOException e) { throw new BuildException("Error running Poet ptjavac compiler", e, location); } } }
Index: defaults.properties =================================================================== RCS file: /home/cvspublic/jakarta-ant/src/main/org/apache/tools/ant/taskdefs/defaults.properties,v retrieving revision 1.58 diff -u -r1.58 defaults.properties --- defaults.properties 2000/11/30 12:41:08 1.58 +++ defaults.properties 2000/12/05 16:54:03 @@ -86,6 +86,7 @@ cccheckout=org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckout cccheckin=org.apache.tools.ant.taskdefs.optional.clearcase.CCCheckin ccuncheckout=org.apache.tools.ant.taskdefs.optional.clearcase.CCUnCheckout +ptjavac=org.apache.tools.ant.taskdefs.optional.poet.PTJavac # deprecated ant tasks (kept for back compatibility) javadoc2=org.apache.tools.ant.taskdefs.Javadoc
Index: build.xml
===================================================================
RCS file: /home/cvspublic/jakarta-ant/build.xml,v
retrieving revision 1.104
diff -u -r1.104 build.xml
--- build.xml 2000/11/29 11:49:45 1.104
+++ build.xml 2000/12/05 15:42:53
@@ -77,6 +77,7 @@
<available property="stylebook.present"
classname="org.apache.stylebook.Engine" />
<available property="jakarta.regexp.present"
classname="org.apache.regexp.RE" />
<available property="jakarta.oro.present"
classname="org.apache.oro.text.regex.Perl5Matcher" />
+ <available property="poet.ptjavac.present"
classname="com.poet.tools.ptjavac.Main" />
</target>
<!-- =================================================================== -->
@@ -120,6 +121,7 @@
<exclude name="**/JakartaRegexpMatcher.java"
unless="jakarta.regexp.present" />
<exclude name="**/JakartaOroMatcher.java" unless="jakarta.oro.present" />
<exclude name="**/perforce/*.java" unless="jakarta.oro.present" />
+ <exclude name="**/poet/*.java" unless="poet.ptjavac.present" />
</javac>
<copy todir="${build.classes}">
PTJavac
Description
Compiles a source tree using the Poet ptjavac external compiler.
The ptjavac compiler compiles and enhances the Java source code for use with the Poet object oriented database (OODB).
The source and destination directory will be recursively scanned for Java source files to compile. Only Java files that have no corresponding class file or where the class file is older than the java file will be compiled.
The directory structure of the source tree should follow the package hierarchy.
It is possible to refine the set of files that are being compiled/copied. This can be done with the includes, includesfile, excludes, excludesfile and defaultexcludes attributes. With the includes or includesfile attribute you specify the files you want to have included by using patterns. The exclude or excludesfile attribute is used to specify the files you want to have excluded. This is also done with patterns. And finally with the defaultexcludes attribute, you can specify whether you want to use default exclusions or not. See the section on directory based tasks, on how the inclusion/exclusion of files works, and how to write patterns.
Parameters
| Attribute | Description | Required |
| poetschemaargs | Poet schema
action arguments. Valid values are:
|
Yes |
| poetconfigpath | Poet configuration
filename specification. Default is ptjavac.opt in
the build root directory. |
No |
| srcdir | location of the java files. | Yes, unless nested <src> elements are present. |
| destdir | location where to store the class files. | No |
| includes | comma separated list of patterns of files that must be included. All files are included when omitted. | No |
| includesfile | the name of a file. Each line of this file is taken to be an include pattern | No |
| excludes | comma separated list of patterns of files that must be excluded. No files (except default excludes) are excluded when omitted. | No |
| excludesfile | the name of a file. Each line of this file is taken to be an exclude pattern | No |
| defaultexcludes | indicates whether default excludes should be used or not ("yes"/"no"). Default excludes are used when omitted. | No |
| classpath | the classpath to use. | No |
| bootclasspath | location of bootstrap class files. | No |
| classpathref | the classpath to use, given as reference to a PATH defined elsewhere. | No |
| bootclasspathref | location of bootstrap class files, given as by reference to a PATH defined elsewhere. | No |
| extdirs | location of installed extensions. | No |
| encoding | encoding of source files. | No |
| debug | indicates whether there should be compiled with debug information ("off"). | No |
| optimize | indicates whether there should be compiled with optimization ("off"). | No |
| deprecation | indicates whether there should be compiled with deprecation information ("off"). | No |
| target | Generate class files for specific VM version, e.g. "1.1" or "1.2". | No |
| verbose | asks the compiler for verbose output. | No |
Parameters specified as nested elements
This task forms an implicit FileSet and
supports all attributes of <fileset>
(dir becomes srcdir) as well as the nested
<include>, <exclude> and
<patternset> elements.
src, classpath, bootclasspath and extdirs
PTJavac's srcdir, classpath,
bootclasspath and extdirs attributes are PATH like structure and can also be set via nested
src, classpath, bootclasspath and
extdirs elements respectively.
Examples
<ptjavac srcdir="${src}"
poetschemaargs="-xc"
poetconfigpath="${src.dir}/ptjavac.opt"
destdir="${build}"
classpath="xyz.jar"
debug="on"
/>
compiles all .java files under the directory ${src}, stores
the .class files in the directory ${build}, and creates
the Poet schema and database files according to the options in the
specified Poet configuration file.
The classpath used contains xyz.jar, and debug information is on.
<ptjavac srcdir="${src}"
poetschemaargs="-xu"
destdir="${build}"
includes="mypackage/p1/**,mypackage/p2/**"
excludes="mypackage/p1/testpackage/**"
classpath="xyz.jar"
debug="on"
/>
compiles .java files under the directory ${src},
updates the Poet schema and database files, and stores the
class files in the directory ${build}.
The classpath used contains xyz.jar, and debug information is on.
Only files under mypackage/p1 and mypackage/p2 are
used. Files in the mypackage/p1/testpackage directory are excluded
form compilation and copy.
<ptjavac srcdir="${src}:${src2}"
poetschemaargs="-xu"
destdir="${build}"
includes="mypackage/p1/**,mypackage/p2/**"
excludes="mypackage/p1/testpackage/**"
classpath="xyz.jar"
debug="on"
/>
is the same as the previous example with the addition of a second source path, defined by
the propery src2. This can also be represented using nested elements as follows
<ptjavac destdir="${build}"
poetschemaargs="-xu"
classpath="xyz.jar"
debug="on">
<src path="${src}" />
<src path="${src2}" />
<include name="mypackage/p1/**" />
<include name="mypackage/p2/**" />
<exclude name="mypackage/p1/testpackage/**" />
</ptjavac>
Note: If you are using Ant on Windows and a new DOS-Window pops up for every use of an external compiler this may be a problem of the JDK you are using. This problem may occur with all JDK's < 1.2.
