summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Bodewig <bodewig@apache.org>2005-02-04 08:08:07 +0000
committerStefan Bodewig <bodewig@apache.org>2005-02-04 08:08:07 +0000
commit13b07b313fdc7ab2620f71517ab16698be496f24 (patch)
treedffe24d8241ccc5f36067cf53a425ebaa6c882b2
parent5ffacddada00339f7c26549ff306e1d4fa04fc41 (diff)
downloadant-13b07b313fdc7ab2620f71517ab16698be496f24.tar.gz
Make javah a facade task, support kaffeh
git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@277590 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--WHATSNEW16
-rw-r--r--docs/manual/OptionalTasks/javah.html62
-rw-r--r--src/etc/testcases/taskdefs/optional/javah/build.xml47
-rw-r--r--src/etc/testcases/taskdefs/optional/javah/input/org/example/Foo.java25
-rwxr-xr-xsrc/main/org/apache/tools/ant/taskdefs/optional/Javah.java315
-rw-r--r--src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java2
-rw-r--r--src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapter.java34
-rw-r--r--src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java96
-rw-r--r--src/main/org/apache/tools/ant/taskdefs/optional/javah/Kaffeh.java90
-rw-r--r--src/main/org/apache/tools/ant/taskdefs/optional/javah/SunJavah.java120
-rw-r--r--src/testcases/org/apache/tools/ant/taskdefs/optional/JavahTest.java44
11 files changed, 684 insertions, 167 deletions
diff --git a/WHATSNEW b/WHATSNEW
index 2d40a462b..de828fb0e 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -144,7 +144,7 @@ Other changes:
* Added <target> nested elements to <ant> and <antcall> to allow
specification of multiple sub-build targets, which are executed
with a single dependency analysis.
-
+
* Refactored Target invocation into org.apache.tools.ant.Executor
implementations. Bugzilla Reports 21421, 29248.
@@ -203,7 +203,7 @@ Other changes:
* Added length task to get strings' and files' lengths.
-* <native2ascii> now also supports Kaffe's version.
+* <native2ascii> and <javah> now also support Kaffe's versions.
* Recursive token expansion in a filterset can now be disabled by
setting its recurse attribute to false.
@@ -1291,6 +1291,18 @@ Other changes:
clashes of custom tasks
+* <java> and <junit> now support <assertions>, which let you enable
+ and disable Java1.4 assertions on a package or class basis. These
+ only work when fork=true, currently.
+
+* .NET tasks expanded with VB support <vbc> and J#, via <jsharp>,
+ <importtypelib> and <ilasm>. <csc> supports nested <src> types,
+ <defines> for (potentially conditional) definitions, <reference>
+ filesets for references. The executable attribute lets you switch to
+ mono or other implementations -<csc> has been tested with Mono on
+ Linux and OSX.
+
+
Changes from Ant 1.5.3 to Ant 1.5.4
===================================
diff --git a/docs/manual/OptionalTasks/javah.html b/docs/manual/OptionalTasks/javah.html
index 8d06e7f06..0fb005b76 100644
--- a/docs/manual/OptionalTasks/javah.html
+++ b/docs/manual/OptionalTasks/javah.html
@@ -15,6 +15,16 @@ are needed to implement native methods. JNI operates differently depending on
whether <a href="http://java.sun.com/j2se/1.3/docs/tooldocs/win32/javah.html">JDK1.2</a>
(or later) or <a href="http://java.sun.com/products/jdk/1.1/docs/tooldocs/win32/javah.html">pre-JDK1.2</a>
systems are used.</p>
+
+<p>It is possible to use different compilers. This can be selected
+with the <code>implementation</code> attribute. <a
+name="implementationvalues">Here are the choices</a>:</p>
+<ul>
+ <li>default - the default compiler (kaffeh or sun) for the platform.</li>
+ <li>sun (the standard compiler of the JDK)</li>
+ <li>kaffeh (the native standard compiler of <a href="http://www.kaffe.org" target="_top">Kaffe</a>)</li>
+</ul>
+
<h3>Parameters</h3>
<table border="1" cellpadding="2" cellspacing="0">
<tr>
@@ -74,8 +84,58 @@ systems are used.</p>
<td valign="top"> location of installed extensions.</td>
<td valign="top" align="center">No</td>
</tr>
+ <tr>
+ <td valign="top">implementation</td>
+ <td valign="top">The compiler implementation to use. If this
+ attribute is not set, the default compiler for the current VM
+ will be used. (See the above <a
+ href="#implementationvalues">list</a> of valid compilers.)</td>
+ <td align="center" valign="top">No</td>
+ </tr>
</table>
<p>Either outputFile or destdir must be supplied, but not both.&nbsp;</p>
+
+<h3>Parameters specified as nested elements</h3>
+
+<h4>arg</h4>
+
+<p>You can specify additional command line arguments for the compiler
+with nested <code>&lt;arg&gt;</code> elements. These elements are
+specified like <a href="../using.html#arg">Command-line Arguments</a>
+but have an additional attribute that can be used to enable arguments
+only if a given compiler implementation will be used.</p>
+
+<table border="1" cellpadding="2" cellspacing="0">
+<tr>
+ <td width="12%" valign="top"><b>Attribute</b></td>
+ <td width="78%" valign="top"><b>Description</b></td>
+ <td width="10%" valign="top"><b>Required</b></td>
+</tr>
+ <tr>
+ <td valign="top">value</td>
+ <td align="center" rowspan="4">See
+ <a href="../using.html#arg">Command-line Arguments</a>.</td>
+ <td align="center" rowspan="4">Exactly one of these.</td>
+ </tr>
+ <tr>
+ <td valign="top">line</td>
+ </tr>
+ <tr>
+ <td valign="top">file</td>
+ </tr>
+ <tr>
+ <td valign="top">path</td>
+ </tr>
+ <tr>
+ <td valign="top">implementation</td>
+ <td>Only pass the specified argument if the chosen compiler
+ implementation matches the value of this attribute. Legal values
+ are the same as those in the above <a
+ href="#implementationvalues">list</a> of valid compilers.)</td>
+ <td align="center">No</td>
+ </tr>
+</table>
+
<h3>Examples</h3>
<pre> &lt;javah destdir=&quot;c&quot; class=&quot;org.foo.bar.Wibble&quot;/&gt;</pre>
<p>makes a JNI header of the named class, using the JDK1.2 JNI model. Assuming
@@ -110,7 +170,7 @@ writes the corresponding .c stubs. The verbose option will cause Javah to
describe its progress.</p>
<hr>
-<p align="center">Copyright &copy; 2001-2002,2004 The Apache Software Foundation. All rights
+<p align="center">Copyright &copy; 2001-2002,2004-2005 The Apache Software Foundation. All rights
Reserved.</p>
</body>
diff --git a/src/etc/testcases/taskdefs/optional/javah/build.xml b/src/etc/testcases/taskdefs/optional/javah/build.xml
new file mode 100644
index 000000000..e54f218f6
--- /dev/null
+++ b/src/etc/testcases/taskdefs/optional/javah/build.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+
+<!--
+ Copyright 2005 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project default="no">
+
+ <property name="out" location="output"/>
+ <property name="in" location="input"/>
+
+ <target name="no">
+ <fail>For tests only</fail>
+ </target>
+
+ <target name="setUp">
+ <mkdir dir="${out}"/>
+ </target>
+
+ <target name="tearDown">
+ <delete dir="${out}"/>
+ </target>
+
+ <target name="compile" depends="setUp">
+ <javac srcdir="${in}" destdir="${out}"/>
+ </target>
+
+ <target name="simple-compile" depends="compile">
+ <javah destdir="${out}">
+ <class name="org.example.Foo"/>
+ <classpath>
+ <pathelement location="${out}"/>
+ </classpath>
+ </javah>
+ </target>
+</project>
diff --git a/src/etc/testcases/taskdefs/optional/javah/input/org/example/Foo.java b/src/etc/testcases/taskdefs/optional/javah/input/org/example/Foo.java
new file mode 100644
index 000000000..e0e4f0535
--- /dev/null
+++ b/src/etc/testcases/taskdefs/optional/javah/input/org/example/Foo.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.example;
+
+public class Foo {
+
+ public Foo() {}
+
+ public native String bar(Object baz);
+
+}
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/Javah.java b/src/main/org/apache/tools/ant/taskdefs/optional/Javah.java
index 48b866543..a68f1f445 100755
--- a/src/main/org/apache/tools/ant/taskdefs/optional/Javah.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/Javah.java
@@ -18,18 +18,21 @@
package org.apache.tools.ant.taskdefs.optional;
import java.io.File;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
+import java.util.ArrayList;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.Vector;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
+import org.apache.tools.ant.taskdefs.optional.javah.JavahAdapter;
+import org.apache.tools.ant.taskdefs.optional.javah.JavahAdapterFactory;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.util.JavaEnvUtils;
+import org.apache.tools.ant.util.facade.FacadeTaskHelper;
+import org.apache.tools.ant.util.facade.ImplementationSpecificArgument;
/**
* Generates JNI header files using javah.
@@ -76,6 +79,11 @@ public class Javah extends Task {
private Path bootclasspath;
//private Path extdirs;
private static String lSep = System.getProperty("line.separator");
+ private FacadeTaskHelper facade = null;
+
+ public Javah() {
+ facade = new FacadeTaskHelper(JavahAdapterFactory.getDefault());
+ }
/**
* the fully-qualified name of the class (or classes, separated by commas).
@@ -101,7 +109,6 @@ public class Javah extends Task {
public void setName(String name) {
this.name = name;
- log("ClassArgument.name=" + name);
}
public String getName() {
@@ -110,6 +117,28 @@ public class Javah extends Task {
}
/**
+ * Names of the classes to process.
+ *
+ * @since Ant 1.6.3
+ */
+ public String[] getClasses() {
+ ArrayList al = new ArrayList();
+ if (cls != null) {
+ StringTokenizer tok = new StringTokenizer(cls, ",", false);
+ while (tok.hasMoreTokens()) {
+ al.add(tok.nextToken().trim());
+ }
+ }
+
+ Enumeration e = classes.elements();
+ while (e.hasMoreElements()) {
+ ClassArgument arg = (ClassArgument) e.nextElement();
+ al.add(arg.getName());
+ }
+ return (String[]) al.toArray(new String[0]);
+ }
+
+ /**
* Set the destination directory into which the Java source
* files should be compiled.
*/
@@ -118,6 +147,15 @@ public class Javah extends Task {
}
/**
+ * The destination directory, if any.
+ *
+ * @since Ant 1.6.3
+ */
+ public File getDestdir() {
+ return destDir;
+ }
+
+ /**
* the classpath to use.
*/
public void setClasspath(Path src) {
@@ -147,6 +185,15 @@ public class Javah extends Task {
}
/**
+ * The classpath to use.
+ *
+ * @since Ant 1.6.3
+ */
+ public Path getClasspath() {
+ return classpath;
+ }
+
+ /**
* location of bootstrap class files.
*/
public void setBootclasspath(Path src) {
@@ -175,27 +222,14 @@ public class Javah extends Task {
createBootclasspath().setRefid(r);
}
- ///**
- // * Sets the extension directories that will be used during the
- // * compilation.
- // */
- //public void setExtdirs(Path extdirs) {
- // if (this.extdirs == null) {
- // this.extdirs = extdirs;
- // } else {
- // this.extdirs.append(extdirs);
- // }
- //}
-
- ///**
- // * Maybe creates a nested classpath element.
- // */
- //public Path createExtdirs() {
- // if (extdirs == null) {
- // extdirs = new Path(project);
- // }
- // return extdirs.createPath();
- //}
+ /**
+ * The bootclasspath to use.
+ *
+ * @since Ant 1.6.3
+ */
+ public Path getBootclasspath() {
+ return bootclasspath;
+ }
/**
* Concatenates the resulting header or source files for all
@@ -206,6 +240,15 @@ public class Javah extends Task {
}
/**
+ * The destination file, if any.
+ *
+ * @since Ant 1.6.3
+ */
+ public File getOutputfile() {
+ return outputFile;
+ }
+
+ /**
* If true, output files should always be written (JDK1.2 only).
*/
public void setForce(boolean force) {
@@ -213,6 +256,15 @@ public class Javah extends Task {
}
/**
+ * Whether output files should always be written.
+ *
+ * @since Ant 1.6.3
+ */
+ public boolean getForce() {
+ return force;
+ }
+
+ /**
* If true, specifies that old JDK1.0-style header files should be
* generated.
* (otherwise output file contain JNI-style native method function prototypes) (JDK1.2 only)
@@ -222,6 +274,15 @@ public class Javah extends Task {
}
/**
+ * Whether old JDK1.0-style header files should be generated.
+ *
+ * @since Ant 1.6.3
+ */
+ public boolean getOld() {
+ return old;
+ }
+
+ /**
* If true, generate C declarations from the Java object file (used with old).
*/
public void setStubs(boolean stubs) {
@@ -229,6 +290,15 @@ public class Javah extends Task {
}
/**
+ * Whether C declarations from the Java object file should be generated.
+ *
+ * @since Ant 1.6.3
+ */
+ public boolean getStubs() {
+ return stubs;
+ }
+
+ /**
* If true, causes Javah to print a message concerning
* the status of the generated files.
*/
@@ -237,6 +307,51 @@ public class Javah extends Task {
}
/**
+ * Whether verbose output should get generated.
+ *
+ * @since Ant 1.6.3
+ */
+ public boolean getVerbose() {
+ return verbose;
+ }
+
+ /**
+ * Choose the implementation for this particular task.
+ * @param impl the name of the implemenation
+ * @since Ant 1.6.3
+ */
+ public void setImplementation(String impl) {
+ if ("default".equals(impl)) {
+ facade.setImplementation(JavahAdapterFactory.getDefault());
+ } else {
+ facade.setImplementation(impl);
+ }
+ }
+
+ /**
+ * Adds an implementation specific command-line argument.
+ * @return a ImplementationSpecificArgument to be configured
+ *
+ * @since Ant 1.6.3
+ */
+ public ImplementationSpecificArgument createArg() {
+ ImplementationSpecificArgument arg =
+ new ImplementationSpecificArgument();
+ facade.addImplementationArgument(arg);
+ return arg;
+ }
+
+ /**
+ * Returns the (implementation specific) settings given as nested
+ * arg elements.
+ *
+ * @since Ant 1.6.3
+ */
+ public String[] getCurrentArgs() {
+ return facade.getArgs();
+ }
+
+ /**
* Execute the task
*
* @throws BuildException is there is a problem in the task execution.
@@ -271,132 +386,20 @@ public class Javah extends Task {
classpath = classpath.concatSystemClasspath("ignore");
}
- /* unused.
- TODO: If anyone cannot come up with a reason for this, lets delete it
-
- String compiler = getProject().getProperty("build.compiler");
- if (compiler == null) {
- if (!JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)
- && !JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_2)) {
- compiler = "modern";
- } else {
- compiler = "classic";
- }
+ JavahAdapter ad =
+ JavahAdapterFactory.getAdapter(facade.getImplementation(),
+ this);
+ if (!ad.compile(this)) {
+ throw new BuildException("compilation failed");
}
- */
- doClassicCompile();
}
- // XXX
- // we need a way to not use the current classpath.
-
/**
- * Performs a compile using the classic compiler that shipped with
- * JDK 1.1 and 1.2.
- */
-
- private void doClassicCompile() throws BuildException {
- Commandline cmd = setupJavahCommand();
-
- // 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 {
- Class javahMainClass = null;
- try {
- // first search for the "old" javah class in 1.4.2 tools.jar
- javahMainClass = Class.forName("com.sun.tools.javah.oldjavah.Main");
- } catch (ClassNotFoundException cnfe) {
- // assume older than 1.4.2 tools.jar
- javahMainClass = Class.forName("com.sun.tools.javah.Main");
- }
-
- // now search for the constructor that takes in String[] arguments.
- Class[] strings = new Class[] {String[].class};
- Constructor constructor = javahMainClass.getConstructor(strings);
-
- // construct the javah Main instance
- Object javahMain = constructor.newInstance(new Object[] {cmd.getArguments()});
-
- // find the run method
- Method runMethod = javahMainClass.getMethod("run", new Class[0]);
-
- runMethod.invoke(javahMain, new Object[0]);
- } catch (Exception ex) {
- if (ex instanceof BuildException) {
- throw (BuildException) ex;
- } else {
- throw new BuildException("Error starting javah: " + ex, ex, getLocation());
- }
- }
- }
-
- /**
- * Does the command line argument processing common to classic and
- * modern.
+ * Logs the compilation parameters, adds the files to compile and logs the
+ * &quot;niceSourceList&quot;
*/
- private Commandline setupJavahCommand() {
- Commandline cmd = new Commandline();
-
- if (destDir != null) {
- cmd.createArgument().setValue("-d");
- cmd.createArgument().setFile(destDir);
- }
-
- if (outputFile != null) {
- cmd.createArgument().setValue("-o");
- cmd.createArgument().setFile(outputFile);
- }
-
- if (classpath != null) {
- cmd.createArgument().setValue("-classpath");
- cmd.createArgument().setPath(classpath);
- }
-
- // JDK1.1 is rather simpler than JDK1.2
- if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) {
- if (verbose) {
- cmd.createArgument().setValue("-v");
- }
- } else {
- if (verbose) {
- cmd.createArgument().setValue("-verbose");
- }
- if (old) {
- cmd.createArgument().setValue("-old");
- }
- if (force) {
- cmd.createArgument().setValue("-force");
- }
- }
-
- if (stubs) {
- if (!old) {
- throw new BuildException("stubs only available in old mode.", getLocation());
- }
- cmd.createArgument().setValue("-stubs");
- }
- Path bcp = new Path(getProject());
- if (bootclasspath != null) {
- bcp.append(bootclasspath);
- }
- bcp = bcp.concatSystemBootClasspath("ignore");
- if (bcp.size() > 0) {
- cmd.createArgument().setValue("-bootclasspath");
- cmd.createArgument().setPath(bcp);
- }
-
+ public void logAndAddFiles(Commandline cmd) {
logAndAddFilesToCompile(cmd);
- return cmd;
}
/**
@@ -404,32 +407,18 @@ public class Javah extends Task {
* &quot;niceSourceList&quot;
*/
protected void logAndAddFilesToCompile(Commandline cmd) {
- int n = 0;
log("Compilation " + cmd.describeArguments(),
Project.MSG_VERBOSE);
StringBuffer niceClassList = new StringBuffer();
- if (cls != null) {
- StringTokenizer tok = new StringTokenizer(cls, ",", false);
- while (tok.hasMoreTokens()) {
- String aClass = tok.nextToken().trim();
- cmd.createArgument().setValue(aClass);
- niceClassList.append(" " + aClass + lSep);
- n++;
- }
- }
-
- Enumeration e = classes.elements();
- while (e.hasMoreElements()) {
- ClassArgument arg = (ClassArgument) e.nextElement();
- String aClass = arg.getName();
- cmd.createArgument().setValue(aClass);
- niceClassList.append(" " + aClass + lSep);
- n++;
+ String[] c = getClasses();
+ for (int i = 0; i < c.length; i++) {
+ cmd.createArgument().setValue(c[i]);
+ niceClassList.append(" " + c[i] + lSep);
}
StringBuffer prefix = new StringBuffer("Class");
- if (n > 1) {
+ if (c.length > 1) {
prefix.append("es");
}
prefix.append(" to be compiled:");
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java b/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java
index 8ed26974e..35de85408 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java
@@ -123,7 +123,7 @@ public class Native2Ascii extends MatchingTask {
/**
* Choose the implementation for this particular task.
- * @param compiler the name of the compiler
+ * @param impl the name of the implemenation
* @since Ant 1.6.3
*/
public void setImplementation(String impl) {
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapter.java b/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapter.java
new file mode 100644
index 000000000..4891eb80c
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapter.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tools.ant.taskdefs.optional.javah;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.optional.Javah;
+
+/**
+ * Interface for different backend implementations of the Javah task.
+ *
+ * @since Ant 1.6.3
+ */
+public interface JavahAdapter {
+ /**
+ * Performs the actual compilation.
+ *
+ * @since Ant 1.6.3
+ */
+ boolean compile(Javah javah) throws BuildException;
+} \ No newline at end of file
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java b/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java
new file mode 100644
index 000000000..9f3dff458
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.javah;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * Creates the JavahAdapter based on the user choice and
+ * potentially the VM vendor.
+ *
+ * @since Ant 1.6.3
+ */
+public class JavahAdapterFactory {
+
+ /**
+ * Determines the default choice of adapter based on the VM
+ * vendor.
+ *
+ * @return the default choice of adapter based on the VM
+ * vendor
+ */
+ public static String getDefault() {
+ if (JavaEnvUtils.isKaffe()) {
+ return Kaffeh.IMPLEMENTATION_NAME;
+ }
+ return SunJavah.IMPLEMENTATION_NAME;
+ }
+
+ /**
+ * Creates the JavahAdapter based on the user choice and
+ * potentially the VM vendor.
+ *
+ * @param choice the user choice (if any).
+ * @param log a ProjectComponent instance used to access Ant's
+ * logging system.
+ * @return The adapter to use.
+ */
+ public static JavahAdapter getAdapter(String choice,
+ ProjectComponent log)
+ throws BuildException {
+ if ((JavaEnvUtils.isKaffe() && choice == null)
+ || Kaffeh.IMPLEMENTATION_NAME.equals(choice)) {
+ return new Kaffeh();
+ } else if (SunJavah.IMPLEMENTATION_NAME.equals(choice)) {
+ return new SunJavah();
+ } else if (choice != null) {
+ return resolveClassName(choice);
+ }
+
+ // This default has been good enough until Ant 1.6.3, so stick
+ // with it
+ return new SunJavah();
+ }
+
+ /**
+ * Tries to resolve the given classname into a native2ascii 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 JavahAdapter.
+ */
+ private static JavahAdapter resolveClassName(String className)
+ throws BuildException {
+ try {
+ Class c = Class.forName(className);
+ Object o = c.newInstance();
+ return (JavahAdapter) o;
+ } catch (ClassNotFoundException cnfe) {
+ throw new BuildException("Can't load " + className, cnfe);
+ } catch (ClassCastException cce) {
+ throw new BuildException(className
+ + " is not a Javah adapter", cce);
+ } catch (Throwable t) {
+ // for all other possibilities
+ throw new BuildException(className + " caused an interesting "
+ + "exception.", t);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/javah/Kaffeh.java b/src/main/org/apache/tools/ant/taskdefs/optional/javah/Kaffeh.java
new file mode 100644
index 000000000..5ed3d3c73
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/javah/Kaffeh.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.javah;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.Execute;
+import org.apache.tools.ant.taskdefs.optional.Javah;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * Adapter to the native kaffeh compiler.
+ *
+ * @since Ant 1.6.3
+ */
+public class Kaffeh implements JavahAdapter {
+
+ public static final String IMPLEMENTATION_NAME = "kaffeh";
+
+ /**
+ * Performs the actual compilation.
+ *
+ * @since Ant 1.6.3
+ */
+ public boolean compile(Javah javah) throws BuildException {
+ Commandline cmd = setupKaffehCommand(javah);
+ try {
+ Execute.runCommand(javah, cmd.getCommandline());
+ return true;
+ } catch (BuildException e) {
+ if (e.getMessage().indexOf("failed with return code") == -1) {
+ throw e;
+ }
+ }
+ return false;
+ }
+
+ private Commandline setupKaffehCommand(Javah javah) {
+ Commandline cmd = new Commandline();
+ cmd.setExecutable(JavaEnvUtils.getJdkExecutable("kaffeh"));
+
+ if (javah.getDestdir() != null) {
+ cmd.createArgument().setValue("-d");
+ cmd.createArgument().setFile(javah.getDestdir());
+ }
+
+ if (javah.getOutputfile() != null) {
+ cmd.createArgument().setValue("-o");
+ cmd.createArgument().setFile(javah.getOutputfile());
+ }
+
+ Path cp = new Path(javah.getProject());
+ if (javah.getBootclasspath() != null) {
+ cp.append(javah.getBootclasspath());
+ }
+ cp = cp.concatSystemBootClasspath("ignore");
+ if (javah.getClasspath() != null) {
+ cp.append(javah.getClasspath());
+ }
+ if (cp.size() > 0) {
+ cmd.createArgument().setValue("-classpath");
+ cmd.createArgument().setPath(cp);
+ }
+
+ if (!javah.getOld()) {
+ cmd.createArgument().setValue("-jni");
+ }
+
+ cmd.addArguments(javah.getCurrentArgs());
+
+ javah.logAndAddFiles(cmd);
+ return cmd;
+ }
+
+} \ No newline at end of file
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/javah/SunJavah.java b/src/main/org/apache/tools/ant/taskdefs/optional/javah/SunJavah.java
new file mode 100644
index 000000000..b6faf36af
--- /dev/null
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/javah/SunJavah.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional.javah;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.taskdefs.ExecuteJava;
+import org.apache.tools.ant.taskdefs.optional.Javah;
+import org.apache.tools.ant.types.Commandline;
+import org.apache.tools.ant.types.Path;
+import org.apache.tools.ant.util.JavaEnvUtils;
+
+/**
+ * Adapter to com.sun.tools.javah.oldjavah.Main or com.sun.tools.javah.Main.
+ *
+ * @since Ant 1.6.3
+ */
+public class SunJavah implements JavahAdapter {
+
+ public static final String IMPLEMENTATION_NAME = "sun";
+
+ /**
+ * Performs the actual compilation.
+ *
+ * @since Ant 1.6.3
+ */
+ public boolean compile(Javah javah) throws BuildException {
+ Commandline cmd = setupJavahCommand(javah);
+ ExecuteJava ej = new ExecuteJava();
+
+ try {
+ try {
+ // first search for the "old" javah class in 1.4.2 tools.jar
+ Class.forName("com.sun.tools.javah.oldjavah.Main");
+ cmd.setExecutable("com.sun.tools.javah.oldjavah.Main");
+ } catch (ClassNotFoundException cnfe) {
+ // assume older than 1.4.2 tools.jar
+ Class.forName("com.sun.tools.javah.Main");
+ cmd.setExecutable("com.sun.tools.javah.Main");
+ }
+ } catch (ClassNotFoundException ex) {
+ throw new BuildException("Can't load javah", ex,
+ javah.getLocation());
+ }
+ ej.setJavaCommand(cmd);
+ return ej.fork(javah) == 0;
+ }
+
+ private Commandline setupJavahCommand(Javah javah) {
+ Commandline cmd = new Commandline();
+
+ if (javah.getDestdir() != null) {
+ cmd.createArgument().setValue("-d");
+ cmd.createArgument().setFile(javah.getDestdir());
+ }
+
+ if (javah.getOutputfile() != null) {
+ cmd.createArgument().setValue("-o");
+ cmd.createArgument().setFile(javah.getOutputfile());
+ }
+
+ if (javah.getClasspath() != null) {
+ cmd.createArgument().setValue("-classpath");
+ cmd.createArgument().setPath(javah.getClasspath());
+ }
+
+ // JDK1.1 is rather simpler than JDK1.2
+ if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) {
+ if (javah.getVerbose()) {
+ cmd.createArgument().setValue("-v");
+ }
+ } else {
+ if (javah.getVerbose()) {
+ cmd.createArgument().setValue("-verbose");
+ }
+ if (javah.getOld()) {
+ cmd.createArgument().setValue("-old");
+ }
+ if (javah.getForce()) {
+ cmd.createArgument().setValue("-force");
+ }
+ if (javah.getStubs() && !javah.getOld()) {
+ throw new BuildException("stubs only available in old mode.",
+ javah.getLocation());
+ }
+ }
+
+ if (javah.getStubs()) {
+ cmd.createArgument().setValue("-stubs");
+ }
+ Path bcp = new Path(javah.getProject());
+ if (javah.getBootclasspath() != null) {
+ bcp.append(javah.getBootclasspath());
+ }
+ bcp = bcp.concatSystemBootClasspath("ignore");
+ if (bcp.size() > 0) {
+ cmd.createArgument().setValue("-bootclasspath");
+ cmd.createArgument().setPath(bcp);
+ }
+
+ cmd.addArguments(javah.getCurrentArgs());
+
+ javah.logAndAddFiles(cmd);
+ return cmd;
+ }
+
+} \ No newline at end of file
diff --git a/src/testcases/org/apache/tools/ant/taskdefs/optional/JavahTest.java b/src/testcases/org/apache/tools/ant/taskdefs/optional/JavahTest.java
new file mode 100644
index 000000000..8148e9123
--- /dev/null
+++ b/src/testcases/org/apache/tools/ant/taskdefs/optional/JavahTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.tools.ant.taskdefs.optional;
+
+import org.apache.tools.ant.BuildFileTest;
+
+public class JavahTest extends BuildFileTest {
+
+ private final static String BUILD_XML =
+ "src/etc/testcases/taskdefs/optional/javah/build.xml";
+
+ public JavahTest(String name) {
+ super(name);
+ }
+
+ public void setUp() {
+ configureProject(BUILD_XML);
+ }
+
+ public void tearDown() {
+ executeTarget("tearDown");
+ }
+
+ public void testSimpleCompile() {
+ executeTarget("simple-compile");
+ assertTrue(getProject().resolveFile("output/org_example_Foo.h")
+ .exists());
+ }
+
+} \ No newline at end of file