Browse Source

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
master
Stefan Bodewig 20 years ago
parent
commit
13b07b313f
11 changed files with 684 additions and 167 deletions
  1. +14
    -2
      WHATSNEW
  2. +61
    -1
      docs/manual/OptionalTasks/javah.html
  3. +47
    -0
      src/etc/testcases/taskdefs/optional/javah/build.xml
  4. +25
    -0
      src/etc/testcases/taskdefs/optional/javah/input/org/example/Foo.java
  5. +152
    -163
      src/main/org/apache/tools/ant/taskdefs/optional/Javah.java
  6. +1
    -1
      src/main/org/apache/tools/ant/taskdefs/optional/Native2Ascii.java
  7. +34
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapter.java
  8. +96
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java
  9. +90
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/javah/Kaffeh.java
  10. +120
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/javah/SunJavah.java
  11. +44
    -0
      src/testcases/org/apache/tools/ant/taskdefs/optional/JavahTest.java

+ 14
- 2
WHATSNEW View File

@@ -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
===================================



+ 61
- 1
docs/manual/OptionalTasks/javah.html View File

@@ -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>



+ 47
- 0
src/etc/testcases/taskdefs/optional/javah/build.xml View File

@@ -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>

+ 25
- 0
src/etc/testcases/taskdefs/optional/javah/input/org/example/Foo.java View File

@@ -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);

}

+ 152
- 163
src/main/org/apache/tools/ant/taskdefs/optional/Javah.java View File

@@ -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() {
@@ -109,6 +116,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.
@@ -117,6 +146,15 @@ public class Javah extends Task {
this.destDir = destDir;
}

/**
* The destination directory, if any.
*
* @since Ant 1.6.3
*/
public File getDestdir() {
return destDir;
}

/**
* the classpath to use.
*/
@@ -146,6 +184,15 @@ public class Javah extends Task {
createClasspath().setRefid(r);
}

/**
* The classpath to use.
*
* @since Ant 1.6.3
*/
public Path getClasspath() {
return classpath;
}

/**
* location of bootstrap class files.
*/
@@ -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
@@ -205,6 +239,15 @@ public class Javah extends Task {
this.outputFile = outputFile;
}

/**
* 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).
*/
@@ -212,6 +255,15 @@ public class Javah extends Task {
this.force = force;
}

/**
* 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.
@@ -221,6 +273,15 @@ public class Javah extends Task {
this.old = old;
}

/**
* 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).
*/
@@ -228,6 +289,15 @@ public class Javah extends Task {
this.stubs = stubs;
}

/**
* 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.
@@ -236,6 +306,51 @@ public class Javah extends Task {
this.verbose = verbose;
}

/**
* 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
*
@@ -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:");


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

@@ -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) {


+ 34
- 0
src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapter.java View File

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

+ 96
- 0
src/main/org/apache/tools/ant/taskdefs/optional/javah/JavahAdapterFactory.java View File

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

+ 90
- 0
src/main/org/apache/tools/ant/taskdefs/optional/javah/Kaffeh.java View File

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

}

+ 120
- 0
src/main/org/apache/tools/ant/taskdefs/optional/javah/SunJavah.java View File

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

}

+ 44
- 0
src/testcases/org/apache/tools/ant/taskdefs/optional/JavahTest.java View File

@@ -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());
}

}

Loading…
Cancel
Save