JOGL TempJarCache natives jars already in classpath

classic Classic list List threaded Threaded
6 messages Options
sam
Reply | Threaded
Open this post in threaded view
|

JOGL TempJarCache natives jars already in classpath

sam
hi,

I try to use JOGL in a standalone environment. I know that using the TempJarCache, JOGL automatically tries to find and load the native library jars. However in my current situation I already have the right platform specific native jar package in my class path.

But JOGL still tries to load the external native jar, which is impossible as I had to rename it, breaking the search conventions.

Any ideas how to fix that, such that JOGL extracts the native libraries already part of its classpath?

thanks in advance

Reply | Threaded
Open this post in threaded view
|

Re: JOGL TempJarCache natives jars already in classpath

gouessej
Administrator
Hi

You can disable the automatic extraction of native libraries, set the Java library path and use the DLL/SO,JNILIB files i.e the old way, like in JOGL 1. The JARs containing the native libraries shouldn't be in the classpath, they just have to be in the same directory than the JARs containing the Java libraries. Renaming the JARs containing the native libraries is a bad idea, just don't do that, we can't support all the conventions.
Julien Gouesse | Personal blog | Website
sam
Reply | Threaded
Open this post in threaded view
|

Re: JOGL TempJarCache natives jars already in classpath

sam
Hi,

I fully understand that JOGL can't test every possible convention.

Inspired by your idea just to put the native libraries side by side to the jars. I manually extract the native libraries from the included jars right before I initialize jogl

private void extractJOGLLibraries() {
	final File dir = new File(".");
	ClassLoader classLoader = SandBoxLauncher.class.getClassLoader();
	for(String lib : Arrays.asList("gluegen-rt","jogl_desktop","jogl_mobile","nativewindow_awt","nativewindow_win32","newt") ) {
		String nativeLib = System.mapLibraryName(lib);
		File file = new File(dir,nativeLib);
		try (InputStream in = classLoader.getResourceAsStream(nativeLib);
				OutputStream to = new BufferedOutputStream(new FileOutputStream(file))) {
			ByteStreams.copy(in, to);
		} catch (IOException e) {
			System.err.println("can't extract: " + nativeLib);
			e.printStackTrace();
		}
		file.deleteOnExit();
	}
}

Reply | Threaded
Open this post in threaded view
|

Re: JOGL TempJarCache natives jars already in classpath

gouessej
Administrator
I'm happy to see that it works for you now. Maybe Sven has a better suggestion, it would be better if you used the build-in mechanism of GlueGen that already works in applets and Java Web Start.
Julien Gouesse | Personal blog | Website
sam
Reply | Threaded
Open this post in threaded view
|

Re: JOGL TempJarCache natives jars already in classpath

sam
gouessej wrote
I'm happy to see that it works for you now. Maybe Sven has a better suggestion, it would be better if you used the build-in mechanism of GlueGen that already works in applets and Java Web Start.
another interesting idea,

I looked up the code and there is already some special hook to specify a custom library loader. The advantage is using this custom library loader I can extract the files to a temporary directory instead of the primary one + I don't need to now the exact file names.

code

1. before starting JOGL set that it should use a custom library loader:
System.setProperty("jnlp.launcher.class", SandBoxLibraryLoader.class.getCanonicalName());

2. the code of SandBoxLibraryLoader:
public final class SandBoxLibraryLoader {
	/**
	 * extract the given library of the classpath and put it to a temporary file
	 */
	public static File toTemporaryFile(String libName) throws IOException {
		// convert to native library name
		libName = System.mapLibraryName(libName);

		// create
		String extension = Files.getFileExtension(libName);
		File file = File.createTempFile(StringUtils.removeEnd(libName, extension), "." + extension);
		file.deleteOnExit();

		URL res = SandBoxLibraryLoader.class.getResource("/" + libName);
		if (res == null)
			throw new FileNotFoundException("can't extract: " + libName);
		try (InputStream in = res.openStream();
				OutputStream to = new BufferedOutputStream(new FileOutputStream(file))) {
			ByteStreams.copy(in, to);
		} catch (IOException e) {
			System.err.println("can't extract: " + libName);
			e.printStackTrace();
			throw new FileNotFoundException("can't extract: " + libName);
		}
		return file;
	}

	/**
	 * convention for custom library loader
	 */
	public static void loadLibrary(String libName) throws IOException {
		File file = toTemporaryFile(libName);
		// use System.load as it supports absolute file paths
		System.load(file.getAbsolutePath());
	}
}
                       
Reply | Threaded
Open this post in threaded view
|

Re: JOGL TempJarCache natives jars already in classpath

Sven Gothel
Administrator
On 08/14/2013 04:10 PM, sam [via jogamp] wrote:

>     gouessej wrote
>     I'm happy to see that it works for you now. Maybe Sven has a better
>     suggestion, it would be better if you used the build-in mechanism of
>     GlueGen that already works in applets and Java Web Start.
>
> another interesting idea,
>
> I looked up the code and there is already some special hook to specify a
> custom library loader. The advantage is using this custom library loader I can
> extract the files to a temporary directory instead of the primary one + I
> don't need to now the exact file names.
.. and last but definetly not least: 'com.jogamp.common.util.JarUtil.Resolver',
which currently allows one to resolve a non std protocol.

We may be able to add a similar 'plugin' to resolve the
native library name, i.e. in case you have a different naming scheme.
Still, I would only 'allow' this to change the native jar basename,
i.e. keeping the URI location intact (protocol, server and path).

IMHO this should solve the problem for any jar/native-jar name-space
combinations, while still using the jar/native-jar concept.

?

>
> code
>
> 1. before starting JOGL set that it should use a custom library loader:
>
> System.setProperty("jnlp.launcher.class", SandBoxLibraryLoader.class.getCanonicalName());

Note: We may remove 'jnlp.launcher.class' due to security considerations ..
undecided yet.

~Sven


signature.asc (911 bytes) Download Attachment