Javah Task

## Javah

### Description

Generates JNI headers from a Java class.

When this task executes, it will generate the C header and source files that are needed to implement native methods. JNI operates differently depending on whether JDK 1.2+ or pre-1.2 JDK systems are used.

If you are building with Java 8 or above consider using `javac`'s nativeheaderdir attribute instead which allows you to compile the classes and generate the native header files in a single step.

Note: `javah` has been deprecated in Java 9 and removed in Java 10. Attempts to use it with Java 10 will fail.

It is possible to use different compilers. This can be selected with the implementation attribute or a nested element. Here are the choices of the attribute:

- default—the default compiler for the platform.
- sun—the standard compiler of the JDK.
- kaffeh—the native standard compiler of Kaffe.
- gcjh—the native standard compiler of gcj and gij. Since Apache Ant 1.8.2
- forking—runs the `javah` executable via its command line interface in a separate process. Default when not running on Kaffe or gcj/gij since Ant 1.9.8

Note: if you are using this task to work on multiple files the command line may become too long on some operating systems. Unfortunately the `javah` command doesn't support command argument files the way `javac` (for example) does, so all that can be done is breaking the amount of classes to compile into smaller chunks.

### Parameters

Attribute | Description | Required
--- | --- | ---
class | the fully-qualified name of the class (or classes, separated by commas) | Yes
outputFile | concatenates the resulting header or source files for all the classes listed into this file | Exactly one of the two
destdir | sets the directory where `javah` saves the header files or the stub files.
force | specifies that output files should always be written (JDK 1.2 only) | No
old | specifies that old JDK 1.0-style header files should be generated (otherwise output file contain JNI-style native method function prototypes) (JDK 1.2 only) | No
stubs | generate C declarations from the Java object file (used with old) | No
verbose | causes `javah` to print a message concerning the status of the generated files | No
classpath | the classpath to use | No
bootclasspath | location of bootstrap class files | No
extdirs | location of installed extensions | No
implementation | The compiler implementation to use. (See the above list of valid compilers.) | No; defaults to default compiler for the current JDK

### Parameters specified as nested elements

#### arg

You can specify additional command line arguments for the compiler with nested `<arg>` elements. These elements are specified like Command-line Arguments but have an additional attribute that can be used to enable arguments only if a given compiler implementation will be used.

Attribute | Description | Required
--- | --- | ---
value | See Command-line Arguments. | Exactly one of these
line
file
path
prefix | See Command-line Arguments. Since Ant 1.8. | No
suffix | No
implementation | 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 list of valid compilers.) | No

#### implementationclasspath

Since Ant 1.8.0

A path-like structure holding the classpath to use when loading the compiler implementation if a custom class has been specified. Doesn't have any effect when using one of the built-in compilers.

#### Any nested element of a type that implements JavahAdapter

Since Ant 1.8.0

If a defined type implements the `JavahAdapter` interface a nested element of that type can be used as an alternative to the implementation attribute.

### Examples

    <javah destdir="c" class="org.foo.bar.Wibble"/>

makes a JNI header of the named class, using the JDK 1.2 JNI model. Assuming the directory `c` already exists, the file `org_foo_bar_Wibble.h` is created there. If this file already exists, it is left unchanged.

    <javah outputFile="wibble.h">
      <class name="org.foo.bar.Wibble,org.foo.bar.Bobble"/>
    </javah>

is similar to the previous example, except the output is written to a file called `wibble.h` in the current directory.

    <javah destdir="c" force="yes">
      <class name="org.foo.bar.Wibble"/>
      <class name="org.foo.bar.Bobble"/>
      <class name="org.foo.bar.Tribble"/>
    </javah>

writes three header files, one for each of the classes named. Because the force option is set, these header files are always written when the `Javah` task is invoked, even if they already exist.

    <javah destdir="c" verbose="yes" old="yes" force="yes">
      <class name="org.foo.bar.Wibble"/>
      <class name="org.foo.bar.Bobble"/>
      <class name="org.foo.bar.Tribble"/>
    </javah>
    <javah destdir="c" verbose="yes" stubs="yes" old="yes" force="yes">
      <class name="org.foo.bar.Wibble"/>
      <class name="org.foo.bar.Bobble"/>
      <class name="org.foo.bar.Tribble"/>
    </javah>

writes the headers for the three classes using the 'old' JNI format, then writes the corresponding `.c` stubs. The verbose option will cause `Javah` to describe its progress.

If you want to use a custom `JavahAdapter` `org.example.MyAdapter` you can either use the implementation attribute:

    <javah destdir="c" class="org.foo.bar.Wibble"
           implementation="org.example.MyAdapter"/>

or a define a type and nest this into the task like in:

    <componentdef classname="org.example.MyAdapter"
                  name="myadapter"/>
    <javah destdir="c" class="org.foo.bar.Wibble">
      <myadapter/>
    </javah>

in which case your `javah` adapter can support attributes and nested elements of its own.