aboutsummaryrefslogtreecommitdiffstats
path: root/netx
diff options
context:
space:
mode:
authorAdam Domurad <[email protected]>2013-06-03 10:34:36 -0400
committerAdam Domurad <[email protected]>2013-06-03 10:34:36 -0400
commit58464afe42ef3f0558da034bece3a7800f9104ff (patch)
tree8635f31393ee772b81e977af1549e4d242feccfe /netx
parent1c3034421f64b802cef7b30c44b8524b36255e2f (diff)
Extract NativeLibraryStorage class from JNLPClassLoader
Diffstat (limited to 'netx')
-rw-r--r--netx/net/sourceforge/jnlp/cache/NativeLibraryStorage.java162
-rw-r--r--netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java139
2 files changed, 175 insertions, 126 deletions
diff --git a/netx/net/sourceforge/jnlp/cache/NativeLibraryStorage.java b/netx/net/sourceforge/jnlp/cache/NativeLibraryStorage.java
new file mode 100644
index 0000000..ef0bd82
--- /dev/null
+++ b/netx/net/sourceforge/jnlp/cache/NativeLibraryStorage.java
@@ -0,0 +1,162 @@
+package net.sourceforge.jnlp.cache;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+import net.sourceforge.jnlp.util.FileUtils;
+
+/**
+ * Handles loading and access of native code loading through a JNLP application or applet.
+ * Stores native code in a temporary folder.
+ * Be sure to call cleanupTemporayFolder when finished with the object.
+ */
+public class NativeLibraryStorage {
+ private ResourceTracker tracker;
+ private List<File> nativeSearchDirectories = new ArrayList<File>();
+
+ /* Temporary directory to store native jar entries, added to our search path */
+ private File jarEntryDirectory = null;
+
+ public NativeLibraryStorage(ResourceTracker tracker) {
+ this.tracker = tracker;
+ }
+
+ /**
+ * Clean up our temporary folder if we created one.
+ */
+ public void cleanupTemporaryFolder() {
+ if (jarEntryDirectory != null) {
+ if (JNLPRuntime.isDebug()) {
+ System.out.println("Cleaning up native directory" + jarEntryDirectory.getAbsolutePath());
+ }
+ try {
+ FileUtils.recursiveDelete(jarEntryDirectory,
+ new File(System.getProperty("java.io.tmpdir")));
+ jarEntryDirectory = null;
+ } catch (IOException e) {
+ /*
+ * failed to delete a file in tmpdir, no big deal (as well the VM
+ * might be shutting down at this point so no much we can do)
+ */
+ }
+ }
+ }
+
+ /**
+ * Adds the {@link File} to the search path of this {@link NativeLibraryStorage}
+ * when trying to find a native library
+ */
+ public void addSearchDirectory(File directory) {
+ nativeSearchDirectories.add(directory);
+ }
+
+ public List<File> getSearchDirectories() {
+ return nativeSearchDirectories;
+ }
+
+ /**
+ * Looks in the search directories for 'fileName',
+ * returning a path to the found file if it exists.
+ * Returns null otherwise.
+ */
+ public File findLibrary(String fileName) {
+ for (File dir : getSearchDirectories()) {
+ File target = new File(dir, fileName);
+ if (target.exists())
+ return target;
+ }
+ return null;
+ }
+
+ /**
+ * Search for and enable any native code contained in a JAR by copying the
+ * native files into the filesystem. Called in the security context of the
+ * classloader.
+ */
+ public void addSearchJar(URL jarLocation) {
+ if (JNLPRuntime.isDebug())
+ System.out.println("Activate native: " + jarLocation);
+
+ File localFile = tracker.getCacheFile(jarLocation);
+ if (localFile == null)
+ return;
+
+ String[] librarySuffixes = { ".so", ".dylib", ".jnilib", ".framework", ".dll" };
+
+ try {
+ JarFile jarFile = new JarFile(localFile, false);
+ Enumeration<JarEntry> entries = jarFile.entries();
+
+ while (entries.hasMoreElements()) {
+ JarEntry e = entries.nextElement();
+
+ if (e.isDirectory()) {
+ continue;
+ }
+
+ String name = new File(e.getName()).getName();
+ boolean isLibrary = false;
+
+ for (String suffix : librarySuffixes) {
+ if (name.endsWith(suffix)) {
+ isLibrary = true;
+ break;
+ }
+ }
+ if (!isLibrary) {
+ continue;
+ }
+
+ ensureNativeStoreDirectory();
+
+ File outFile = new File(jarEntryDirectory, name);
+ if (!outFile.isFile()) {
+ FileUtils.createRestrictedFile(outFile, true);
+ }
+ CacheUtil.streamCopy(jarFile.getInputStream(e),
+ new FileOutputStream(outFile));
+ }
+
+ jarFile.close();
+ } catch (IOException ex) {
+ if (JNLPRuntime.isDebug())
+ ex.printStackTrace();
+ }
+ }
+
+ private void ensureNativeStoreDirectory() {
+ if (jarEntryDirectory == null) {
+ jarEntryDirectory = createNativeStoreDirectory();
+ addSearchDirectory(jarEntryDirectory);
+ }
+ }
+
+ /**
+ * Create a random base directory to store native code files in.
+ */
+ private static File createNativeStoreDirectory() {
+ final int rand = (int)((Math.random()*2 - 1) * Integer.MAX_VALUE);
+ File nativeDir = new File(System.getProperty("java.io.tmpdir")
+ + File.separator + "netx-native-"
+ + (rand & 0xFFFF));
+ File parent = nativeDir.getParentFile();
+ if (!parent.isDirectory() && !parent.mkdirs()) {
+ return null;
+ }
+
+ try {
+ FileUtils.createRestrictedDirectory(nativeDir);
+ return nativeDir;
+ } catch (IOException e) {
+ return null;
+ }
+ }
+}
diff --git a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
index dee9115..46212d7 100644
--- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
@@ -82,6 +82,7 @@ import net.sourceforge.jnlp.SecurityDesc;
import net.sourceforge.jnlp.Version;
import net.sourceforge.jnlp.cache.CacheUtil;
import net.sourceforge.jnlp.cache.IllegalResourceDescriptorException;
+import net.sourceforge.jnlp.cache.NativeLibraryStorage;
import net.sourceforge.jnlp.cache.ResourceTracker;
import net.sourceforge.jnlp.cache.UpdatePolicy;
import net.sourceforge.jnlp.security.AppVerifier;
@@ -127,11 +128,8 @@ public class JNLPClassLoader extends URLClassLoader {
* initialization of applets that share a unique key*/
private static Map<String, ReentrantLock> uniqueKeyToLock = new HashMap<String, ReentrantLock>();
- /** the directory for native code */
- private File nativeDir = null; // if set, some native code exists
-
- /** a list of directories that contain native libraries */
- private List<File> nativeDirectories = Collections.synchronizedList(new LinkedList<File>());
+ /** Provides a search path & temporary storage for native code */
+ private NativeLibraryStorage nativeLibraryStorage;
/** security context */
private AccessControlContext acc = AccessController.getContext();
@@ -231,6 +229,8 @@ public class JNLPClassLoader extends URLClassLoader {
this.updatePolicy = policy;
this.resources = file.getResources();
+ this.nativeLibraryStorage = new NativeLibraryStorage(tracker);
+
this.mainClass = mainName;
AppVerifier verifier;
@@ -270,21 +270,7 @@ public class JNLPClassLoader extends URLClassLoader {
* there is one). Other classloaders (parent, peers) will all
* cleanup things they created
*/
- if (nativeDir != null) {
- if (JNLPRuntime.isDebug()) {
- System.out.println("Cleaning up native directory" + nativeDir.getAbsolutePath());
- }
- try {
- FileUtils.recursiveDelete(nativeDir,
- new File(System.getProperty("java.io.tmpdir")));
- } catch (IOException e) {
- /*
- * failed to delete a file in tmpdir, no big deal (not
- * to mention that the VM is shutting down at this
- * point so no much we can do)
- */
- }
- }
+ nativeLibraryStorage.cleanupTemporaryFolder();
}
});
}
@@ -1349,7 +1335,7 @@ public class JNLPClassLoader extends URLClassLoader {
}
// some programs place a native library in any jar
- activateNative(jar);
+ nativeLibraryStorage.addSearchJar(jar.getLocation());
}
return null;
@@ -1360,114 +1346,14 @@ public class JNLPClassLoader extends URLClassLoader {
}
/**
- * Search for and enable any native code contained in a JAR by copying the
- * native files into the filesystem. Called in the security context of the
- * classloader.
- */
- protected void activateNative(JARDesc jar) {
- if (JNLPRuntime.isDebug())
- System.out.println("Activate native: " + jar.getLocation());
-
- File localFile = tracker.getCacheFile(jar.getLocation());
- if (localFile == null)
- return;
-
- String[] librarySuffixes = { ".so", ".dylib", ".jnilib", ".framework", ".dll" };
-
- try {
- JarFile jarFile = new JarFile(localFile, false);
- Enumeration<JarEntry> entries = jarFile.entries();
-
- while (entries.hasMoreElements()) {
- JarEntry e = entries.nextElement();
-
- if (e.isDirectory()) {
- continue;
- }
-
- String name = new File(e.getName()).getName();
- boolean isLibrary = false;
-
- for (String suffix : librarySuffixes) {
- if (name.endsWith(suffix)) {
- isLibrary = true;
- break;
- }
- }
- if (!isLibrary) {
- continue;
- }
-
- if (nativeDir == null)
- nativeDir = getNativeDir();
-
- File outFile = new File(nativeDir, name);
- if (!outFile.isFile()) {
- FileUtils.createRestrictedFile(outFile, true);
- }
- CacheUtil.streamCopy(jarFile.getInputStream(e),
- new FileOutputStream(outFile));
-
- }
- jarFile.close();
- } catch (IOException ex) {
- if (JNLPRuntime.isDebug())
- ex.printStackTrace();
- }
- }
-
- /**
- * Return the base directory to store native code files in.
- * This method does not need to return the same directory across
- * calls.
- */
- protected File getNativeDir() {
- final int rand = (int)((Math.random()*2 - 1) * Integer.MAX_VALUE);
- nativeDir = new File(System.getProperty("java.io.tmpdir")
- + File.separator + "netx-native-"
- + (rand & 0xFFFF));
- File parent = nativeDir.getParentFile();
- if (!parent.isDirectory() && !parent.mkdirs()) {
- return null;
- }
-
- try {
- FileUtils.createRestrictedDirectory(nativeDir);
- // add this new native directory to the search path
- addNativeDirectory(nativeDir);
- return nativeDir;
- } catch (IOException e) {
- return null;
- }
- }
-
- /**
- * Adds the {@link File} to the search path of this {@link JNLPClassLoader}
- * when trying to find a native library
- */
- protected void addNativeDirectory(File nativeDirectory) {
- nativeDirectories.add(nativeDirectory);
- }
-
- /**
- * Returns a list of all directories in the search path of the current classloader
- * when it tires to find a native library.
- * @return a list of directories in the search path for native libraries
- */
- protected List<File> getNativeDirectories() {
- return nativeDirectories;
- }
-
- /**
* Return the absolute path to the native library.
*/
protected String findLibrary(String lib) {
String syslib = System.mapLibraryName(lib);
+ File libFile = nativeLibraryStorage.findLibrary(syslib);
- for (File dir : getNativeDirectories()) {
- File target = new File(dir, syslib);
- if (target.exists())
- return target.toString();
+ if (libFile != null) {
+ return libFile.toString();
}
String result = super.findLibrary(lib);
@@ -2044,8 +1930,9 @@ public class JNLPClassLoader extends URLClassLoader {
addToCodeBaseLoader(extLoader.file.getCodeBase());
// native search paths
- for (File nativeDirectory : extLoader.getNativeDirectories())
- addNativeDirectory(nativeDirectory);
+ for (File nativeDirectory : extLoader.nativeLibraryStorage.getSearchDirectories()) {
+ nativeLibraryStorage.addSearchDirectory(nativeDirectory);
+ }
// security descriptors
for (URL key : extLoader.jarLocationSecurityMap.keySet()) {