users@glassfish.java.net

Re: Calling the linux shell from Glassfish

From: <glassfish_at_javadesktop.org>
Date: Thu, 18 Oct 2007 11:43:57 PDT

It looks as if the problem has something to do with the way I've set up the folders and packages.

I've been carrying out some tests with the CLI and get similar error messages to the ones in my posting immediately above. What I did was to copy the files into temporary folders that will be organized exactly the same way as when I want to deploy the code with Glassfish. In the folder /com/corejsf I put in a test driver class in "CallUserBean.java" as follows:

// Listing 1
package com.corejsf;

import java.io.*;
import java.util.*;

class CallUserBean {
    public static void main(String[] args) {
        UserBean bean = new UserBean();
        String s = new String();
        s = "Passing this string to UserBean";
        System.out.println(s);
        bean.setName(s);
    }
}

Which calls the class in "UserBean.java"

// Listing 2
package com.corejsf;

import java.io.*;
import java.util.*;

public class UserBean {
   private String name;
   private String password;

   // PROPERTY: name
   public String getName() { return name; }
   public void setName(String newValue) {
       System.out.println("Now in UserBean.setName()");
       System.out.println(newValue);
       String command = new String();
       command = "ls -lt > jnioutput.txt";
       System.out.println("Sending the string - " + command + " - to native code");
       CallSystem.system(command);

       name = newValue;
   }

   // PROPERTY: password
   public String getPassword() { return password; }
   public void setPassword(String newValue) { password = newValue; }
}

At the moment for the test only the methods "getName", "setPassword" and "getPassword" are not used. This in turns calls the class in "CallSystem.java":

Listing 3
package com.corejsf;

class CallSystem {
    public static native void system(String s);
    static {
        System.loadLibrary("CallSystem");
    }
}

Which calls the native C code in "CallSystem.c":

Listing 4
#include "UserBean.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

JNIEXPORT void JNICALL Java_CallSystem_system(JNIEnv* env, jclass cl, jstring jcommand) {
    const char *ccommand;

    ccommand = (*env)->GetStringUTFChars(env, jcommand, NULL);
    system(ccommand);

    (*env)->ReleaseStringUTFChars(env, jcommand, ccommand);
}

which passes a string to the shell for execution. In this case a simple test "ls" is executed, as you can see in listing 1.

After I compile the C code and link in the shared library, then compile the Java files with the "package com.corejsf;" commented out in listings 1, 2 and 3, the code works with the command:

"java -Djava.library.path=. CallUserBean"

from inside /com/corejsf. However, if I uncomment the package statements and recompile the Java files using the statements "javac -classpath "../../" CallSystem.java", and likewise for the other two files then issue the command:

"java -Djava.library.path=. -classpath ../../ CallUserBean"

from within the folder having the classes, I get the following output:

Passing this string to UserBean
Now in UserBean.setName()
Passing this string to UserBean
Sending the string - ls -lt > jnioutput.txt - to native code
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.corejsf.CallSystem.system(Ljava/lang/String;)V
        at com.corejsf.CallSystem.system(Native Method)
        at com.corejsf.UserBean.setName(UserBean.java:19)
        at CallUserBean.main(CallUserBean.java:11)

Which obviously means it can't find the native class. Presumably there is an easy way of solving this.

Once this has been fixed, and assuming Glassfish is working correctly, I want to test that Glassfish can execute the code starting at listing 2, with listing 1 discarded.

I would be most grateful for some help on this problem which hopefully will be easy to fix.

Christopher Sharp
[Message sent by forum member 'csharpdotcom' (csharpdotcom)]

http://forums.java.net/jive/thread.jspa?messageID=241013