UnsatisfiedLinkError using Java Webstart with custom classloader

Discussion in 'Java' started by Andi, Mar 17, 2008.

  1. Andi

    Andi Guest

    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, Mar 17, 2008
    #1
    1. Advertising

  2. Andi

    Andi Guest

    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)
     
    Andi, Mar 17, 2008
    #2
    1. Advertising

  3. On Mar 17, 9:42 pm, Andi <> wrote:
    ...
    > 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.
    >
    > Here my jnlp:
    >
    > <?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+"
    >   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"/>


    * 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
     
    Andrew Thompson, Mar 17, 2008
    #3
  4. Andi

    Roedy Green Guest

    On Mon, 17 Mar 2008 03:42:42 -0700 (PDT), Andi
    <> 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
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Mar 17, 2008
    #4
  5. Andi

    Andi Guest

    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.
     
    Andi, Mar 17, 2008
    #5
  6. Andi

    Andi Guest

    >
    > 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
     
    Andi, Mar 17, 2008
    #6
  7. Andi

    Roedy Green Guest

    On Mon, 17 Mar 2008 06:26:09 -0700 (PDT), Andi
    <> 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.
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Mar 17, 2008
    #7
  8. Andi

    Andi Guest

    On 17 Mrz., 15:46, Roedy Green <>
    wrote:
    > On Mon, 17 Mar 2008 06:26:09 -0700 (PDT), Andi
    > <> 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
    >
    > seehttp://mindprod.com/jgloss/jni.html
    >
    > the native code class is called PCClock.
    > --
    >
    > 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.
     
    Andi, Mar 18, 2008
    #8
  9. Andi

    Roedy Green Guest

    On Mon, 17 Mar 2008 03:42:42 -0700 (PDT), Andi
    <> 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.
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Mar 20, 2008
    #9
  10. Andi

    Roedy Green Guest

    On Mon, 17 Mar 2008 03:42:42 -0700 (PDT), Andi
    <> 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
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Mar 20, 2008
    #10
  11. Andi

    Roedy Green Guest

    On Mon, 17 Mar 2008 03:46:13 -0700 (PDT), Andi
    <> 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
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Mar 20, 2008
    #11
  12. Andi

    Roedy Green Guest

    On Tue, 18 Mar 2008 07:00:50 -0700 (PDT), Andi
    <> 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.
    --

    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
     
    Roedy Green, Mar 20, 2008
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Lorin Hochstein
    Replies:
    2
    Views:
    1,803
    Lorin Hochstein
    Mar 5, 2004
  2. Replies:
    2
    Views:
    355
    Richard Maher
    Mar 8, 2008
  3. TsanChung
    Replies:
    0
    Views:
    1,454
    TsanChung
    Sep 4, 2008
  4. TsanChung
    Replies:
    8
    Views:
    3,113
    anandmadhab
    Sep 30, 2011
  5. Replies:
    5
    Views:
    1,381
    Roedy Green
    Jun 18, 2012
Loading...

Share This Page