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