Servlet + JNI = remote control hardware

hi, everybody ~ HELP! HELP!

Does Someone have the example for "Servlet + JNI"?

I have a problem:

JAVA -> JNI -> C -> DLL (Control Hardware)

the DLL is OK, so I can control Hardware.

but how to use "Servlet" with "JNI" ?

does any body have examples? help~~~~

thanks..

[332 byte] By [cofensen] at [2007-9-26 3:15:18]
# 1
I would think you could just have the doGet() or doPost() method of the servlet call your native methods that are in your Java class that goes through JNI. It really shouldn't be any different.
swatdba at 2007-6-29 11:26:28 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 2
Hmm, thanks. I tried. ^_QBut something strange in the error message below:java.lang.NoClassDefFoundErrorat java.lang.Class.forName0(Native Method)at java.lang.Class.forName(Class.java:195)in the simple Java -> JNI -> C , it's works good.
cofensen at 2007-6-29 11:26:28 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 3
Your class that contains the native method(s), have you put its .class file in the servlet engine's classpath, e.g. WEB-INF/classes or WEB-INF/lib?Servlet -> Java wrapper class -> native C++ methodLooks like Servlet cannot find your Java wrapper class.
yilin at 2007-6-29 11:26:28 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 4
Yes. I put.and something strange still in the message.I put all of the files I created. The message appears again.Any suggestion? Help~~~ thanks
cofensen at 2007-6-29 11:26:28 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 5
Can you show the entire stack trace of that message? Can you tell from the trace which class cannot be found?
yilin at 2007-6-29 11:26:28 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 6
I feel so strange.I tried so much times....can't find the answer... help~~Do you have a sample for Servlet -> JNI -> C ?
cofensen at 2007-6-29 11:26:28 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 7

So terrable... Q_Q... help

For the Servlet problem, I can't solve it.So now I am changing a way.

Using JavaBean to replace the Servlet way.

"JavaBean -> Java -> JNI -> C"

the JavaBean only doing interface for "Java".

Let JavaBean call the Java.

But the message is shown again.. my God... Q_Q

I post it in next message.

cofensen at 2007-6-29 11:26:28 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 8

-[ JSP file ]--

<jsp:useBean id="myBean" scope="page" class="Counter"/>

<jsp:getProperty name="myBean" property="count"/>

-[ Counter.java ] for JavaBean

import HelloWorld;

public class Counter{

public Counter(){

}

public String getCount(){

HelloWorld abc = new HelloWorld();

String rr = abc.print();

return rr;

}

public void setCount(int newCount){

}

}

-[ Java -> JNI ]--

class HelloWorld {

public native String print();

public static void main(String[] args){

new HelloWorld().print();

}

static{

System.loadLibrary("HelloWorld");

}

}

[ HelloWorld.c ]

#include <jni.h>

#include <stdio.h>

#include "HelloWorld.h"

JNIEXPORT jstring JNICALL

Java_HelloWorld_print(JNIEnv *env,jobject obj){

printf("Hello World!\n hihihi success!");

return;

}

-- Server replay --

500 Internal Server Error

java.lang.NoClassDefFoundError

at Counter.getCount(Counter.java:10)

.......

What can I do.... so strange... Q_Q

cofensen at 2007-6-29 11:26:28 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 9
So your Count cannot find HelloWorld class. How do you package them in the deployment dir? Do you have both Count.class and HelloWorld.class in the same jar file? If they are not in jar files, are the 2 class files in the same dir?
yilin at 2007-6-29 11:26:28 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 10

Yes, they all in the same dir.

I tried so much ways , but still can't success.

Now I Combine the JavaBean and (Java->JNI) in the it.

*** Counter.java (JavaBean) , Compiler OK, in DOS see the words from calling C's DLL. Because I have main().

public class Counter{

public Counter(){}

public native String printt();

public static void main(String[] args){

new Counter().printt();

}

public String getCount(){

return(new Counter().printt());

}

public void setCount(int newCount){}

static{

System.loadLibrary("HelloWorld");

}

}

*** HelloWorld.c *****

class HelloWorld {

public native String printt();

public static void main(String[] args){

new HelloWorld().printt();

}

static{ System.loadLibrary("HelloWorld"); }

}

************* The result that Server says ******

500 Internal Server Error

