Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / March 2008

Tip: Looking for answers? Try searching our database.

UnsatisfiedLinkError using Java Webstart with custom classloader

Thread view: 
Andi - 17 Mar 2008 11:42 GMT
Hi,

I have a big problem to get my Application running on java webstart. I
have a custom classloader which will be used for some classes. Also I
need to load a dll which will be used by a native interface.

Here is my application entry point:

public class ApplicationStarter
{
   public static void main(String[] args)
   {
       try
       {
           System.setSecurityManager(null);
           CustomClassLoader classLoader = new
CustomClassLoader(Thread.currentThread().getContextClassLoader());
           Thread.currentThread().setContextClassLoader(classLoader);

classLoader.loadClass("bugreport.jws6.Application").getMethod("main",
new Class[] { String[].class })
                   .invoke(null, new Object[] { args });
       }
       catch (Exception e)
       {
           e.printStackTrace();
       }
   }
}

That all the classloading my classloader will be used I am calling the
real applcation per reflection loaded by my classloader.

Here the application I start:

public class Application
{
   public static void main(String[] args)
   {
       try
       {
           System.loadLibrary("jws6-bugreport");
           NativeInterface nativeInterface = new NativeInterface();
           System.out.println("Native call result :" +
nativeInterface.doSomething());
       }
       catch (Throwable t)
       {
           t.printStackTrace();
       }
   }
}

Here my Classloader:

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;

public class CustomClassLoader extends ClassLoader
{

   private HashMap<String, Class<?>> loadedClasses = new
HashMap<String, Class<?>>();

   public CustomClassLoader(ClassLoader parent)
   {
       super(parent);
   }

   public Class<?> customLoadClass(String name) throws
ClassNotFoundException
   {
       System.out.println("Custom loading of class " + name);
       Class<?> clazz = this.loadedClasses.get(name);
       if(clazz == null)
       {
           try
           {
               String classFilename = name.replace('.', '/') +
".class";

               InputStream inputStream =
getResourceAsStream(classFilename);
               if(inputStream == null)
                   throw new ClassNotFoundException(name);

               ByteArrayOutputStream baout = new
ByteArrayOutputStream();
               byte[] b = new byte[2048];
               int byteCount;
               while((byteCount = inputStream.read(b, 0, 2048)) !=
-1)
               {
                   baout.write(b, 0, byteCount);
               }
               byte[] buffer = baout.toByteArray();
               baout.close();

               clazz = defineClass(name, buffer, 0, buffer.length);
               this.loadedClasses.put(name, clazz);

           }
           catch (IOException e)
           {
               throw new ClassNotFoundException(name, e);
           }
       }

       return clazz;
   }

   @Override
   public Class<?> loadClass(String name) throws
ClassNotFoundException
   {
       Class<?> clazz;
       if(name.startsWith("bugreport.jws6"))
       {
           clazz = customLoadClass(name);
       }
       else
       {
           clazz = super.loadClass(name);
       }
       return clazz;
   }

   public String toString()
   {
       return getClass().getName();
   }
}

That works perfect when I have a normal client application but it
doesn't when I use Java Webstart.

Here my jnlp:

<?xml version="1.0" encoding="utf-8"?>
<!-- JNLP File for SwingSet2 Demo Application -->
<jnlp
 spec="1.0+"
 codebase="http://localhost/jws6-bugreport"
 href="Webstart6Bugreport.jnlp">
 <information>
   <title>Webstart 6 Bugreport</title>
   <vendor>Skillworks AG</vendor>
   <description>None</description>
   <description kind="short">None</description>
   <offline-allowed/>
 </information>
 <security>
     <all-permissions/>
 </security>
 <resources>
   <j2se version="1.5"/>
   <nativelib href="jws6-bugreport-native.jar"/>

<jar href="jws6-bugreport-app-1.0.jar" main="true"/>
<jar href="jws6-bugreport-jni-1.0.jar"/>

 </resources>
 <application-desc main-class="bugreport.jws6.ApplicationStarter"/>
</jnlp>

Here the native code:

public class NativeInterface {

    public native String doSomething();
}

#include "NativeInterface.h"

JNIEXPORT jstring JNICALL
Java_bugreport_jws6_NativeInterface_doSomething
 (JNIEnv *jEnv, jobject obj)
{

   jstring referenceKey = jEnv->NewStringUTF("Native Call done");
    return referenceKey;
}

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class bugreport_jws6_NativeInterface */

