From: <ka...@us...> - 2010-04-01 21:01:58
|
Revision: 3305 http://java-game-lib.svn.sourceforge.net/java-game-lib/?rev=3305&view=rev Author: kappa1 Date: 2010-04-01 21:01:51 +0000 (Thu, 01 Apr 2010) Log Message: ----------- Allow LWJGL applets to work when seperate_jvm parameter is not supported (i.e. java plugin1). Modified Paths: -------------- trunk/LWJGL/src/java/org/lwjgl/util/applet/AppletLoader.java Modified: trunk/LWJGL/src/java/org/lwjgl/util/applet/AppletLoader.java =================================================================== --- trunk/LWJGL/src/java/org/lwjgl/util/applet/AppletLoader.java 2010-04-01 18:27:51 UTC (rev 3304) +++ trunk/LWJGL/src/java/org/lwjgl/util/applet/AppletLoader.java 2010-04-01 21:01:51 UTC (rev 3305) @@ -52,6 +52,7 @@ import java.io.StringWriter; import java.io.Writer; import java.lang.reflect.Constructor; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.JarURLConnection; @@ -68,6 +69,7 @@ import java.security.cert.Certificate; import java.util.Enumeration; import java.util.StringTokenizer; +import java.util.Vector; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; @@ -233,6 +235,9 @@ "Please accept the permissions dialog to allow", "the applet to continue the loading process."}; + /** have natives been loaded by another instance of this applet */ + static protected boolean natives_loaded = false; + /* * @see java.applet.Applet#init() */ @@ -736,13 +741,67 @@ }; debug_sleep(2000); - + + // unload natives loaded by a previous instance of this lwjgl applet + unloadNatives(path); + // add natives files path to native class path System.setProperty("org.lwjgl.librarypath", path + "natives"); // Make sure jinput knows about the new path too System.setProperty("net.java.games.input.librarypath", path + "natives"); + + // mark natives as loaded + natives_loaded = true; } + + /** + * Unload natives loaded by a different classloader. + * + * Due to limitations of the jvm, native files can only + * be loaded once and only be used by the classloader + * they were loaded from. + * + * Due to the way applets on plugin1 work, one jvm must + * be used for all applets. We need to use multiple + * classloaders in the same jvm due to LWJGL's static + * nature. I order to solver this we simply remove the + * natives from a previous classloader allowing a new + * classloader to use those natives in the same jvm. + * + * This method will only attempt to unload natives from a + * previous classloader if it detects that the natives have + * been loaded in the same jvm. + * + * @param nativePath directory where natives are stored + */ + private void unloadNatives(String nativePath) { + + // check whether natives have been loaded into this jvm + if (!natives_loaded) { + return; + } + + try { + Field field = ClassLoader.class.getDeclaredField("loadedLibraryNames"); + field.setAccessible(true); + Vector libs = (Vector) field.get(getClass().getClassLoader()); + + String path = new File(nativePath).getCanonicalPath(); + + for (int i = 0; i < libs.size(); i++) { + String s = (String) libs.get(i); + + // if a native from the nativePath directory is loaded, unload it + if (s.startsWith(path)) { + libs.remove(i); + i--; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } /** * replace the current applet with the lwjgl applet This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |