SWT comes with a base JAR and one specific JAR per platform (Windows, Linux/32bit, Linux/64bit, Mac, AIX, ...). How can I create an executable JAR that will select the correct platform JAR at runtime?
[EDIT] I was thinking to supply all platform JARs in a subdirectory and in main()
would then modify the class loader. Has anyone already tried this?
For my current job I needed to supply an executable jar that could load jars inside itself and execute a second main(). Basically a bootstrap main() and an application main().
Step 1. in the manifest "main-class" you put your bootstrap class
Step 2. When your bootstrap class runs it unjar's its own jar and all jars inside it to a temp directory. Use something like the line below to get your own jar.
Main.class.getProtectionDomain().getCodeSource().getLocation().toURI()
Step 3. Your bootstrap class detects the OS via the "os.name" property and loads the appropriate jars from the temp directory with this
private static void loadJarIntoClassloader( URL u ) throws Exception
{
URLClassLoader sysLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class<URLClassLoader> sysclass = URLClassLoader.class;
Method method = sysclass.getDeclaredMethod("addURL", URL.class);
method.setAccessible(true);
method.invoke(sysLoader, new Object[]{u});
}
Step 4. Now you should be able to run your application by calling the application main().
NOTE: This little hack depends on your JVM using URLClassLoader
as its SystemClassLoader, which is true for Sun JVMs, not for sure on others.
This way you can deliver a single jar only, and it will unpack itself and run with the correct jars.