#ifndef _Included_bugreport_jws6_NativeInterface
#define _Included_bugreport_jws6_NativeInterface
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     bugreport_jws6_NativeInterface
* Method:    doSomething
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
Java_bugreport_jws6_NativeInterface_doSomething
 (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

Does anybody help me with that problem...?
Thanks for every hint
Andi - 17 Mar 2008 11:46 GMT
Here the Exception I got:

java.lang.UnsatisfiedLinkError: no jws6-bugreport in java.library.path
    at java.lang.ClassLoader.loadLibrary(Unknown Source)
    at java.lang.Runtime.loadLibrary0(Unknown Source)
    at java.lang.System.loadLibrary(Unknown Source)
    at bugreport.jws6.Application.startup(Application.java:24)
    at bugreport.jws6.Application.main(Application.java:10)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at bugreport.jws6.ApplicationStarter.main(ApplicationStarter.java:10)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.sun.javaws.Launcher.executeApplication(Unknown Source)
    at com.sun.javaws.Launcher.executeMainClass(Unknown Source)
    at com.sun.javaws.Launcher.continueLaunch(Unknown Source)
    at com.sun.javaws.Launcher.handleApplicationDesc(Unknown Source)
    at com.sun.javaws.Launcher.handleLaunchFile(Unknown Source)
    at com.sun.javaws.Launcher.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Roedy Green - 20 Mar 2008 06:53 GMT
On Mon, 17 Mar 2008 03:46:13 -0700 (PDT), Andi
<andreas.schneider@skillworks.de> wrote, quoted or indirectly quoted
someone who said :

>java.lang.UnsatisfiedLinkError: no jws6-bugreport in java.library.path

It might be wise to dump the java.library.path just prior to your load
library. Perhaps the problem is the library path being anemic.

See http://mindprod.com/applet/wassup.html
for source code.

also
http://mindprod.com/jgloss/properties.html
Signature


Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Andrew Thompson - 17 Mar 2008 12:27 GMT
...
> I have a big problem to get my Application running on java webstart. I
> have a custom classloader which will be used for some classes.

JWS *has* been known to be finicky with classloaders,
a lot of apps. used code that could 'discover' the
exact location to which it was downloaded.  Changes
between 1.5 and 6.0 made that code break.

I am curious though to know exactly - *why*
are you using a custom classloader?

>..Also I
> need to load a dll which will be used by a native interface.

More on that below. *

(big snip...)
> That works perfect when I have a normal client application but it
> doesn't when I use Java Webstart.
[quoted text clipped - 3 lines]
> <?xml version="1.0" encoding="utf-8"?>
> <!-- JNLP File for SwingSet2 Demo Application -->

This is a fib, by the way.  This is not
the SwingSet2 application.  If we are going
to include comments, it seems sensible to
make them factual.  ( And yes, I've been
caught out by the same thing myself ;)

> <jnlp
>   spec="1.0+"
[quoted text clipped - 16 lines]
> <jar href="jws6-bugreport-app-1.0.jar" main="true"/>
> <jar href="jws6-bugreport-jni-1.0.jar"/>

* OK.  I think the nativelib element should be
*after* the jar elements.  That is how it is
listed in the JNLP File Syntax here..
<http://java.sun.com/j2se/1.4.2/docs/guide/jws/developersguide/
syntax.html#resources>

JWS has also been known to be very finicky
about JNLP files, though frustratingly, it
makes a poor attempt at parsing invalid files,
and if it reports an error at all, it is usually
pointing to an entirely different element..

So, that brings me to the question..
Have you validated this JNLP file?

You might try validating it against the 1.5 DTD

<http://java.sun.com/dtd/JNLP-1.5.dtd >

> Does anybody help me with that problem...?
> Thanks for every hint

BTW - that was a great example you posted,
I would like to have tried it locally, but
unfortunately I do not have the immediate
means to generate the binary.

And another thing.  The JNLP mentions 'bugreport'
in a number of parts.  Have you actually lodged
a bug with Sun against this?  Have you searched
the Bug DB for other related reports?

--
Andrew T.
PhySci.org
Andi - 17 Mar 2008 14:07 GMT
Hi,

I am using a custom classloader because some classes are encrypted. So
I have to decrypt them before.

I have validated the jnlp and it seems to be OK. When I start the
application without my custom classloader it is working perfect.

It is now my second time I added this issue to the sun bug database.
The first time I got an answer that there seems to be a problem but
they need
the source code or a test case to reconstruct it. But I have send it
to them everytime. I think the problem is that it needs a bit time to
deploy this example to reconstruct it.
So I thougt I ask the community in this forum. I could send you my
project. It should be buildable with maven and Visual Studio 2003 or
2005.

Thanks for the answer.
Roedy Green - 17 Mar 2008 13:06 GMT
On Mon, 17 Mar 2008 03:42:42 -0700 (PDT), Andi
<andreas.schneider@skillworks.de> wrote, quoted or indirectly quoted
someone who said :

>I have a big problem to get my Application running on java webstart. I
>have a custom classloader which will be used for some classes. Also I
>need to load a dll which will be used by a native interface.

you might have a look how I handled this problem:

see http://mindprod.com/products1.html#SETCLOCK
Signature


Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Andi - 17 Mar 2008 14:26 GMT
> you might have a look how I handled this problem:
>
> seehttp://mindprod.com/products1.html#SETCLOCK
> --
Can You give me a hint where I should look in your sorce code?
Thanks
Roedy Green - 17 Mar 2008 15:46 GMT
On Mon, 17 Mar 2008 06:26:09 -0700 (PDT), Andi
<andreas.schneider@skillworks.de> wrote, quoted or indirectly quoted
someone who said :

>Can You give me a hint where I should look in your sorce code?
>Thanks

The source code is not likely the problem.

check:

1. the jnlp file.
2. how the dll fits in the jar and how it is named.
3. the load/loadlibrary

see http://mindprod.com/jgloss/jni.html

the native code class is called PCClock.
Signature


Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Andi - 18 Mar 2008 15:00 GMT
On 17 Mrz., 15:46, Roedy Green <see_webs...@mindprod.com.invalid>
wrote:
> On Mon, 17 Mar 2008 06:26:09 -0700 (PDT), Andi
> <andreas.schnei...@skillworks.de> wrote, quoted or indirectly quoted
[quoted text clipped - 18 lines]
> Roedy Green Canadian Mind Products
> The Java Glossaryhttp://mindprod.com

Yes, but that is working fine. When I don't use my custom classloader
everything is working. It is just a problem when I define a class
by myself (see CustomClassLoader / clazz = defineClass(name, buffer,
0, buffer.length); ). Now I have tested that I load all classes with
my custom classloader except the native interface and the class which
calls System.loadLibrary(...). So these classes will be loaded by the
parent classloader, the JNLPClassLoader. Then it is working. It is a
workaround but it didn't solve the problem.
Roedy Green - 20 Mar 2008 06:54 GMT
On Tue, 18 Mar 2008 07:00:50 -0700 (PDT), Andi
<andreas.schneider@skillworks.de> wrote, quoted or indirectly quoted
someone who said :

>Yes, but that is working fine. When I don't use my custom classloader
>everything is working.

Very good.  You have eliminated 75% of what could be going off the
rails.
Signature


Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Roedy Green - 20 Mar 2008 06:41 GMT
On Mon, 17 Mar 2008 03:42:42 -0700 (PDT), Andi
<andreas.schneider@skillworks.de> wrote, quoted or indirectly quoted
someone who said :

>I have a big problem to get my Application running on java webstart. I
>have a custom classloader which will be used for some classes. Also I
>need to load a dll which will be used by a native interface.

I would suggest first writing a simplified test harness that exercises
the native method, without the complication of the custom class
loader.

Have a look at http://mindprod.com/projects1.html#SETCLOCK for a model
of how to use a native class in Java Web Start.  Things to check:

1. name of dll in jar
2. name of dll in jnlp file
3. name of dll in loadlibrary

Make sure you are using the same patterns as I am.

Then be aware that the loadlibrary you do in custom loader X will be
visible only to classes loaded with that loader or its children.
Signature


Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Roedy Green - 20 Mar 2008 06:42 GMT
On Mon, 17 Mar 2008 03:42:42 -0700 (PDT), Andi
<andreas.schneider@skillworks.de> wrote, quoted or indirectly quoted
someone who said :

>I have a big problem to get my Application running on java webstart. I
>have a custom classloader which will be used for some classes. Also I
>need to load a dll which will be used by a native interface.

You might also want to write a test harness for your native class that
does not use Java Web Start. Check out the tips at
http://mindprod.com/jgloss/jni.html
Signature


Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.