failonerror |
If set to false, the build will continue even if there are compilation errors.
diff --git a/src/main/org/apache/tools/ant/taskdefs/Execute.java b/src/main/org/apache/tools/ant/taskdefs/Execute.java
index a9a5e9a4a..be2a73b0f 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Execute.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Execute.java
@@ -355,7 +355,7 @@ public class Execute {
exitValue = value;
}
- protected int getExitValue() {
+ public int getExitValue() {
return exitValue;
}
diff --git a/src/main/org/apache/tools/ant/taskdefs/Javac.java b/src/main/org/apache/tools/ant/taskdefs/Javac.java
index 186ddc3d7..7917f84bd 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Javac.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Javac.java
@@ -59,11 +59,9 @@ 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 org.apache.tools.ant.taskdefs.compilers.*;
-import java.lang.reflect.Method;
-import java.lang.reflect.Constructor;
-import java.io.*;
-import java.util.*;
+import java.io.File;
/**
* Task to compile Java source files. This task can take the following
@@ -81,6 +79,9 @@ import java.util.*;
* target
* depend
* vebose
+ * failonerror
+ * includeantruntime
+ * includejavaruntime
*
* Of these arguments, the sourcedir and destdir are required.
*
@@ -91,16 +92,13 @@ import java.util.*;
* @author James Davidson duncan@x180.com
* @author Robin Green greenrd@hotmail.com
* @author Stefan Bodewig
+ * @author J D Glanville
*/
public class Javac extends MatchingTask {
- /**
- * 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 static final String FAIL_MSG
+ = "Compile failed, messages should have been provided.";
private Path src;
private File destDir;
@@ -114,7 +112,8 @@ public class Javac extends MatchingTask {
private String target;
private Path bootclasspath;
private Path extdirs;
- private static String lSep = System.getProperty("line.separator");
+ private boolean includeAntRuntime = true;
+ private boolean includeJavaRuntime = false;
protected boolean failOnError = true;
protected File[] compileList = new File[0];
@@ -143,6 +142,11 @@ public class Javac extends MatchingTask {
}
}
+ /** Gets the source dirs to find the source java files. */
+ public Path getSrcdir() {
+ return src;
+ }
+
/**
* Set the destination directory into which the Java source
* files should be compiled.
@@ -151,6 +155,14 @@ public class Javac extends MatchingTask {
this.destDir = destDir;
}
+ /**
+ * Gets the destination directory into which the java source files
+ * should be compiled.
+ */
+ public File getDestdir() {
+ return destDir;
+ }
+
/**
* Set the classpath to be used for this compilation.
*/
@@ -162,6 +174,11 @@ public class Javac extends MatchingTask {
}
}
+ /** Gets the classpath to be used for this compilation. */
+ public Path getClasspath() {
+ return compileClasspath;
+ }
+
/**
* Maybe creates a nested classpath element.
*/
@@ -191,6 +208,14 @@ public class Javac extends MatchingTask {
}
}
+ /**
+ * Gets the bootclasspath that will be used to compile the classes
+ * against.
+ */
+ public Path getBootclasspath() {
+ return bootclasspath;
+ }
+
/**
* Maybe creates a nested classpath element.
*/
@@ -220,6 +245,14 @@ public class Javac extends MatchingTask {
}
}
+ /**
+ * Gets the extension directories that will be used during the
+ * compilation.
+ */
+ public Path getExtdirs() {
+ return extdirs;
+ }
+
/**
* Maybe creates a nested classpath element.
*/
@@ -244,6 +277,13 @@ public class Javac extends MatchingTask {
failOnError = !proceed;
}
+ /**
+ * Gets the failonerror flag.
+ */
+ public boolean getFailonerror() {
+ return failOnError;
+ }
+
/**
* Set the deprecation flag.
*/
@@ -251,6 +291,11 @@ public class Javac extends MatchingTask {
this.deprecation = deprecation;
}
+ /** Gets the deprecation flag. */
+ public boolean getDeprecation() {
+ return deprecation;
+ }
+
/**
* Set the Java source file encoding name.
*/
@@ -258,6 +303,11 @@ public class Javac extends MatchingTask {
this.encoding = encoding;
}
+ /** Gets the java source file encoding name. */
+ public String getEncoding() {
+ return encoding;
+ }
+
/**
* Set the debug flag.
*/
@@ -265,26 +315,46 @@ public class Javac extends MatchingTask {
this.debug = debug;
}
+ /** Gets the debug flag. */
+ public boolean getDebug() {
+ return debug;
+ }
+
/**
* Set the optimize flag.
*/
- public void setOptimize(boolean optimize) {
- this.optimize = optimize;
- }
+ public void setOptimize(boolean optimize) {
+ this.optimize = optimize;
+ }
+
+ /** Gets the optimize flag. */
+ public boolean getOptimize() {
+ return optimize;
+ }
/**
* Set the depend flag.
*/
- public void setDepend(boolean depend) {
- this.depend = depend;
- }
+ public void setDepend(boolean depend) {
+ this.depend = depend;
+ }
+
+ /** Gets the depend flag. */
+ public boolean getDepend() {
+ return depend;
+ }
/**
* Set the verbose flag.
*/
- public void setVerbose(boolean verbose) {
- this.verbose = verbose;
- }
+ public void setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ /** Gets the verbose flag. */
+ public boolean getVerbose() {
+ return verbose;
+ }
/**
* Sets the target VM that the classes will be compiled for. Valid
@@ -294,6 +364,42 @@ public class Javac extends MatchingTask {
this.target = target;
}
+ /** Gets the target VM that the classes will be compiled for. */
+ public String getTarget() {
+ return target;
+ }
+
+ /**
+ * 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;
+ }
+
/**
* Executes the task.
*/
@@ -312,7 +418,7 @@ public class Javac extends MatchingTask {
throw new BuildException("destination directory \"" + destDir + "\" does not exist or is not a directory", location);
}
- // scan source directories and dest directory to build up both copy lists and
+ // scan source directories and dest directory to build up
// compile lists
resetFileLists();
for (int i=0; i 0) {
+
+ CompilerAdapter adapter = CompilerAdapterFactory.getCompiler(
+ compiler, this );
log("Compiling " + compileList.length +
" source file"
+ (compileList.length == 1 ? "" : "s")
+ (destDir != null ? " to " + destDir : ""));
- boolean compileSucceeded = false;
-
- if (compiler.equalsIgnoreCase("classic")) {
- compileSucceeded = doClassicCompile();
- } else if (compiler.equalsIgnoreCase("modern")) {
- compileSucceeded = doModernCompile();
- } else if (compiler.equalsIgnoreCase("jikes")) {
- compileSucceeded = doJikesCompile();
- } else if (compiler.equalsIgnoreCase("jvc")) {
- compileSucceeded = doJvcCompile();
- } else {
- String msg = "Don't know how to use compiler " + compiler;
- throw new BuildException(msg, location);
- }
+ // now we need to populate the compiler adapter
+ adapter.setJavac( this );
- if (!compileSucceeded) {
+ // finally, lets execute the compiler!!
+ if (!adapter.execute()) {
if (failOnError) {
throw new BuildException(FAIL_MSG, location);
}
@@ -382,7 +480,6 @@ public class Javac extends MatchingTask {
* Scans the directory looking for source files to be compiled.
* The results are returned in the class variable compileList
*/
-
protected void scanDir(File srcDir, File destDir, String files[]) {
GlobPatternMapper m = new GlobPatternMapper();
m.setFrom("*.java");
@@ -391,527 +488,19 @@ public class Javac extends MatchingTask {
File[] newFiles = sfs.restrictAsFiles(files, srcDir, destDir, m);
if (newFiles.length > 0) {
- File[] newCompileList = new File[compileList.length + newFiles.length];
- System.arraycopy(compileList, 0, newCompileList, 0, compileList.length);
- System.arraycopy(newFiles, 0, newCompileList, compileList.length, newFiles.length);
+ File[] newCompileList = new File[compileList.length +
+ newFiles.length];
+ System.arraycopy(compileList, 0, newCompileList, 0,
+ compileList.length);
+ System.arraycopy(newFiles, 0, newCompileList,
+ compileList.length, newFiles.length);
compileList = newCompileList;
}
}
- /**
- * Builds the compilation classpath.
- *
- * @param addRuntime Shall rt.jar or
- * classes.zip be added to the classpath.
- */
- protected Path getCompileClasspath(boolean addRuntime) {
- Path classpath = new Path(project);
-
- // add dest dir to classpath so that previously compiled and
- // untouched classes are on classpath
-
- if (destDir != null) {
- classpath.setLocation(destDir);
- }
-
- // 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());
- }
-
- // optionally add the runtime classes
-
- if (addRuntime) {
- 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 {
- // 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;
- }
-
- /**
- * Peforms a compile using the classic compiler that shipped with
- * JDK 1.1 and 1.2.
- *
- * @return true if the compile succeeded
- */
- private boolean doClassicCompile() throws BuildException {
- log("Using classic compiler", Project.MSG_VERBOSE);
- Commandline cmd = setupJavacCommand();
-
- // Use reflection to be able to build on all JDKs
- /*
- // provide the compiler a different message sink - namely our own
- sun.tools.javac.Main compiler =
- new sun.tools.javac.Main(new LogOutputStream(this, Project.MSG_WARN), "javac");
-
- if (!compiler.compile(cmd.getArguments())) {
- throw new BuildException("Compile failed");
- }
- */
- try {
- // Create an instance of the compiler, redirecting output to
- // the project log
- OutputStream logstr = new LogOutputStream(this, Project.MSG_WARN);
- Class c = Class.forName("sun.tools.javac.Main");
- Constructor cons = c.getConstructor(new Class[] { OutputStream.class, String.class });
- Object compiler = cons.newInstance(new Object[] { logstr, "javac" });
-
- // Call the compile() method
- Method compile = c.getMethod("compile", new Class [] { String[].class });
- Boolean ok = (Boolean)compile.invoke(compiler, new Object[] {cmd.getArguments()});
- return ok.booleanValue();
- }
- catch (ClassNotFoundException ex) {
- throw new BuildException("Cannot use classic compiler, as it is not available"+
- " A common solution is to set the environment variable"+
- " JAVA_HOME to your jdk directory.", location);
- }
- catch (Exception ex) {
- if (ex instanceof BuildException) {
- throw (BuildException) ex;
- } else {
- throw new BuildException("Error starting classic compiler: ", ex, location);
- }
- }
- }
-
- /**
- * Performs a compile using the newer compiler that ships with JDK 1.3
- *
- * @return true if the compile succeeded
- */
- private boolean doModernCompile() throws BuildException {
- try {
- Class.forName("com.sun.tools.javac.Main");
- } catch (ClassNotFoundException cnfe) {
- log("Modern compiler is not available - using classic compiler", Project.MSG_WARN);
- return doClassicCompile();
- }
-
- log("Using modern compiler", Project.MSG_VERBOSE);
- Commandline cmd = setupJavacCommand();
-
- PrintStream err = System.err;
- PrintStream out = System.out;
-
- // Use reflection to be able to build on all JDKs >= 1.1:
- try {
- PrintStream logstr =
- new PrintStream(new LogOutputStream(this, Project.MSG_WARN));
- System.setOut(logstr);
- System.setErr(logstr);
- Class c = Class.forName ("com.sun.tools.javac.Main");
- Object compiler = c.newInstance ();
- Method compile = c.getMethod ("compile",
- new Class [] {(new String [] {}).getClass ()});
- int result = ((Integer) compile.invoke
- (compiler, new Object[] {cmd.getArguments()})) .intValue ();
- return (result == MODERN_COMPILER_SUCCESS);
- } catch (Exception ex) {
- if (ex instanceof BuildException) {
- throw (BuildException) ex;
- } else {
- throw new BuildException("Error starting modern compiler", ex, location);
- }
- } finally {
- System.setErr(err);
- System.setOut(out);
- }
+ /** Gets the list of files to be compiled. */
+ public File[] getFileList() {
+ return compileList;
}
- /**
- * Does the command line argument processing common to classic and
- * modern.
- */
- private Commandline setupJavacCommand() {
- Commandline cmd = new Commandline();
- Path classpath = getCompileClasspath(false);
-
- if (deprecation == true) {
- cmd.createArgument().setValue("-deprecation");
- }
-
- if (destDir != null) {
- cmd.createArgument().setValue("-d");
- cmd.createArgument().setFile(destDir);
- }
-
- cmd.createArgument().setValue("-classpath");
- // Just add "sourcepath" to classpath ( for JDK1.1 )
- if (Project.getJavaVersion().startsWith("1.1")) {
- cmd.createArgument().setValue(classpath.toString()
- + File.pathSeparator
- + src.toString());
- } else {
- 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 (depend) {
- if (Project.getJavaVersion().startsWith("1.1")) {
- cmd.createArgument().setValue("-depend");
- } else if (Project.getJavaVersion().startsWith("1.2")) {
- cmd.createArgument().setValue("-Xdepend");
- } else {
- log("depend attribute is not supported by the modern compiler",
- Project.MSG_WARN);
- }
- }
-
- if (verbose) {
- cmd.createArgument().setValue("-verbose");
- }
-
- logAndAddFilesToCompile(cmd);
- return cmd;
- }
-
- /**
- * Logs the compilation parameters, adds the files to compile and logs the
- * &qout;niceSourceList"
- */
- protected void logAndAddFilesToCompile(Commandline cmd) {
- log("Compilation args: " + cmd.toString(),
- Project.MSG_VERBOSE);
-
- StringBuffer niceSourceList = new StringBuffer("File");
- if (compileList.length != 1) {
- niceSourceList.append("s");
- }
- niceSourceList.append(" to be compiled:");
-
- niceSourceList.append(lSep);
-
- for (int i=0; i < compileList.length; i++) {
- String arg = compileList[i].getAbsolutePath();
- cmd.createArgument().setValue(arg);
- niceSourceList.append(" " + arg + lSep);
- }
-
- log(niceSourceList.toString(), Project.MSG_VERBOSE);
- }
-
- /**
- * Performs a compile using the Jikes compiler from IBM..
- * Mostly of this code is identical to doClassicCompile()
- * However, it does not support all options like
- * bootclasspath, extdirs, deprecation and so on, because
- * there is no option in jikes and I don't understand
- * what they should do.
- *
- * It has been successfully tested with jikes >1.10
- *
- * @author skanthak@muehlheim.de
- *
- * @return true if the compile succeeded
- */
- private boolean doJikesCompile() throws BuildException {
- log("Using jikes compiler", Project.MSG_VERBOSE);
-
- Path classpath = new Path(project);
-
- // Jikes doesn't support bootclasspath dir (-bootclasspath)
- // so we'll emulate it for compatibility and convenience.
- if (bootclasspath != null) {
- classpath.append(bootclasspath);
- }
-
- // Jikes doesn't support an extension dir (-extdir)
- // so we'll emulate it for compatibility and convenience.
- addExtdirsToClasspath(classpath);
-
- classpath.append(getCompileClasspath(true));
-
- // Jikes has no option for source-path so we
- // will add it to classpath.
- classpath.append(src);
-
- // if the user has set JIKESPATH we should add the contents as well
- String jikesPath = System.getProperty("jikes.class.path");
- if (jikesPath != null) {
- classpath.append(new Path(project, jikesPath));
- }
-
- Commandline cmd = new Commandline();
- cmd.setExecutable("jikes");
-
- 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);
-
- if (encoding != null) {
- cmd.createArgument().setValue("-encoding");
- cmd.createArgument().setValue(encoding);
- }
- if (debug) {
- cmd.createArgument().setValue("-g");
- }
- if (optimize) {
- cmd.createArgument().setValue("-O");
- }
- if (verbose) {
- cmd.createArgument().setValue("-verbose");
- }
- if (depend) {
- cmd.createArgument().setValue("-depend");
- }
- /**
- * XXX
- * Perhaps we shouldn't use properties for these
- * three options (emacs mode, warnings and pedantic),
- * but include it in the javac directive?
- */
-
- /**
- * Jikes has the nice feature to print error
- * messages in a form readable by emacs, so
- * that emacs can directly set the cursor
- * to the place, where the error occured.
- */
- String emacsProperty = project.getProperty("build.compiler.emacs");
- if (emacsProperty != null && Project.toBoolean(emacsProperty)) {
- cmd.createArgument().setValue("+E");
- }
-
- /**
- * Jikes issues more warnings that javac, for
- * example, when you have files in your classpath
- * that don't exist. As this is often the case, these
- * warning can be pretty annoying.
- */
- String warningsProperty = project.getProperty("build.compiler.warnings");
- if (warningsProperty != null && !Project.toBoolean(warningsProperty)) {
- cmd.createArgument().setValue("-nowarn");
- }
-
- /**
- * Jikes can issue pedantic warnings.
- */
- String pedanticProperty = project.getProperty("build.compiler.pedantic");
- if (pedanticProperty != null && Project.toBoolean(pedanticProperty)) {
- cmd.createArgument().setValue("+P");
- }
-
- /**
- * Jikes supports something it calls "full dependency
- * checking", see the jikes documentation for differences
- * between -depend and +F.
- */
- String fullDependProperty = project.getProperty("build.compiler.fulldepend");
- if (fullDependProperty != null && Project.toBoolean(fullDependProperty)) {
- cmd.createArgument().setValue("+F");
- }
-
- int firstFileName = cmd.size();
- logAndAddFilesToCompile(cmd);
-
- return executeExternalCompile(cmd.getCommandline(), firstFileName) == 0;
- }
-
- /**
- * 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 executeExternalCompile(String[] args, int firstFileName) {
- String[] commandArray = null;
- File tmpFile = null;
-
- try {
- /*
- * Many system have been reported to get into trouble with
- * long command lines - no, not only Windows ;-).
- *
- * POSIX seems to define a lower limit of 4k, so use a temporary
- * file if the total length of the command line exceeds this limit.
- */
- if (Commandline.toString(args).length() > 4096) {
- PrintWriter out = null;
- try {
- tmpFile = new File("jikes"+(new Random(System.currentTimeMillis())).nextLong());
- out = new PrintWriter(new FileWriter(tmpFile));
- for (int i = firstFileName; i < args.length; i++) {
- out.println(args[i]);
- }
- out.flush();
- commandArray = new String[firstFileName+1];
- System.arraycopy(args, 0, commandArray, 0, firstFileName);
- commandArray[firstFileName] = "@" + tmpFile.getAbsolutePath();
- } catch (IOException e) {
- throw new BuildException("Error creating temporary file", e, location);
- } finally {
- if (out != null) {
- try {out.close();} catch (Throwable t) {}
- }
- }
- } else {
- 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);
- exe.execute();
- return exe.getExitValue();
- } catch (IOException e) {
- throw new BuildException("Error running Jikes compiler", e, location);
- }
- } finally {
- if (tmpFile != null) {
- tmpFile.delete();
- }
- }
- }
-
- /**
- * 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) {
- if (extdirs == null) {
- String extProp = System.getProperty("java.ext.dirs");
- if (extProp != null) {
- extdirs = new Path(project, extProp);
- } else {
- return;
- }
- }
-
- String[] dirs = extdirs.list();
- for (int i=0; i.
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Javac;
+
+/**
+ * The interface that all compiler adapters must adher to.
+ *
+ * A compiler adapter is an adapter that interprets the javac's
+ * parameters in preperation to be passed off to the compier this
+ * adapter represents. As all the necessary values are stored in the
+ * Javac task itself, the only thing all adapters need is the javac
+ * task, the execute command and a parameterless constructor (for
+ * reflection).
+ *
+ * @author Jay Dickon Glanville jayglanville@home.com
+ */
+
+public interface CompilerAdapter {
+
+ /**
+ * Sets the compiler attributes, which are stored in the Javac task.
+ */
+ public void setJavac( Javac attributes );
+
+ /**
+ * Executes the task.
+ *
+ * @return has the compilation been successful
+ */
+ public boolean execute() throws BuildException;
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java b/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java
new file mode 100644
index 000000000..ed3dcfbe5
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java
@@ -0,0 +1,151 @@
+/*
+ * 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
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.Project;
+
+/**
+ * Creates the necessary compiler adapter, given basic criteria.
+ *
+ * @author J D Glanville
+ */
+public class CompilerAdapterFactory {
+
+ /** This is a singlton -- can't create instances!! */
+ private CompilerAdapterFactory() {
+ }
+
+ /**
+ * Based on the parameter passed in, this method creates the necessary
+ * factory desired.
+ *
+ * The current mapping for compiler names are as follows:
+ * - jikes = jikes compiler
+ *
- classic, javac1.1, javac1.2 = the standard compiler from JDK
+ * 1.1/1.2
+ *
- modern, javac1.3 = the new compiler of JDK 1.3
+ *
- jvc, microsoft = the command line compiler from Microsoft's SDK
+ * for Java / Visual J++
+ *
- a fully quallified classname = the name of a compiler
+ * adapter
+ *
+ *
+ * @param compilerType either the name of the desired compiler, or the
+ * full classname of the compiler's adapter.
+ * @param task a task to log through.
+ * @throws BuildException if the compiler type could not be resolved into
+ * a compiler adapter.
+ */
+ public static CompilerAdapter getCompiler( String compilerType, Task task )
+ throws BuildException {
+ /* If I've done things right, this should be the extent of the
+ * conditional statements required.
+ */
+ if ( compilerType.equalsIgnoreCase("jikes") ) {
+ return new Jikes();
+ }
+ if ( compilerType.equalsIgnoreCase("classic") ||
+ compilerType.equalsIgnoreCase("javac1.1") ||
+ compilerType.equalsIgnoreCase("javac1.2")) {
+ return new Javac12();
+ }
+ if ( compilerType.equalsIgnoreCase("modern") ||
+ compilerType.equalsIgnoreCase("javac1.3")) {
+ // does the modern compiler exist?
+ try {
+ Class.forName("com.sun.tools.javac.Main");
+ } catch (ClassNotFoundException cnfe) {
+ task.log("Modern compiler is not available - using "
+ + "classic compiler", Project.MSG_WARN);
+ return new Javac12();
+ }
+ return new Javac13();
+ }
+ if ( compilerType.equalsIgnoreCase("jvc") ||
+ compilerType.equalsIgnoreCase("microsoft")) {
+ return new Jvc();
+ }
+ return resolveClassName( compilerType );
+ }
+
+ /**
+ * Tries to resolve the given classname into a compiler 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 CompilerAdapter.
+ */
+ private static CompilerAdapter resolveClassName( String className )
+ throws BuildException {
+ try {
+ Class c = Class.forName( className );
+ Object o = c.newInstance();
+ return (CompilerAdapter) 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 compiler adapter.", cce);
+ } catch ( Throwable t ) {
+ // for all other possibilities
+ throw new BuildException(className + " caused an interesting "
+ + "exception.", t);
+ }
+ }
+
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java b/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java
new file mode 100644
index 000000000..867cb3a78
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java
@@ -0,0 +1,373 @@
+/*
+ * 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
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import org.apache.tools.ant.*;
+import org.apache.tools.ant.taskdefs.*;
+import org.apache.tools.ant.types.*;
+
+import java.io.*;
+import java.util.Random;
+
+/**
+ * This is the default implementation for the CompilerAdapter interface.
+ * Currently, this is a cut-and-paste of the original javac task.
+ *
+ * @author James Davidson duncan@x180.com
+ * @author Robin Green greenrd@hotmail.com
+ * @author Stefan Bodewig
+ * @author J D Glanville
+ */
+public abstract class DefaultCompilerAdapter implements CompilerAdapter {
+
+ /* jdg - TODO - all these attributes are currently protected, but they
+ * should probably be private in the near future.
+ */
+
+ protected Path src;
+ protected File destDir;
+ protected String encoding;
+ protected boolean debug = false;
+ protected boolean optimize = false;
+ protected boolean deprecation = false;
+ protected boolean depend = false;
+ protected boolean verbose = false;
+ protected String target;
+ protected Path bootclasspath;
+ protected Path extdirs;
+ protected Path compileClasspath;
+ protected Project project;
+ protected Location location;
+ protected boolean includeAntRuntime;
+ protected boolean includeJavaRuntime;
+
+ protected File[] compileList;
+ protected static String lSep = System.getProperty("line.separator");
+ protected Javac attributes;
+
+ public void setJavac( Javac attributes ) {
+ this.attributes = attributes;
+ src = attributes.getSrcdir();
+ destDir = attributes.getDestdir();
+ encoding = attributes.getEncoding();
+ debug = attributes.getDebug();
+ optimize = attributes.getOptimize();
+ deprecation = attributes.getDeprecation();
+ depend = attributes.getDepend();
+ verbose = attributes.getVerbose();
+ target = attributes.getTarget();
+ bootclasspath = attributes.getBootclasspath();
+ extdirs = attributes.getExtdirs();
+ compileList = attributes.getFileList();
+ compileClasspath = attributes.getClasspath();
+ project = attributes.getProject();
+ location = attributes.getLocation();
+ includeAntRuntime = attributes.getIncludeantruntime();
+ includeJavaRuntime = attributes.getIncludejavaruntime();
+ }
+
+ public Javac getJavac() {
+ return attributes;
+ }
+
+ /**
+ * Builds the compilation classpath.
+ *
+ */
+ protected Path getCompileClasspath() {
+ Path classpath = new Path(project);
+
+ // add dest dir to classpath so that previously compiled and
+ // untouched classes are on classpath
+
+ if (destDir != null) {
+ classpath.setLocation(destDir);
+ }
+
+ // Combine the build classpath with the system classpath, in an
+ // order determined by the value of build.classpath
+
+ if (compileClasspath == null) {
+ if ( includeAntRuntime ) {
+ classpath.addExisting(Path.systemClasspath);
+ }
+ } else {
+ if ( includeAntRuntime ) {
+ classpath.addExisting(compileClasspath.concatSystemClasspath("last"));
+ } else {
+ classpath.addExisting(compileClasspath.concatSystemClasspath("ignore"));
+ }
+ }
+
+ if (includeJavaRuntime) {
+ 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 {
+ // 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;
+ }
+
+ /**
+ * Does the command line argument processing common to classic and
+ * modern.
+ */
+ protected Commandline setupJavacCommand() {
+ Commandline cmd = new Commandline();
+ Path classpath = getCompileClasspath();
+
+ if (deprecation == true) {
+ cmd.createArgument().setValue("-deprecation");
+ }
+
+ if (destDir != null) {
+ cmd.createArgument().setValue("-d");
+ cmd.createArgument().setFile(destDir);
+ }
+
+ cmd.createArgument().setValue("-classpath");
+ // Just add "sourcepath" to classpath ( for JDK1.1 )
+ if (Project.getJavaVersion().startsWith("1.1")) {
+ cmd.createArgument().setValue(classpath.toString()
+ + File.pathSeparator
+ + src.toString());
+ } else {
+ 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 (depend) {
+ if (Project.getJavaVersion().startsWith("1.1")) {
+ cmd.createArgument().setValue("-depend");
+ } else if (Project.getJavaVersion().startsWith("1.2")) {
+ cmd.createArgument().setValue("-Xdepend");
+ } else {
+ attributes.log("depend attribute is not supported by the modern compiler",
+ Project.MSG_WARN);
+ }
+ }
+
+ if (verbose) {
+ cmd.createArgument().setValue("-verbose");
+ }
+
+ logAndAddFilesToCompile(cmd);
+ return cmd;
+ }
+
+ /**
+ * Logs the compilation parameters, adds the files to compile and logs the
+ * &qout;niceSourceList"
+ */
+ protected void logAndAddFilesToCompile(Commandline cmd) {
+ attributes.log("Compilation args: " + cmd.toString(),
+ Project.MSG_VERBOSE);
+
+ StringBuffer niceSourceList = new StringBuffer("File");
+ if (compileList.length != 1) {
+ niceSourceList.append("s");
+ }
+ niceSourceList.append(" to be compiled:");
+
+ niceSourceList.append(lSep);
+
+ for (int i=0; i < compileList.length; i++) {
+ String arg = compileList[i].getAbsolutePath();
+ cmd.createArgument().setValue(arg);
+ niceSourceList.append(" " + arg + lSep);
+ }
+
+ attributes.log(niceSourceList.toString(), Project.MSG_VERBOSE);
+ }
+
+ /**
+ * 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 executeExternalCompile(String[] args, int firstFileName) {
+ String[] commandArray = null;
+ File tmpFile = null;
+
+ try {
+ /*
+ * Many system have been reported to get into trouble with
+ * long command lines - no, not only Windows ;-).
+ *
+ * POSIX seems to define a lower limit of 4k, so use a temporary
+ * file if the total length of the command line exceeds this limit.
+ */
+ if (Commandline.toString(args).length() > 4096) {
+ PrintWriter out = null;
+ try {
+ tmpFile = new File("jikes"+(new Random(System.currentTimeMillis())).nextLong());
+ out = new PrintWriter(new FileWriter(tmpFile));
+ for (int i = firstFileName; i < args.length; i++) {
+ out.println(args[i]);
+ }
+ out.flush();
+ commandArray = new String[firstFileName+1];
+ System.arraycopy(args, 0, commandArray, 0, firstFileName);
+ commandArray[firstFileName] = "@" + tmpFile.getAbsolutePath();
+ } catch (IOException e) {
+ throw new BuildException("Error creating temporary file", e, location);
+ } finally {
+ if (out != null) {
+ try {out.close();} catch (Throwable t) {}
+ }
+ }
+ } else {
+ commandArray = args;
+ }
+
+ try {
+ Execute exe = new Execute(new LogStreamHandler(attributes,
+ Project.MSG_INFO,
+ Project.MSG_WARN));
+ exe.setAntRun(project);
+ exe.setWorkingDirectory(project.getBaseDir());
+ exe.setCommandline(commandArray);
+ exe.execute();
+ return exe.getExitValue();
+ } catch (IOException e) {
+ throw new BuildException("Error running " + args[0]
+ + " compiler", e, location);
+ }
+ } finally {
+ if (tmpFile != null) {
+ tmpFile.delete();
+ }
+ }
+ }
+
+ /**
+ * 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) {
+ if (extdirs == null) {
+ String extProp = System.getProperty("java.ext.dirs");
+ if (extProp != null) {
+ extdirs = new Path(project, extProp);
+ } else {
+ return;
+ }
+ }
+
+ String[] dirs = extdirs.list();
+ for (int i=0; i.
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+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 javac compiler for JDK 1.2
+ * This is primarily a cut-and-paste from the original javac task before it
+ * was refactored.
+ *
+ * @author James Davidson duncan@x180.com
+ * @author Robin Green greenrd@hotmail.com
+ * @author Stefan Bodewig
+ * @author J D Glanville
+ */
+public class Javac12 extends DefaultCompilerAdapter {
+
+ public boolean execute() throws BuildException {
+ attributes.log("Using classic compiler", Project.MSG_VERBOSE);
+ Commandline cmd = setupJavacCommand();
+
+ try {
+ // Create an instance of the compiler, redirecting output to
+ // the project log
+ OutputStream logstr = new LogOutputStream(attributes, Project.MSG_WARN);
+ Class c = Class.forName("sun.tools.javac.Main");
+ Constructor cons = c.getConstructor(new Class[] { OutputStream.class, String.class });
+ Object compiler = cons.newInstance(new Object[] { logstr, "javac" });
+
+ // Call the compile() method
+ Method compile = c.getMethod("compile", new Class [] { String[].class });
+ Boolean ok = (Boolean)compile.invoke(compiler, new Object[] {cmd.getArguments()});
+ return ok.booleanValue();
+ }
+ catch (ClassNotFoundException ex) {
+ throw new BuildException("Cannot use classic compiler, as it is not available"+
+ " A common solution is to set the environment variable"+
+ " JAVA_HOME to your jdk directory.", location);
+ }
+ catch (Exception ex) {
+ if (ex instanceof BuildException) {
+ throw (BuildException) ex;
+ } else {
+ throw new BuildException("Error starting classic compiler: ", ex, location);
+ }
+ }
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java b/src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java
new file mode 100644
index 000000000..a50713f95
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java
@@ -0,0 +1,113 @@
+/*
+ * 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
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+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.lang.reflect.Method;
+import java.io.*;
+
+/**
+ * The implementation of the javac compiler for JDK 1.3
+ * This is primarily a cut-and-paste from the original javac task before it
+ * was refactored.
+ *
+ * @author James Davidson duncan@x180.com
+ * @author Robin Green greenrd@hotmail.com
+ * @author Stefan Bodewig
+ * @author J D Glanville
+ */
+public class Javac13 extends DefaultCompilerAdapter {
+
+ /**
+ * Integer returned by the "Modern" jdk1.3 compiler to indicate success.
+ */
+ private static final int MODERN_COMPILER_SUCCESS = 0;
+
+ public boolean execute() throws BuildException {
+ attributes.log("Using modern compiler", Project.MSG_VERBOSE);
+ Commandline cmd = setupJavacCommand();
+
+ PrintStream err = System.err;
+ PrintStream out = System.out;
+
+ // Use reflection to be able to build on all JDKs >= 1.1:
+ try {
+ PrintStream logstr =
+ new PrintStream(new LogOutputStream(attributes, Project.MSG_WARN));
+ System.setOut(logstr);
+ System.setErr(logstr);
+ Class c = Class.forName ("com.sun.tools.javac.Main");
+ Object compiler = c.newInstance ();
+ Method compile = c.getMethod ("compile",
+ new Class [] {(new String [] {}).getClass ()});
+ int result = ((Integer) compile.invoke
+ (compiler, new Object[] {cmd.getArguments()})) .intValue ();
+ return (result == MODERN_COMPILER_SUCCESS);
+ } catch (Exception ex) {
+ if (ex instanceof BuildException) {
+ throw (BuildException) ex;
+ } else {
+ throw new BuildException("Error starting modern compiler", ex, location);
+ }
+ } finally {
+ System.setErr(err);
+ System.setOut(out);
+ }
+ }
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/Jikes.java b/src/main/org/apache/tools/ant/taskdefs/compilers/Jikes.java
new file mode 100644
index 000000000..fbc4e1266
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/Jikes.java
@@ -0,0 +1,205 @@
+/*
+ * 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
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.*;
+
+/**
+ * The implementation of the jikes compiler.
+ * This is primarily a cut-and-paste from the original javac task before it
+ * was refactored.
+ *
+ * @author James Davidson duncan@x180.com
+ * @author Robin Green greenrd@hotmail.com
+ * @author Stefan Bodewig
+ * @author J D Glanville
+ */
+public class Jikes extends DefaultCompilerAdapter {
+
+ /**
+ * Performs a compile using the Jikes compiler from IBM..
+ * Mostly of this code is identical to doClassicCompile()
+ * However, it does not support all options like
+ * bootclasspath, extdirs, deprecation and so on, because
+ * there is no option in jikes and I don't understand
+ * what they should do.
+ *
+ * It has been successfully tested with jikes >1.10
+ *
+ * @author skanthak@muehlheim.de
+ */
+ public boolean execute() throws BuildException {
+ attributes.log("Using jikes compiler", Project.MSG_VERBOSE);
+
+ Path classpath = new Path(project);
+
+ // Jikes doesn't support bootclasspath dir (-bootclasspath)
+ // so we'll emulate it for compatibility and convenience.
+ if (bootclasspath != null) {
+ classpath.append(bootclasspath);
+ }
+
+ // Jikes doesn't support an extension dir (-extdir)
+ // so we'll emulate it for compatibility and convenience.
+ addExtdirsToClasspath(classpath);
+
+ if ( (bootclasspath == null) || (bootclasspath.size() == 0) ) {
+ // no bootclasspath, therefore, get one from the java runtime
+ includeJavaRuntime = true;
+ } else {
+ // there is a bootclasspath stated. By default, the
+ // includeJavaRuntime is false. If the user has stated a
+ // bootclasspath and said to include the java runtime, it's on
+ // their head!
+ }
+ classpath.append(getCompileClasspath());
+
+ // Jikes has no option for source-path so we
+ // will add it to classpath.
+ classpath.append(src);
+
+ // if the user has set JIKESPATH we should add the contents as well
+ String jikesPath = System.getProperty("jikes.class.path");
+ if (jikesPath != null) {
+ classpath.append(new Path(project, jikesPath));
+ }
+
+ Commandline cmd = new Commandline();
+ cmd.setExecutable("jikes");
+
+ 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);
+
+ if (encoding != null) {
+ cmd.createArgument().setValue("-encoding");
+ cmd.createArgument().setValue(encoding);
+ }
+ if (debug) {
+ cmd.createArgument().setValue("-g");
+ }
+ if (optimize) {
+ cmd.createArgument().setValue("-O");
+ }
+ if (verbose) {
+ cmd.createArgument().setValue("-verbose");
+ }
+ if (depend) {
+ cmd.createArgument().setValue("-depend");
+ }
+ /**
+ * XXX
+ * Perhaps we shouldn't use properties for these
+ * three options (emacs mode, warnings and pedantic),
+ * but include it in the javac directive?
+ */
+
+ /**
+ * Jikes has the nice feature to print error
+ * messages in a form readable by emacs, so
+ * that emacs can directly set the cursor
+ * to the place, where the error occured.
+ */
+ String emacsProperty = project.getProperty("build.compiler.emacs");
+ if (emacsProperty != null && Project.toBoolean(emacsProperty)) {
+ cmd.createArgument().setValue("+E");
+ }
+
+ /**
+ * Jikes issues more warnings that javac, for
+ * example, when you have files in your classpath
+ * that don't exist. As this is often the case, these
+ * warning can be pretty annoying.
+ */
+ String warningsProperty = project.getProperty("build.compiler.warnings");
+ if (warningsProperty != null && !Project.toBoolean(warningsProperty)) {
+ cmd.createArgument().setValue("-nowarn");
+ }
+
+ /**
+ * Jikes can issue pedantic warnings.
+ */
+ String pedanticProperty = project.getProperty("build.compiler.pedantic");
+ if (pedanticProperty != null && Project.toBoolean(pedanticProperty)) {
+ cmd.createArgument().setValue("+P");
+ }
+
+ /**
+ * Jikes supports something it calls "full dependency
+ * checking", see the jikes documentation for differences
+ * between -depend and +F.
+ */
+ String fullDependProperty = project.getProperty("build.compiler.fulldepend");
+ if (fullDependProperty != null && Project.toBoolean(fullDependProperty)) {
+ cmd.createArgument().setValue("+F");
+ }
+
+ int firstFileName = cmd.size();
+ logAndAddFilesToCompile(cmd);
+
+ return executeExternalCompile(cmd.getCommandline(), firstFileName) == 0;
+ }
+
+
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/compilers/Jvc.java b/src/main/org/apache/tools/ant/taskdefs/compilers/Jvc.java
new file mode 100644
index 000000000..415b3fb58
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/compilers/Jvc.java
@@ -0,0 +1,134 @@
+/*
+ * 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
+ * .
+ */
+
+package org.apache.tools.ant.taskdefs.compilers;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.*;
+
+/**
+ * The implementation of the jvc compiler from microsoft.
+ * This is primarily a cut-and-paste from the original javac task before it
+ * was refactored.
+ *
+ * @author James Davidson duncan@x180.com
+ * @author Robin Green greenrd@hotmail.com
+ * @author Stefan Bodewig
+ * @author J D Glanville
+ */
+public class Jvc extends DefaultCompilerAdapter {
+
+ public boolean execute() throws BuildException {
+ attributes.log("Using jvc compiler", Project.MSG_VERBOSE);
+
+ Path classpath = new Path(project);
+
+ // jvc doesn't support bootclasspath dir (-bootclasspath)
+ // so we'll emulate it for compatibility and convenience.
+ if (bootclasspath != null) {
+ classpath.append(bootclasspath);
+ }
+
+ // jvc doesn't support an extension dir (-extdir)
+ // so we'll emulate it for compatibility and convenience.
+ addExtdirsToClasspath(classpath);
+
+ if ( (bootclasspath == null) || (bootclasspath.size() == 0) ) {
+ // no bootclasspath, therefore, get one from the java runtime
+ includeJavaRuntime = true;
+ } else {
+ // there is a bootclasspath stated. By default, the
+ // includeJavaRuntime is false. If the user has stated a
+ // bootclasspath and said to include the java runtime, it's on
+ // their head!
+ }
+ classpath.append(getCompileClasspath());
+
+ // jvc has no option for source-path so we
+ // will add it to classpath.
+ classpath.append(src);
+
+ Commandline cmd = new Commandline();
+ cmd.setExecutable("jvc");
+
+ if (destDir != null) {
+ cmd.createArgument().setValue("/d");
+ cmd.createArgument().setFile(destDir);
+ }
+
+ // Add the Classpath before the "internal" one.
+ cmd.createArgument().setValue("/cp:p");
+ cmd.createArgument().setPath(classpath);
+
+ // Enable MS-Extensions and ...
+ cmd.createArgument().setValue("/x-");
+ // ... do not display a Message about this.
+ cmd.createArgument().setValue("/nomessage");
+ // Do not display Logo
+ cmd.createArgument().setValue("/nologo");
+
+ if (debug) {
+ cmd.createArgument().setValue("/g");
+ }
+ if (optimize) {
+ cmd.createArgument().setValue("/O");
+ }
+
+ int firstFileName = cmd.size();
+ logAndAddFilesToCompile(cmd);
+
+ return executeExternalCompile(cmd.getCommandline(), firstFileName) == 0;
+ }
+}
diff --git a/src/main/org/apache/tools/ant/types/Path.java b/src/main/org/apache/tools/ant/types/Path.java
index f9a27a4c3..6241cf198 100644
--- a/src/main/org/apache/tools/ant/types/Path.java
+++ b/src/main/org/apache/tools/ant/types/Path.java
@@ -467,15 +467,25 @@ public class Path extends DataType implements Cloneable {
}
/**
- * Concatenates the system class path in the order specified
- * by the ${build.sysclasspath} property.
+ * Concatenates the system class path in the order specified by
+ * the ${build.sysclasspath} property - using "last" as
+ * default value.
*/
public Path concatSystemClasspath() {
+ return concatSystemClasspath("last");
+ }
+
+ /**
+ * Concatenates the system class path in the order specified by
+ * the ${build.sysclasspath} property - using the supplied value
+ * if ${build.sysclasspath} has not been set.
+ */
+ public Path concatSystemClasspath(String defValue) {
Path result = new Path(project);
String order = project.getProperty("build.sysclasspath");
- if (order == null) order="last";
+ if (order == null) order=defValue;
if (order.equals("only")) {
// only: the developer knows what (s)he is doing
|