I had lots of class loader errors many months ago, and I got this fix from a guy.
Basically, it prevents certain classes from being unloaded which should NOT be unloaded.
Feel free to put this at the very startup of your main in your standalone apps.
The symptoms of the problem are class loader errors after a jnlp-launched Swing app has been
running for many many hours. It has to do with the "guts" of the Java runtime
and make sure that things which should NOT be garbage collected, are not
collected. Way over my head !!! But it works.
There's a reference in the code to the Java BUG which this workaround fixes. Feel free
to look at it, but it's easier just do run this routine on startup of your code.
If you deploy your complex apps using Java Web Start, then this may save you.
Just take it "on faith" -- it works.
HyperScalper
// this class must NOT be garbage collected
// and must be retained for lifetime of this app
static JNLPClassLoaderFix jnlpFix = null;
public static void main(String[] args) {
/*
* FIX to JNLP class loader BUG so that we can use runtimes
* greater than Java 6 Update 17
*/
try {
jnlpFix = new JNLPClassLoaderFix();
jnlpFix.fixIt();
}
catch(Exception e) {
e.printStackTrace();
}
// ....... start up your app
}
//package de.bauerkirch.tools.bktimer;
package com.twc.util;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
import com.sun.deploy.cache.CachedJarFile;
// Requires deploy.jar
/**
* Workaround https://bugs.sun.com/view_bug.do?bug_id=6967414
* based on squaat's solution
*
* @author Henning Pautsch, Bauer+Kirch GmbH
*/
public class JNLPClassLoaderFix {
private Set<Object> hardlinkedReferences = new HashSet<Object>();
public boolean fixIt() {
try {
Class<?> clazz = Class.forName("com.sun.jnlp.JNLPClassLoader");
Object jnlpLoader = clazz.getMethod("getInstance").invoke(null);
if (jnlpLoader == null) {
System.out.println("Not running in JNLP-Mode. Ignoring Fix");
return false;
}
Object launchDesc = clazz.getMethod("getLaunchDesc").invoke(jnlpLoader);
Object resources = launchDesc.getClass().getMethod("getResources").invoke(launchDesc);
Object[] allJars = (Object[]) resources.getClass()
.getMethod("getEagerOrAllJarDescs", new Class[] { boolean.class }).invoke(resources, true);
for (Object jarDesc : allJars) {
URL descLocation = (URL) jarDesc.getClass().getMethod("getLocation").invoke(jarDesc);
Method getJarMethod;
CachedJarFile jarFile = null;
getJarMethod = jnlpLoader.getClass().getMethod("getJarFile", new Class[] { URL.class });
getJarMethod.setAccessible(true);
jarFile = (CachedJarFile) getJarMethod.invoke(jnlpLoader, descLocation);
assert (jarFile != null);
Object signersResult = invokePrivateMethod(jarFile, "getSigners");
Object signerMapResult = invokePrivateMethod(jarFile, "getSignerMap");
Object codeSourceCacheResult = invokePrivateMethod(jarFile, "getCodeSourceCache");
hardlinkedReferences.add(signersResult);
hardlinkedReferences.add(signerMapResult);
hardlinkedReferences.add(codeSourceCacheResult);
Object signersRef = getPrivateFieldData(jarFile, "signersRef");
Object signersMapRef = getPrivateFieldData(jarFile, "signerMapRef");
Object codeSourceCacheRef = getPrivateFieldData(jarFile, "codeSourceCacheRef");
hardlinkedReferences.add(signersRef);
hardlinkedReferences.add(signersMapRef);
hardlinkedReferences.add(codeSourceCacheRef);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
return false;
} catch (IllegalArgumentException e) {
e.printStackTrace();
return false;
} catch (SecurityException e) {
e.printStackTrace();
return false;
} catch (IllegalAccessException e) {
e.printStackTrace();
return false;
} catch (InvocationTargetException e) {
e.printStackTrace();
return false;
} catch (NoSuchMethodException e) {
e.printStackTrace();
return false;
}
return true;
}
private Object invokePrivateMethod(final Object object, final String methodName) {
Object result = null;
try {
Method method = object.getClass().getDeclaredMethod(methodName);
method.setAccessible(true);
result = method.invoke(object);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return result;
}
private Object getPrivateFieldData(final Object object, final String fieldName) {
Object result = null;
try {
Field field = object.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
result = field.get(object);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return result;
}
}