Sourceforge Project
Public Forums


In order to generate the C++ code for a Java object the class must meet a few simple requirements. After that, JPeerGen can be run as a javadoc doclet from the command line or within an ANT build script.

Table of contents:

  • Java Class Considerations
    • The peer attribute
    • The peer.return.jni attribute
  • Running the doclet
    • Doclet options
  • Running the doclet in ANT

Java Class Considerations

There are two "modes" under which a class can be peered: fully peered and staticly peered. A fully peered class is one that has a related C++ instance for every Java instance. These instances can then interact back and forth. A staticly peered class is one where the Java class only has static native methods and/or the C++ class only needs to call static peered methods on the Java class.

The peer attribute

In order to facilitate the relationship between a fully peered object and its C++ counterpart, the Java class is required to implement a peer attribute.

private long peer;

The binding code will store the pointer to the C++ instance in this attribute and use it for later peer lookups. It is important that the java code not modify this value in any way.

This is only required if full peering is desired. Classes that only have static native or peered methods need not have this attribute.

The @peered javadoc tag

The @peered javadoc tag is used to designate reverse peering. Any method with this tag defined in its javadoc will have bindings generated for it that make the method easier to call from C++ code.

Example method declaration:

public class MyObject {
    private long peer;

     *  Method for doing something on this object.
     *  @peered
    public int doSomething( String s ) {
        // Do something with s

This will cause a C++ binding to be generated with the following signature:

int MyObject::doSomething( std:string s );

Native code can then call that method directly without worrying about the raw JNI details or string conversion issues, etc..

The @peered.return.jni javadoc tag

This is an alternate way to designate reverse peering that specifies that the return type should not be converted. By default, if a Java method returns an instance of the Java class as a return value then the C++ binding will automatically convert that value.

In some cases, this is not desirable. For example, the native code may need to work directly with the JNI jobject value. Another case is when the class isn't fully peered. The current version of JPeerGen will attempt to generate a conversion even though the peer lookup will fail.

Example method declaration:

public class MyObject {

     *  Method for doing something on this object.
     *  @peered.return.jni
    public static MyObject doSomething( String s ) {
        // Do something with s

This will cause a C++ binding to be generated with the following signature:

static jobject MyObject::doSomething( std:string s );

It is then up to the native code to deal with the jobject value directly.

Running the doclet

JPeerGen needs to be run as a doclet from within javadoc. Following is an example of running the JPeerGen doclet:

javadoc -private -doclet org.progeeks.jni.PeerDoclet src\foo\

The above will generate the various C++ files needed to peer the MyObject class and place them into the current directory.

Source file lists can be specified in all of the usual javadoc ways and all of the non-doclet-specific options on javadoc can be brought to use to specify the doclet classpath, etc.. More on this topic can be read in the javadoc documentation.

Note: it is a good idea to only pass classes to javadoc that actually have some form of peering required. JPeerGen will do its best to determine whether or not an object should be peered, but passing the whole source tree can cause problems if there are Java classes that have native methods that JPeerGen should not be dealing with.

Doclet Options

The JPeerGen doclet defines several options the can be used to customize output. These are as follows:

Option Description
-d <directory> Sets the destination directory for all generated files.

javadoc -private -doclet org.progeeks.jni.PeerDoclet -d src/jni src\foo\
Causes generated C++ files to go into the src/jni sub-directory.
-overwrite Causes files that would normally not be overwritten to be overwritten.
Use this option with caution since it will wipe out any customizations done to the C++ code.
-save Instead of skipping files that would overwrite a user-modifiable file, this option causes the file to be created with the .new extension.

-exclude <comma separated class list> Sets a list of classes to exclude from generation. The value is a comma separated list of fully qualified class names.

javadoc -private -doclet org.progeeks.jni.PeerDoclet -exclude foo.MyOtherObject src\foo\*.java
Causes all classes in the foo package to be passed through JPeerGen except for the foo.MyOtherObject class.

Running the doclet in ANT

Following is a simple example of running the JPeerGen doclet within an ANT build file using ANT's built-in "javadoc" task:

    <javadoc private="true" sourcepath="src/java"
             sourcefiles="foo/,foo/" >
        <doclet name="org.progeeks.jni.PeerDoclet" >
            <param name="-d" value="src/jni" />
            <param name="-save" />

The above task definition will generate any necessary C++ peer files for the classes foo.MyObject and foo.MyOtherObject located in the src/java directory. The generated files will be put into src/jni. If any existing user-modifiable files already exist, new versions will be generated with the .new extension tacked on.

Copyright Paul Speed and Progeeks 2004