JNI and Applets - really big bugs with browsers

Hi,

I am implementing an applet using dll with JNI. I followed the instructions and proceeded step by step, but I have a really "strange" error.

The point is that I download my dll from a zip file taken from the web (untill here no problem); and I save them into a temp directory (System.getProperty("user.tmpdir")).

Then I try to load them with System.load(absolute path of the dll).

But here I have a browser crash (with IE and firefox), more precisely a jvm crash and I get this log:

#

# An unexpected error has been detected by HotSpot Virtual Machine:

#

# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000000, pid=2812, tid=2216

#

# Java VM: Java HotSpot(TM) Client VM (1.4.2_10-b03 mixed mode)

# Problematic frame:

# C 0x00000000

#

... (I could send the rest if necessary)

And, a really strange stuff is that if I put my dll into a directory from the path, like the %java_home%\bin directory, my applet is loaded and works correctly.

I really don't have a clue where the problem is, could you help me please?

Thank you.

Flo

[1149 byte] By [Flo-skarpa] at [2007-10-2 5:56:15]
# 1

Actually, since the dll is in a folder from the java.library.path, it works.

BUT:

- if you modify java.library.path

by the method System.setProperty(...,...)

,

- or if you use a limited user account

it doesn't work.

user.dir is by default in java.library.path. The problem is that on IE, it's the desktop, so you can write and it works, but on Mozilla it's C:\Program Files\Mozilla Firefox where a limited user cannot write. And I would like to find a solution for my applet to work on both browsers.

If I load the Dll from another folder not in the path, at the first call to a native method from these Dll I have the jvm crash : Access Violation Error I sent before.

If you have anything who could help me, please say it, I really have to do this, and other alternatives (Java Web Start, or rewrite in java) aren't possible for what I want to do.

Flo-skarpa at 2007-7-16 2:05:23 > top of Java-index,Security,Signed Applets...
# 2

Why don't you sign the applet to get the runtime permissions you need and load its relevant libraries you delivered directly from the jar file; something like this assuming the native library is on the base path of the jarfile not in a directory and "this" refers to the applet instance:

Permission p = new RuntimePermission("*");

SecurityManager sm = System.getSecurityManager();

try{

if (sm != null){

sm.checkPermission(p, sm.getSecurityContext());

Runtime.getRuntime().load(

this.getClass().

getClassLoader().getResource("thelibtary.dlll").getPath());

}

}

catch(Exception ex)

{

//Handle it SecuirtyException ...

}

babakNa at 2007-7-16 2:05:23 > top of Java-index,Security,Signed Applets...
# 3

Thank you!

Actually, my applet is signed, otherwise I guess you know, you don't have all permissions. I will try your tip. At the beginning it was my intention to do that, but I failed to find the way to the jar archive without downloading it a second time.

I wanted to monitor the progression of the dll download, in case of the user have a slow internet connection. Do you think it's possible to achieve that simply in this context?

Anyway, thank you already for your help, I will give news soon if it works.

Flo-skarpa at 2007-7-16 2:05:23 > top of Java-index,Security,Signed Applets...
# 4

So, if I do exactly as you said, I get this Exception:

java.lang.UnsatisfiedLinkError: Expecting an absolute path of the library: file:/D:/Applet/signedjar/Applet.jar!/dll/Canvas.dll

at java.lang.Runtime.load0(Unknown Source)

at java.lang.Runtime.load(Unknown Source)

at seemageJava.Applet.loadDLL(Applet.java:175)

at seemageJava.Applet.init(Applet.java:63)

at sun.applet.AppletPanel.run(Unknown Source)

at java.lang.Thread.run(Unknown Source)

It looks like it's not Java who gets the load instruction, but the os, so it cannot read inside jar files.

I will try to write the dll (with getRessourceAsStream("dllname.dll")) into a temp dir and then to load it.

Thank you for your support, to be continued...

Flo-skarpa at 2007-7-16 2:05:23 > top of Java-index,Security,Signed Applets...
# 5

So you are restricted to the temporary saving of the binary indeed. but instead of going for loadLibrary which will want you to have the library in java.library.path, try loading with System.load("Fullpath of the library")

respectively Runtime.getRuntime().load(...)

So your applet code should not be mixed with java/javascript communication complications to do actions based on the browser type.

babakNa at 2007-7-16 2:05:23 > top of Java-index,Security,Signed Applets...
# 6

Hi,

Thank you for your ideas.

I did as we said (it was a bit tricky) : extract the dll from the jar file into a temp dir.

Then I load the libs with System.load and the absolute path of the lib, untill now no problem.

Then, at the first call of a native method from my dll, I have the same crash I spoke about in the 1st message, it looks like that:

#

# An unexpected error has been detected by HotSpot Virtual Machine:

