Re: javapackager - partially self-contained apps in JDK 9

2017-04-25 Thread Chris Bensen
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  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  wrote:
>> 
>> 
>>> On Apr 11, 2017, at 10:43 AM, Alan Snyder  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:
>> 
>> 
>> 
>> 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
> 



Re: javapackager - partially self-contained apps in JDK 9

2017-04-25 Thread Chris Bensen

> On Apr 11, 2017, at 10:43 AM, Alan Snyder  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:



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

Re: javapackager - partially self-contained apps in JDK 9

2017-04-25 Thread Scott Palmer

> On Apr 11, 2017, at 1:43 PM, Alan Snyder  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?

My application ran into classpath issues because it tried to dynamically add 
plugins to the classpath and that broke on Java 9.  To work around it I created 
an agent so I could get access to the java.lang.Instrumentation interface to 
add to the classpath.  You might try that approach.  It’s ugly, but better than 
reflectively accessing private fields of URLClassLoader, which doesn’t work for 
Java 9 :-)

Scott



javapackager - partially self-contained apps in JDK 9

2017-04-25 Thread Alan Snyder
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