ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From <Jan.Mate...@rzf.fin-nrw.de>
Subject AW: Writing new task: javani
Date Wed, 28 Apr 2010 10:35:05 GMT
If you have much in common with javah, you should have a look at <javah> task.
http://ant.apache.org/manual/OptionalTasks/javah.html

Maybe you could reuse some of its code.


Jan 

>-----Urspr√ľngliche Nachricht-----
>Von: Mark Bednarczyk [mailto:voytechs@yahoo.com] 
>Gesendet: Mittwoch, 28. April 2010 10:49
>An: Materne, Jan (RZF); dev@ant.apache.org
>Betreff: RE: Writing new task: javani
>
>Hi Jan,
>	thanks for pointing that out.
>
>I couldn't find any ANT tasks that generate C wrapper 
>functions, have no
>additional runtime requirements and allow custom JNI to java 
>peering/binding
>implementation.
>
>There is one project JNI++ which I have looked at before. It's targeted
>toward C++ environments and has a runtime dependency on JNI++ runtime
>library. It's a powerful full-feature library, but overkill 
>for my project
>needs.
>
>My project utilizes a custom JNI to java peering/binding for 
>performance
>reasons. JNI++ kind of forces you into its own implementation 
>of it. You can
>work around it but it defeats the purpose of using something as
>comprehensive as JNI++.
>
>I am looking for a simple C based JNI/java preprocessor, 
>classfile wrapper
>generator. The task 'javani', modeled after existing 'javah' 
>task, fits in
>about 20Kb jar file and has no dependencies (at build or runtime). It
>generates straight forward C function wrappers and has tiny 
>amount of static
>memory overhead per classfile when a classfile is first loaded by a
>ClassLoader. The java/JNI binding/peering implementation, 
>which is where
>most of the complexity is typically found, ateast for a 
>library developer
>like myself, is left up to the user.
>
>I'd love to be able to use an existing ANT task for this and 
>have someone
>else maintain the code. However I am willing to implement 'javani' if I
>can't find a suitable alternative and ANT project wants my code.
>
>May be from ANT's perspective, the proper course would be to 
>enhance 'javah'
>task. Its currently a wrapper around java SDK tool 'javah'. 
>It's a task that
>setup the environment for the external tool to be called. 
>Works very well
>and I use it heavily.  We could however enhance it with a code 
>generator to
>generate newer JNI 1.4 level stubs (which javah executable does not
>support), but also generate wrapper functions for classfiles? 
>At minimum, it
>would certainly make sense for 'javani' to match the 'javah' 
>parameter names
>and behavior as much as possible.
>
>Cheers,
>mark...
>
>> -----Original Message-----
>> From: Jan.Materne@rzf.fin-nrw.de [mailto:Jan.Materne@rzf.fin-nrw.de]
>> Sent: Wednesday, April 28, 2010 2:29 AM
>> To: dev@ant.apache.org; voytechs@yahoo.com
>> Subject: AW: Writing new task: javani
>>
>> http://ant.apache.org/external.html lists a lot of tasks
>> including preprocessors and jni utilities.
>>
>> Jan
>>
>> >-----Urspr√ľngliche Nachricht-----
>> >Von: Mark Bednarczyk [mailto:voytechs@yahoo.com]
>> >Gesendet: Dienstag, 27. April 2010 18:04
>> >An: dev@ant.apache.org
>> >Betreff: Writing new task: javani
>> >
>> >I'm writing a new task "javani" and want to see if there was any
>> >duplicate effort with what I'm proposing.
>> >
>> >Summary:
>> >The task named 'javani' is a java preprocessor for
>> generating wrapper
>> >functions in C. Its input is a compiled java classfile, and
>> its output
>> >either a C or header file to be compiled, or both. The task
>> expands on
>> >what existing 'javah' task performs by generating C wrapper
>> functions
>> >which automate some common tasks usually performed manually
>> using JNI C
>> >programming interface.
>> >
>> >The task can generate source C code (both C and header files), which
>> >needs to be further compiled by a C compiler. The task can be
>> >instructed to generate 2 types of output:
>> >
>> >1) A header file, which provides C declarations for
>> functions and JNI
>> >to java mappings
>> >
>> >2) A C source file containing wrapper functions which can be used to
>> >call on any java method from C. The code generator takes care of
>> >maintaining/caching JNI method and field IDs.
>> >
>> >Typically stub and wrapper C functions do not mix and are
>> thus output
>> >to different C files. Stub files only need to be generated
>> once, while
>> >wrapper functions can be regenerated every time ant build
>> compiles the
>> >code.
>> >
>> >Easily create wrapper functions for any java class
>> (including standard
>> >JRE classes). This saves the time of trying to manually lookup and
>> >cache JNI field and method IDs.  You call on C functions
>> only supplying
>> >the JNIEnv and jobject or jclass parameters and any other parameters
>> >declared in the java method signature.
>> >
>> >Here is an example java class:
>> >
>> >package org.jnetsoft.jni.stub;
>> >public class MyClass {
>> >  public void method1() { }
>> >  public int method2(char c, byte b, short s, int i, long l, String
>> >str) {return 0;}
>> >  private int field1;
>> >}
>> >
>> >And wrapper functions generated:
>> >---------------------------------------------------------------
>> >-----------
>> >#include <jni.h>
>> >#include "org_jnetsoft_jni_stub_MyClass.h"
>> >
>> >org_jnetsoft_jni_stub_MyClass_class_t
>> >org_jnetsoft_jni_stub_MyClass_class;
>> >
>> >/*
>> > * Class:     org.jnetsoft.jni.stub.MyClass
>> > * Method:    onClassLoad
>> > * Signature: ()V
>> > */
>> >JNIEXPORT void JNICALL 
>Java_org_jnetsoft_jni_stub_MyClass_onClassLoad
>> >  (JNIEnv *env, jclass clazz) {
>> >
>> >	org_jnetsoft_jni_stub_MyClass_class_t *c =
>> >&org_jnetsoft_jni_stub_MyClass_class;
>> >
>> >	memset(c, sizeof(org_jnetsoft_jni_stub_MyClass_class_t), 0);
>> >
>> >	c->clazz = (*env)->NewGlobalRef(env, clazz);
>> >
>> >	c->method1	= (*env)->GetMethodID(env, clazz,
>> >"method1", "()V");
>> >	c->method2	= (*env)->GetMethodID(env, clazz, "method2",
>> >"(CBSIJLjava/lang/String;)I");
>> >
>> >	c->field1	= (*env)->GetFieldID(env, clazz, "field1", "I");
>> >}
>> >
>> >/*
>> > * Class:     org.jnetsoft.jni.stub.MyClass
>> > * Method:    onClassUnload
>> > * Signature: ()V
>> > */
>> >JNIEXPORT void JNICALL
>> Java_org_jnetsoft_jni_stub_MyClass_onClassUnload
>> >  (JNIEnv *env, jclass clazz) {
>> >
>> >	org_jnetsoft_jni_stub_MyClass_class_t *c =
>> >&org_jnetsoft_jni_stub_MyClass_class;
>> >
>> >	(*env)->DeleteGlobalRef(env, c->clazz); }
>> >
>> >/*
>> > * Class:     org.jnetsoft.jni.stub.MyClass
>> > * Method:    method1
>> > * Types:     ()
>> > * Signature: ()V
>> > */
>> >void org_jnetsoft_jni_stub_MyClass_method1
>> >  (JNIEnv *env, jobject obj) {
>> >	(*env)->CallVoidMethod(env, obj,
>> >org_jnetsoft_jni_stub_MyClass_class.method1);
>> >}
>> >
>> >/*
>> > * Class:     org.jnetsoft.jni.stub.MyClass
>> > * Method:    method2
>> > * Types:     (char, byte, short, int, long, String, )
>> > * Signature: (CBSIJLjava/lang/String;)I  */ jint
>> >org_jnetsoft_jni_stub_MyClass_method2
>> >  (JNIEnv *env, jobject obj, jchar arg1, jbyte arg2, jshort
>> arg3, jint
>> >arg4, jlong arg6, jobject arg7) {
>> >	return (*env)->CallIntMethod(env, obj,
>> >org_jnetsoft_jni_stub_MyClass_class.method2, arg1, arg2, arg3, arg4,
>> >arg6, arg7); } [truncated...]
>> >---------------------------------------------------------------
>> >-----------
>> >
>> >And so forth. The code generator is working already (as seen
>> above), I
>> >started putting it into an ANT task and figured this would be a good
>> >time to check the community.
>> >
>> >The generator has no external dependencies and is pure java.
>> >The current
>> >code generator can also generate C "stub" functions for all declared
>> >'native' methods in java class, but that functionality would be
>> >ommitted from the task. The long 'namespace' prefix for
>> every function
>> >can be overwritten with any user specified one. For example in the
>> >above sample, the namespace prefix used
>> 'org_jnetsoft_jni_stub' could
>> >be replaced by 'javani' task to user supplied one such as
>> 'stub' thus
>> >greatly shortening the function and ID names making them more
>> >convenient to utilize in user's code.
>> >
>> >Here is a typical scenario I would envision for usage with
>> this task. A
>> >programmer would choose which java calls need to be made on java
>> >classes from native C or C++ code. He would add a list of
>> those classes
>> >to his ANT build script, through a refid or some other list
>> of classes
>> >(typically an external .properties file). The build process would
>> >proceed in roughly the following order:
>> >
>> >1) compile user java code to classfiles
>> >
>> >2) invoke javah to generate stub header files for all native java
>> >functions (as normally done)
>> >
>> >3) invoke javani to generate wrapper functions and header
>> files for all
>> >classes and java methods which are expected to be invoked
>> from user's
>> >native code. User would declare those classes in a list.
>> >
>> >4) compile with a C compiler all the newly generated wrapper
>> functions
>> >and output to a build area.
>> >
>> >5) compile normal user native (C/C++) code. The code at this
>> stage can
>> >reference and rely on any wrapper functions and generated
>> header files.
>> >
>> >I use this process in practice with my projects and it works rather
>> >well.
>> >Steps #3 and #4 can easily be incorporated into any build
>> process and
>> >greatly simplify java method calls from native user space.
>> >
>> >Also note that the wrapper functions can be omitted
>> completely (with an
>> >option to 'javani' task), and the user can rely on entirely on the
>> >cached JNI method and field IDs and invoke JNI API directly
>> using those
>> >IDs. The IDs are exported globally (declared in header files). Once
>> >initialized, the wrapper functions are simply a convenience.
>> The method
>> >and field IDs can be utilized directly by the user if preferred over
>> >additional overhead of wrapper functions.
>> >
>> >There are some limitations. Unlike 'javah' task, my code
>> does not parse
>> >the binary classfile looking for constants. The task uses java
>> >reflection to inspect classes, methods and fields. Therefore any
>> >constants (static final
>> >fields) are typically optimized away by the compiler. These
>> constants
>> >however do exist in the 'javah' generated stub header files,
>> which can
>> >be incorporated into a build process. The 2 tasks are
>> complimentatory
>> >to each other. This is one area, where possibly classfile
>> parser used
>> >by 'javah'
>> >could be reused, but I haven't looked into this possibility yet.
>> >
>> >Cheers,
>> >mark...
>> >
>> >"A government big enough to give you everything you want, is strong
>> >enough to take everything you have."
>> >
>> >- Thomas Jefferson
>> >
>> >
>> >
>> 
>>---------------------------------------------------------------------
>> >To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org For
>> additional
>> >commands, e-mail: dev-help@ant.apache.org
>> >
>> >
>
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org


Mime
View raw message