Skip to main content

Using JNI in applets: impossible due to classloader limitations?

24 replies [Last post]
cowwoc
Offline
Joined: 2003-08-24

Consider:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4642062
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4299094
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4748750
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4286309

Doesn't this imply it is impossible to use JNI in applets? If one instance of the applet closes and another instance opens, how do you get LoadLibrary("sameLibrary") to succeed? The problem is made worse by the fact that the Java Plugin reuses the same JVM across all applets (I believe this is even true in the new engine). Any ideas?

Thanks,
Gili

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
turks
Offline
Joined: 2007-12-23

kbr,

You state "The JNLPAppletLauncher is an interim solution for exactly this problem. Using it does require small changes to the extension that contains the native code" When you say small changes to the extension, do you mean to
the .dll or .so code and a recompile to use your native code with
JNLPAppletLauncher ?

Thanks again for helpful guidance !

kbr
Offline
Joined: 2003-06-16

Small changes to the Java code for the extension in how it loads the library. Instead of calling System.loadLibrary() directly you need to make a reflective call into the JNLPAppletLauncher. See the JNLPAppletLauncher documentation for more information.

rsi2000
Offline
Joined: 2008-01-07

Do native dlls (PC) or dynlibs (MAC) that are downloaded via JNLPAppletLauncher have to digitally signed ? If so, is java able to actually tell if a dll or dynlib is signed ?

Thanks

kbr
Offline
Joined: 2003-06-16

The jar file containing the native libraries needs to be signed with the same signature as the jar archive which holds the JNLPAppletLauncher. In practice, this means you will need to un-jar, re-jar and re-sign the JNLPAppletLauncher, as the one we distribute is signed by Sun and you don't have access to Sun's code signing certificate.

rsi2000
Offline
Joined: 2008-01-07

Once the native library is downloaded, what is the best way to access the methods in the native library ?

Thanks

kbr
Offline
Joined: 2003-06-16

In the normal way -- you define native methods in your class and the JVM resolves them in the native library. The only thing the JNLPAppletLauncher does is replace the call to System.loadLibrary().

rsi2000
Offline
Joined: 2008-01-07

We're getting there.

"In the normal way -- you define native methods in your class and the JVM resolves them in the native library".

Would the normal way be using JNI and creating a bridge dll to the dll
containing the native methods and calling the native methods through the bridge ?

Also, using JNLP-based applet launcher can I define a heap size using the JNLP args
so I can increase the heap from it's default size ?

Thanks again for your help.

kbr
Offline
Joined: 2003-06-16

> Would the normal way be using JNI and creating a
> bridge dll to the dll
> containing the native methods and calling the native
> methods through the bridge ?

Yes. If you haven't done much JNI programming then I would recommend you practice with standalone applications on your own system before attempting to deploy anything via an applet.

> Also, using JNLP-based applet launcher can I define a
> heap size using the JNLP args
> so I can increase the heap from it's default size ?

No, but the next-generation Java Plug-In supports this via the java_arguments parameter to the applet, object and embed tags. See https://jdk6.dev.java.net/6uNea.html and https://jdk6.dev.java.net/testPlugIn.html .

turks
Offline
Joined: 2007-12-23

How is tmpRootDir set ? When using JNLP-based applet launcher on a mac os x
it set to /tmp, (see below) which only has permissions for the owner to write:

lrwxr_xr_x root admin

Therefore applets using JNLP-based applet launcher fail because ordinary (non admin)
users don't have the ability to write to /tmp which causes it to fail. On Windows
tmpRootDir is set to the user's Document and Setting folder which the user has full
rights to. Can tmpRootDir be set dynamically ?

[b]JNLPAppletLauncher: static initializer
os.name = mac os x
nativePrefix = lib nativeSuffix = .jnilib
tmpRootDir = /tmp/jnlp-applet/jln13113
Applet.init[/b]

kbr
Offline
Joined: 2003-06-16

It's placed underneath java.io.tmpdir, which is supposed to be writable by signed code. If non-admin users can't write to this location on Mac OS X then I think this is a bug in Java which should be filed with Apple.

You can see all of the source code to the JNLPAppletLauncher by checking out the project's source code. http://applet-launcher.dev.java.net/

turks
Offline
Joined: 2007-12-23

Has anyone tried JNLP-based applet launcher on Linux or Soloris ?

turks
Offline
Joined: 2007-12-23

Has anyone tried JNLP-based applet launcher using Linux or Solaris ?

kbr
Offline
Joined: 2003-06-16

The JNLPAppletLauncher is an interim solution for exactly this problem. Using it does require small changes to the extension that contains the native code, but there is clear documentation on how to do this on the applet launcher web page.