#

# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000000, pid=2428, tid=3388

#

# Java VM: Java HotSpot(TM) Client VM (1.4.2_10-b03 mixed mode)

# Problematic frame:

# C 0x00000000

#

T H R E A D

Current thread (0x04f3e2a0): JavaThread "thread applet-seemageJava.SeemageApplet.class" [_thread_in_native, id=3388]

siginfo: ExceptionCode=0xc0000005, reading address 0x00000000

Registers:

EAX=0x04dfb950, EBX=0x166c8378, ECX=0x0c53fde8, EDX=0x001b0378

ESP=0x0c53fc24, EBP=0x0c53fc78, ESI=0x04dfb954, EDI=0x04f3e2a0

EIP=0x00000000, EFLAGS=0x00010206

Top of Stack: (sp=0x0c53fc24)

0x0c53fc24:07f611f6 001b0378 00000000 166c83c0

0x0c53fc34:00010003 07f91078 07f91072 0c53fc78

0x0c53fc44:025a80a0 04f3e2a0 025a81a6 04f3e33c

0x0c53fc54:0c53fc8c 0c53fc88 0c53fc5c 166c83c0

0x0c53fc64:0c53fc8c 16708878 00000000 166c8378

0x0c53fc74:0c53fc88 0c53fcac 025a2cb3 00000000

0x0c53fc84:025a64a9 1608cfd0 108ad768 0c53fc90

0x0c53fc94:166c6e6e 0c53fcc0 166c9ff8 00000000

Instructions: (pc=0x00000000)

0xfffffff0:

Stack: [0x0c440000,0x0c540000), sp=0x0c53fc24, free space=1023k

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)

j seemageJava.seemageCanvas.CreateGUI(Ljava/lang/String;)V+0

j seemageJava.SeemageApplet.start()V+6

j sun.applet.AppletPanel.run()V+319

j java.lang.Thread.run()V+11

v ~StubRoutines::call_stub

P R O C E S S

etc... I can supply the whole file if you understand something from it.

Same as before: If I have enough rights to write my dll in a directory included in the path environment variable, it works, otherwise not.

Other strange stuff: setProperty("java.library.path",...) isn't helping, neither is the code you can find at this discussion:

http://forum.java.sun.com/thread.jspa?threadID=627890

Code from the user AjaySingh516:

// Reset the "sys_paths" field of the ClassLoader to null.

Class clazz = ClassLoader.class;

Field field = clazz.getDeclaredField("sys_paths");

boolean accessible = field.isAccessible();

if (!accessible)

field.setAccessible(true);

Object original = field.get(clazz);

// Reset it to null so that whenever "System.loadLibrary" is called, it will be reconstructed with the changed value.

field.set(clazz, null);

try {

// Change the value and load the library.

System.setProperty("java.library.path", "c:\\tmp");

System.loadLibrary("libapr");

}

finally {

//Revert back the changes.

field.set(clazz, original);

field.setAccessible(accessible);

}

Does someone have any idea? Have you done the same kind of applet and did you have the same kind of problem I encounter?

Thank you in advance.

Flo

Flo-skarpa at 2007-7-16 2:05:23 > top of Java-index,Security,Signed Applets...
# 7

This by far is no more a matter of loading the native library rather happening in the scneario of executing the native method.

Have you checked using the native methods outside sandbox but with the same version of VM ( java code instead of applet)? I suppose you should get some similar errors in that case too. Then it is either some memory handling problem over there or not covering some awaited exception in the C code. to pass exceptions to the java code (invalid or semantically false arguments ...).

babakNa at 2007-7-16 2:05:23 > top of Java-index,Security,Signed Applets...
# 8

The same problem occurs with java application, if you don't put the dll in the paths, it is loaded but it crash at the first native call.

If you put the dll in the path, everything works, from the beginning to the end.

It looks like that:

Java -> JNI_DLL -> CoreDLL

with Java I load JNI_DLL, but not the CoreDLL. JNI_DLL is just an interface between Java and my C++ Application.

I was thinking that I have 2 dll, I just load 1 with java, and maybe it's when this dll I load with Java try to load the second dll (but cannot achieve that because it's not in the path) that the JVM crash.

Could it be possible?

Flo-skarpa at 2007-7-16 2:05:23 > top of Java-index,Security,Signed Applets...
# 9

HAHA!

I found out what was the problem: the 1st dll was supposed to load the 2nd with a call to loadLibrary, so assuming that this library was in the path. But it wasn't the case!

SO I just had to give the path of the 2nd to the 1st dll, and it worked.

Sorry to have trouble you with, that, but it was hard to see that it came from the dll.

Flo-skarpa at 2007-7-16 2:05:23 > top of Java-index,Security,Signed Applets...