Hi list,

Short version: 
Anyone know of any issues regarding JNI with James?

Long version: 
I'm trying to use BounceStudio 
(http://www.boogietools.com/Products/Linux/BounceStudioAPI/help/help.html) with 
James. Its supplied only as a linux .so file so you have to interface to it via 
JNI. I built the necessary files but all attempts to call into BounceStudio 
method from a mailet just hung the thread processing that mail with no messages 
whatsoever.

Suspecting either my build process or BounceStudio itself to be at fault, I 
went right back to basics with a minimal "Hello World" type app, and that did 
the same. Apologies for the long post but here are the details:

System is Ubuntu, kernel 2.6.22-15-386, JDK 1.4 because thats what James was 
built with and I wish to keep any JNI classes at the same version.

1. Create HelloJNI.c with the following contents

 #include <jni.h>
 #include <stdio.h>
 #include "HelloJNI.h"
 
 JNIEXPORT void JNICALL 
 Java_HelloJNI_print(JNIEnv *env, jobject obj)
 {
     printf("Hello JNI!\n");
     return;
 }

2. create a makefile (called makefile) with the following contents (adjust 
paths to suit):

JAVA_HOME=/tools/java/j2sdk1.4.2_04
CC=gcc
CSRCS=HelloJNI.c
COUT=libHelloJNI.so
CFLAGS= -shared -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/linux/

JAVAH=$(JAVA_HOME)/bin/javah
JHFLAGS= -classpath bin/
JHSRC=HelloJNI

JAVA=$(JAVA_HOME)/bin/java
JAVAC=$(JAVA_HOME)/bin/javac
JFLAGS= -Xlint -classpath src/:lib/mail-1.3.2.jar -d bin/
JSRC=HelloJNI.java
JOUT=HelloJNI.class

compile : $(CSRCS)
    $(CC) $(CSRCS) -o $(COUT) $(CFLAGS)

3. Create a build script called build.sh with the following contents:

#! /bin/sh

JavacPath=/opt/java/bin/javac
JavahPath=/opt/java/bin/javah

LD_LIBRARY_PATH=.
export LD_LIBRARY_PATH

$JavacPath HelloJNI.java
$JavahPath -jni HelloJNI
make compile
java HelloJNI

4. Run build.sh and you should see:
gcc HelloJNI.c -o libHelloJNI.so -shared -I/tools/java/j2sdk1.4.2_04/include 
-I/tools/java/j2sdk1.4.2_04/include/linux/
Hello JNI!

So we know calling this .so is fine from java.

5. Wire up a mailet appropriately in config.xml and base it on this code:

public class MyMailet extends GenericMailet {
    
    private native void print();
    
    static {

    final String libName = "libHelloJNI.so";
        String hardcodedPath = "/opt/james/apps/james/SAR-INF/lib/"+libName;
        System.out.println("Loading from: "+hardcodedPath+"...");
        System.load(hardcodedPath);
        System.out.println("...Loaded: "+hardcodedPath);
    }

    public void service(Mail mail) throws MessagingException {

    logger.info("Entering MyMailet service method");
        System.out.println("Invoking JNI...");
        try {
            print();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("...back from analysis");
    }

....

}

6. Start James and note the JNI lib is loaded ok.

7. Send an email though James ensuring its matcher is configured to invoke this 
mailet and you see

Invoking JNI...

And no more. Send another and you get another Invoking JNI... - its hanging on 
each request and just spawning a new thread for new emails.

Thanks for any clues

-- Bill



      

Reply via email to