javapackager - partially self-contained apps in JDK 9

Chris Bensen chris.bensen at oracle.com
Tue Apr 25 21:04:57 UTC 2017


The code that I included below will do what you want with modular JARs. I hope to get this as a feature of the Java Packager which would be called Pugins, but there’s only so much time, which is why I provided you with a portion of my prototype code.

Chris


> On Apr 25, 2017, at 12:11 PM, Alan Snyder <javalists at cbfiddle.com> wrote:
> 
> The whole point is not to include the connector JAR in the bundled app, so that it can upgraded independently.
> 
> I tried setting -classpath using fx:jvmuserarg, the app crashed (exit 1) on startup.
> 
> I really wonder why this case is not handled in some convenient way.
> 
> 
> 
> 
>> On Apr 25, 2017, at 11:32 AM, Chris Bensen <chris.bensen at oracle.com> wrote:
>> 
>> 
>>> On Apr 11, 2017, at 10:43 AM, Alan Snyder <javalists at cbfiddle.com> wrote:
>>> 
>>> I have run into a problem in moving my macOS apps from JDK 8 to 9. The issue relates to using MySQL via JDBC.
>>> The connector class name is fixed. The class is loaded using Class.forName(). However, there can be different versions
>>> of the connector in different JAR files, and the proper version might need to be synced with the currently installed version
>>> of MySQL.
>>> 
>>> In JDK 8, I used the extension mechanism to load the MySQL connector JAR rather than building this JAR into the bundled app.
>>> My thinking was that the connector might need to be updated in sync with the database and I should not have to rebuild apps to do that.
>>> 
>>> In JDK 9, the extension mechanism is gone. I have not found any way to achieve the equivalent effect. It seems that javapackager
>>> controls the setting of the CLASSPATH. I have not found an option that would allow me to extend the CLASSPATH with a directory
>>> where the connector JAR could be found. Is there a way to do this?
>>> 
>>> Alan
>>> 
>> 
>> 
>> Are you including the connector JAR in the app image?
>> 
>> I think you could set the classpath if you us ant-javafx.jar:
>> 
>> <fx:jvmuserarg name=“-classpath" value=“...”/>
>> 
>> but honestly I’ve never tried it with JDK 9.
>> 
>> A JDK 9 way of dynamically loading this would be to create a Layer. Here’s some semi working code you could use:
>> 
>> 
>>   public Plugin loadPlugin(String module, String classname) {
>>       Plugin result = null;
>>       Configuration cf = resolve(file.getAbsoluteFile().getParentFile().toPath(), name);
>>       ClassLoader scl = ClassLoader.getSystemClassLoader();
>>       Layer layer = Layer.boot().defineModulesWithOneLoader(cf, scl);
>>       ClassLoader cl = layer.findLoader(name);
>> 
>>       try {
>>           result = createPlugin(layer, name, classname);
>>           result.load();
>>           plugins.add(result);
>>       }
>>       catch (Exception e) {
>>           System.out.println("oh no!" + e.toString());
>>       }
>> 
>>       return result;
>>   }
>> 
>>   private static Configuration resolve(Path modulepath, String... roots) {
>>       ModuleFinder finder = ModuleFinder.of(modulepath);
>>       return Layer.boot()
>>           .configuration()
>>           .resolve(finder, ModuleFinder.of(), Set.of(roots));
>>   }
>> 
>>   private static Plugin createPlugin(Layer layer, String mn, String mc) throws Exception {
>>       ClassLoader loader = layer.findLoader(mn);
>>       Class<?> c = loader.loadClass(mc);
>>       Plugin p = (Plugin)c.getConstructor().newInstance();
>>       return p;
>>   }
>> 
>> Chris
> 



More information about the openjfx-dev mailing list