Browse Source

<javac> rewritten to use a factory.

Submitted by:	Jay Glanville <jayglanville@home.com>


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268444 13f79535-47bb-0310-9956-ffa450edef68
master
Stefan Bodewig 24 years ago
parent
commit
4ca5683c2a
12 changed files with 1349 additions and 559 deletions
  1. +4
    -0
      WHATSNEW
  2. +18
    -1
      docs/index.html
  3. +1
    -1
      src/main/org/apache/tools/ant/taskdefs/Execute.java
  4. +143
    -554
      src/main/org/apache/tools/ant/taskdefs/Javac.java
  5. +86
    -0
      src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapter.java
  6. +151
    -0
      src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java
  7. +373
    -0
      src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java
  8. +108
    -0
      src/main/org/apache/tools/ant/taskdefs/compilers/Javac12.java
  9. +113
    -0
      src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java
  10. +205
    -0
      src/main/org/apache/tools/ant/taskdefs/compilers/Jikes.java
  11. +134
    -0
      src/main/org/apache/tools/ant/taskdefs/compilers/Jvc.java
  12. +13
    -3
      src/main/org/apache/tools/ant/types/Path.java

+ 4
- 0
WHATSNEW View File

@@ -9,6 +9,10 @@ Changes that could break older environments:

* <perforce> has been replaced by a number of new tasks.

* <javac> is now implemented using a factory. This makes extending
javac to use a new compiler a lot easier but may break custom
versions of this task that rely on the old implementation.

Other changes:
--------------



+ 18
- 1
docs/index.html View File

@@ -3170,7 +3170,12 @@ inclusion/exclusion of files works, and how to write patterns.</p>
<li>jvc (the Command-Line Compiler from Microsoft's SDK for Java /
Visual J++)</li>
</ul>
<p>For JDK 1.1/1.2 is classic the default. For JDK 1.3 is modern the default.</p>
<p>For JDK 1.1/1.2 is classic the default. For JDK 1.3 is modern the default.
If you whish to use a different compiler interface then one of the four
supplied, then write a class that implements the CompilerAdapter interface
(package org.apache.tools.ant.taskdefs.compilers). Supply the full
classname in the &quot;build.compiler&quot; property.
</p>
<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -3284,6 +3289,18 @@ inclusion/exclusion of files works, and how to write patterns.</p>
tracking for compilers that support this (jikes and classic)</td>
<td align="center" valign="top">No</td>
</tr>
<tr>
<td valign="top">includeAntRuntime</td>
<td valign="top">whether or not to include the ant runtime libraries.
Default is no.</td>
<td align="center" valign="top">No</td>
</tr>
<tr>
<td valign="top">includeJavaRuntim</td>
<td valign="top">whether or not to include the default runtime
libraries from the executing virtual machine. Default is no.</td>
<td align="center" valign="top">No</td>
</tr>
<tr>
<td valign="top">failonerror</td> <td valign="top">
If set to false, the build will continue even if there are compilation errors.


+ 1
- 1
src/main/org/apache/tools/ant/taskdefs/Execute.java View File

@@ -355,7 +355,7 @@ public class Execute {
exitValue = value;
}

protected int getExitValue() {
public int getExitValue() {
return exitValue;
}



+ 143
- 554
src/main/org/apache/tools/ant/taskdefs/Javac.java View File

@@ -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.*;
* <li>target
* <li>depend
* <li>vebose
* <li>failonerror
* <li>includeantruntime
* <li>includejavaruntime
* </ul>
* Of these arguments, the <b>sourcedir</b> and <b>destdir</b> are required.
* <p>
@@ -91,16 +92,13 @@ import java.util.*;
* @author James Davidson <a href="mailto:duncan@x180.com">duncan@x180.com</a>
* @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com</a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
*/

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<list.length; i++) {
@@ -340,27 +446,19 @@ public class Javac extends MatchingTask {
}

if (compileList.length > 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 <code>rt.jar</code> or
* <code>classes.zip</code> 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&quot;
*/
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<dirs.length; i++) {
if (!dirs[i].endsWith(File.separator)) {
dirs[i] += File.separator;
}
File dir = project.resolveFile(dirs[i]);
FileSet fs = new FileSet();
fs.setDir(dir);
fs.setIncludes("*");
classpath.addFileset(fs);
}
}

/*
*
* @return true if the compile succeeded
*/
private boolean doJvcCompile() throws BuildException {
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);

classpath.append(getCompileClasspath(true));

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


+ 86
- 0
src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapter.java View File

@@ -0,0 +1,86 @@
/*
* 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.compilers;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.Javac;

/**
* The interface that all compiler adapters must adher to.
*
* <p>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).</p>
*
* @author Jay Dickon Glanville <a href="mailto:jayglanville@home.com">jayglanville@home.com</a>
*/

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

+ 151
- 0
src/main/org/apache/tools/ant/taskdefs/compilers/CompilerAdapterFactory.java View File

@@ -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
* <http://www.apache.org/>.
*/

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 <a href="mailto:jayglanville@home.com">J D Glanville</a>
*/
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:
* <ul><li>jikes = jikes compiler
* <li>classic, javac1.1, javac1.2 = the standard compiler from JDK
* 1.1/1.2
* <li>modern, javac1.3 = the new compiler of JDK 1.3
* <li>jvc, microsoft = the command line compiler from Microsoft's SDK
* for Java / Visual J++
* <li><i>a fully quallified classname</i> = the name of a compiler
* adapter
* </ul>
*
* @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);
}
}

}

+ 373
- 0
src/main/org/apache/tools/ant/taskdefs/compilers/DefaultCompilerAdapter.java View File

@@ -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
* <http://www.apache.org/>.
*/

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 <a href="mailto:duncan@x180.com">duncan@x180.com</a>
* @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com</a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
*/
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&quot;
*/
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<dirs.length; i++) {
if (!dirs[i].endsWith(File.separator)) {
dirs[i] += File.separator;
}
File dir = project.resolveFile(dirs[i]);
FileSet fs = new FileSet();
fs.setDir(dir);
fs.setIncludes("*");
classpath.addFileset(fs);
}
}

}


+ 108
- 0
src/main/org/apache/tools/ant/taskdefs/compilers/Javac12.java View File

@@ -0,0 +1,108 @@
/*
* 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.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 <a href="mailto:duncan@x180.com">duncan@x180.com</a>
* @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com</a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
*/
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);
}
}
}
}

+ 113
- 0
src/main/org/apache/tools/ant/taskdefs/compilers/Javac13.java View File

@@ -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
* <http://www.apache.org/>.
*/

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 <a href="mailto:duncan@x180.com">duncan@x180.com</a>
* @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com</a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
*/
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);
}
}
}

+ 205
- 0
src/main/org/apache/tools/ant/taskdefs/compilers/Jikes.java View File

@@ -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
* <http://www.apache.org/>.
*/

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 <a href="mailto:duncan@x180.com">duncan@x180.com</a>
* @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com</a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
*/
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;
}


}

+ 134
- 0
src/main/org/apache/tools/ant/taskdefs/compilers/Jvc.java View File

@@ -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
* <http://www.apache.org/>.
*/

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 <a href="mailto:duncan@x180.com">duncan@x180.com</a>
* @author Robin Green <a href="mailto:greenrd@hotmail.com">greenrd@hotmail.com</a>
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
* @author <a href="mailto:jayglanville@home.com">J D Glanville</a>
*/
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;
}
}

+ 13
- 3
src/main/org/apache/tools/ant/types/Path.java View File

@@ -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 &quot;last&quot; 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


Loading…
Cancel
Save