The new Java Plug-In will support forcing an individual applet into its own JVM instance. RFE 6627835 has been filed about this:

http://bugs.sun.com/view_bug.do?bug_id=6627835

cowwoc
Offline
Joined: 2003-08-24

kbr,

It isn't clear what exactly JNLPAppletLauncher does short of using JNLP file descriptors. Can you (or anyone) please explain what it does differently to solve this problem? There are two distinct problems I am trying to solve:

1a) Each applet should be able to load its own version of the DLL without UnsatisfiedLinkError.

1b) If two applets load the same DLL each should have their own state. That is, changing the state in one applet shouldn't affect the DLL state in another applet unless you are accessing shared memory.

2) If the DLL leaks memory, you want all that memory freed when the applet shuts down.

1a and 2 are strict requirements whereas 1b is more of a nice-to-have.

The way I see it there is no way to achieve this without having a separate JVM per applet. This is simply how processes work under Windows. Did I miss something?

kbr
Offline
Joined: 2003-06-16

The JNLPAppletLauncher solves 1a and 1b. It does so by making a fresh copy of the downloaded (and cached) DLL into a temporary directory on a per-ClassLoader basis, eliminating the conflicts between independent applets' ClassLoaders.

You're right, there is no way to achieve 2 without using a separate JVM instance for the applet. The new Java Plug-In in the 6uN release will solve this problem.

cowwoc
Offline
Joined: 2003-08-24

That's great news. One question though: if you load the same applet multiple times on a client, don't you end up with the same classloader and as such you end up sharing the same temporary directory and DLL instance?

kbr
Offline
Joined: 2003-06-16

Generally, yes. The take-home point is that the UnsatisfiedLinkError is solved with this approach.

cowwoc
Offline
Joined: 2003-08-24

Thank you very much for all your helpful comments. I look forward to testing the new Java Plugin when it comes along ;)

kbr
Offline
Joined: 2003-06-16

Actually it's available now for testing. See https://jdk6.dev.java.net/testing.html , in particular https://jdk6.dev.java.net/testPlugIn.html .

cowwoc
Offline
Joined: 2003-08-24

I just ran into http://forums.java.net/jive/message.jspa?messageID=13908 where Stanley Ho writes:

>The most likely way we will improve native library deployment is to support JNLP
>extension in Java Plug-in, and native libraries would be downloaded into the local cache
>(that user has write permission) and used by the applets during deployment.

So maybe the aforementioned applet-launcher actually works somehow.

mhey123
Offline
Joined: 2003-07-01

You may want to check out https://applet-launcher.dev.java.net/ it may solve the problem of loading the same DLL's into multiple applets. Its essentially a custom classloader that loads the applet jars from a server using the JNLP protocol. It also handles DLL's etc for different platforms (Win, Linux, Solaris, OSX etc etc).

Cheers,
Matt.

cowwoc
Offline
Joined: 2003-08-24

I don't think applet-launcher will help because there is a fundamental problem with the Applet architecture. I only know of two ways to make this work:

1) You can load the DLL into some shared parent classloader that crosses applet boundaries, or

2) You can force the JVM to unload the DLL when the applet terminates

I don't think either approach is technically possible with the existing Applet architecture. Even Tomcat's approach of loading the DLL into some parent classloader is somewhat of a hack. Ideally we want to be able to isolate each application (applet or webapp) into its own JVM but this isn't the case today.

I suspect this is what JSR 121 was supposed to solve: http://jcp.org/en/jsr/detail?id=121 but it never made it into JDK5 as was originally envisioned.

twalljava
Offline
Joined: 2004-07-26

Native libraries loaded with System.loadLibrary will only be unloaded when the classloader is unloaded (which will only happen when there are no more references to your JNI-using class and its classloader, which means your classloader can't be the default/bootstrap one).

Is there a reason you *can't* use a custom class loader to obtain your JNI-using class?

cowwoc
Offline
Joined: 2003-08-24

1) there is no guarantee that the classloader will be unloaded (or *when* even if it does), so...
2) there is no guarantee that it is safe to reload an applet immediately after it has been shut down
3) there is no guarantee it is safe to run the same applet multiple times simultaneously

Essentially that's what you should be able to do, which (in my mind) means you absolutely must have one JVM per applet which is not the case today and probably won't be the case in the new applet engine that is being rolled out in update 4/5 either.

The question is: why? They should probably reuse the same JVM for all non-signed applets and use a new JVM per signed applet. Whatever the performance cost, the resulting stability and flexibility benefits warrant it in my opinion.