git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@277590 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -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 | |||
| =================================== | |||
| @@ -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. </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><arg></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> <javah destdir="c" class="org.foo.bar.Wibble"/></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 © 2001-2002,2004 The Apache Software Foundation. All rights | |||
| <p align="center">Copyright © 2001-2002,2004-2005 The Apache Software Foundation. All rights | |||
| Reserved.</p> | |||
| </body> | |||
| @@ -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> | |||
| @@ -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); | |||
| } | |||
| @@ -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 | |||
| * "niceSourceList" | |||
| */ | |||
| 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 { | |||
| * "niceSourceList" | |||
| */ | |||
| 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:"); | |||
| @@ -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) { | |||
| @@ -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; | |||
| } | |||
| @@ -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); | |||
| } | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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; | |||
| } | |||
| } | |||
| @@ -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()); | |||
| } | |||
| } | |||