Documentation
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
- 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\MyObject.java
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.
Example:
javadoc -private -doclet org.progeeks.jni.PeerDoclet -d src/jni src\foo\MyObject.java
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.
Example:
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/MyObject.java,foo/MyOtherObject.java" >
<doclet name="org.progeeks.jni.PeerDoclet" >
<param name="-d" value="src/jni" />
<param name="-save" />
</doclet>
</javadoc>
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
|