java.lang.NoClassDefFoundError

at java.lang.Class.forName0(Native Method)

at java.lang.Class.forName(Class.java:195)

at com.evermind.server.http.HttpApplication.v6(JAX)

.....

I think use JavaBens is easy to decrease the level of calling much methods. And it can use in the JSP.

BUT... Why appear the "forName0" and "forName" this two guys? My God...help~~~ thanks Q_Q

cofensen at 2007-6-29 11:26:28 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 11
Can you check if the "PATH" env variable for you server includes the dir containing your dll file (HelloWorld.dll)? Usually when you start the server, the start script set "PATH" for the server. (If you use Unix, it's LD_LIBRARY_PATH instead of PATH.)
yilin at 2007-6-29 11:26:28 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 12
the server can find the HelloWorld.dll,if not, will show the loading dll file error...so... strange.... (ps. my OS is W2k... )help~~~
cofensen at 2007-6-29 11:26:28 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 13

at com.evermind.server.http.HttpApplication.v6(JAX)

I am trying to verify exactly which class it is not finding. To do this, I need to locacte the exactly souce code line that cause this exception. So can you show the entire stack trace following the above line? And tell me which line is the 1st line that shows YOUR source code? (I guess com.evermind... is your server vendor, not your own source package, right?)

yilin at 2007-6-29 11:26:28 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 14
hmm.. if the 1st and 2nd error lines can solve , then others error lines should not be shown.They are continue errors, like the 1st error can solve, it may not be shown at 2nd error.thanks..
cofensen at 2007-6-29 11:26:28 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 15

Thanks you again... ^_^ to help me more times..

All My step and files are shown below:

--[1 step]--[ JSP file ]--

<jsp:useBean id="myBean" scope="page" class="Counter"/>

<jsp:getProperty name="myBean" property="count"/>

--[2 step][ write JavaBean ]--

public class Counter{

public Counter(){}

public native String printt();// It's Native entry

public static void main(String[] args){ // This just for Java in DOS runable.

new Counter().printt();

}

public String getCount(){

return(new Counter().printt());

@@@@@@@@@@@@@@@@ <= the server will call getCount() method, which the DLL's create the printt() method.it may cause the 1st errors because can't find printt().I guess.

}

public void setCount(int newCount){}

static{

System.loadLibrary("HelloWorld"); //LOAD the DLL's from C create

}

}

[3 step] [ Create Counter.h ] -- CMD:[ javah - jni Counter ]

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class Counter */

#ifndef _Included_Counter

#define _Included_Counter

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class:Counter

* Method:printt

* Signature: ()Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_Counter_printt

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

-[4 step] [Write HelloWorld.c ]-

#include <jni.h>

#include <stdio.h>

#include "Counter.h"

JNIEXPORT jstring JNICALL

Java_Counter_printt(JNIEnv *env,jobject this){

printf("Hello World!\n hihihi success!");

return;

}

[5 step]-- [use VC++ 5 to create the DLL from HelloWorld.c ]

[6 step] -- The result that Server says -

500 Internal Server Error

java.lang.NoClassDefFoundError

at java.lang.Class.forName0(Native Method)

at java.lang.Class.forName(Class.java:195)

...

cofensen at 2007-7-1 3:34:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 16

To top of stack trace is usually system calls, but these calls can be traced back to your OWN source code, which shows up in the MIDDLE of the stack. So you need to look down to the MIDDLE of the stack trace to find the very first line mentioning your OWN source code. You see what I mean?

yilin at 2007-7-1 3:34:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 17
Understand...nothing.... ?_Q"Could you show a simple sample?THANKS YOU AGAIN~~ ^_^[Before] I had writen a Servlet + JNI, only let the JNI in the Servlet, and then I got the same error 2 lines.
cofensen at 2007-7-1 3:34:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 18

500 Internal Server Error

java.lang.NoClassDefFoundError

at java.lang.Class.forName0(Native Method)

at java.lang.Class.forName(Class.java:195)

...

In your above posting, why don't you show the entire stack trace instead of "..."? Those "..." may turn out to have important information. That's all I mean.

yilin at 2007-7-1 3:34:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 19

Because when error appears.

the error line (I mean "....." is the chain reaction of errors.

if I can solve the front of the two errors. then the error will disapper.

thanks for your help. ^_Q"

I show the all error messages below.

--

500 Internal Server Error

java.lang.NoClassDefFoundError

at java.lang.Class.forName0(Native Method)

at java.lang.Class.forName(Unknown Source)

at com.evermind.server.http.HttpApplication.v6(JAX)

at com.evermind.server.http.ei.tx(JAX)

at com.evermind.server.http.ei.s_(JAX)

at com.evermind.server.http.JSPPage.s_(JAX)

at com.evermind.server.http.HttpApplication.wh(JAX)

at com.evermind.server.http.HttpApplication.xj(JAX)

at com.evermind.server.http.JSPServlet.service(JAX)

at com.evermind.server.http.ea.doFilter(JAX)

at com.orionsupport.cocoon.CocoonFilter.doFilter(CocoonFilter.java:65)

at com.evermind.server.http.d3.sw(JAX)

at com.evermind.server.http.d3.su(JAX)

at com.evermind.server.http.ef.s1(JAX)

at com.evermind.server.http.ef.do(JAX)

at com.evermind.util.f.run(JAX)

cofensen at 2007-7-1 3:34:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 20

It seems that your server cannot find your Servlet/JSP class, because the stack trace does not contain any of your own code, so your JSP is not even run yet.

Try this: put a very simple JSP without any native stuff, just output an HTML string, see it your server can get to your JSP or not.

yilin at 2007-7-1 3:34:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 21

Thanks for your suggestion.

But I used the server a long time ago.

The JSP page is good for run, not the server can't find my JSP page.

I guess the error is the server can't find the "method loaded from DLL file."

So will cause a chain error lines. not for the JSP page can't be founded.

HELP~~~

cofensen at 2007-7-1 3:34:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 22
I solve all the problem~thanks for help me programming thinking ways past this months. ^_^
cofensen at 2007-7-1 3:34:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 23
Curious what the problem(s) really turned out to be?
yilin at 2007-7-1 3:34:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 24
Hi cofensen ! I read the problem you have had, is the same or similar i have. Can you tell me how you put it to work ?Thanks in advance!
tata48 at 2007-7-1 3:34:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 25

Hi Cofensen,

Use try-catch blocks in your code.

Use a try catch block like this.

Where the error could possibly occur.

If you dont want to use try catch block here and there, then declare the method to throws Exception.

This will give the complete stacktrace.

Safe code

try

{

Any unsafe code

Native method calling code

}

catch(Exception)

{

print trace

}

catch(Throwable t)

{

print stack trace

}

Because if you dont catch an error ,

then you give the burden to your webServer.

By the way can you please mention your webserver and

give details about how you have deployed in that.

Some java program should run in the webserver.

check whether the DLL is there in the "-Djava.library.path=<Path of Dir of the dll in server>"

We could solve it. Dont worry.

Good Luck.

LathaDhamo at 2007-7-1 3:34:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 26
Hi cofensen,Good you solved the problem. I have the same problem... Could you please tell us how you solved it ? steps / sample code .. that would help lot of people like me on this forum.ThanksRam
ram_ch_sun at 2007-7-1 3:34:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...
# 27

I'm pretty sure it's ClassLoader. Classes loaded from different 'classloaders' do not 'see' each other (i recall first versions of ServletExec were really weird because of that). So, there is a big chance that from wherever you are calling the native methods from, this class has been loaded in different class loader (i'm not that good in servlet engine specifications, but again, that old ServletExec engine explicitely pointed out that you can not refer to the _static_ field of your HttpServlet class between the calls, since the value is not guaranteed to stay the same, which means that HttpServlet classes can be loaded from different class loaders).

I didn't read all the code you've been sending, but my hunch would be to declare the native methods in a separate class (_not_ HttpServlet). This is so called 'services' class shared between servlets (again, in some early engines you should had put this classes in a separate directory, aside from servlets - i guess for exactly the same reason - they were loaded in a separate classloader so that 'servlet' class loaders could access it).

public class MyServlet extends HttpServlet {

public void doGet(req, resp) {

NativeService.getService().runMethod();

}

}

public class NativeService {

static NativeService ns = new NativeService();

private NativeService() {}

public native runMethod();

public NativeService getService() {return ns;}

}

volenin at 2007-7-1 3:34:56 > top of Java-index,Java HotSpot Virtual Machine,Specifications...