UnsatisfiedLinkError using Java Webstart with custom classloader
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