javapackager - partially self-contained apps in JDK 9
Chris Bensen
chris.bensen at oracle.com
Tue Apr 25 18:32:26 UTC 2017
> 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