sexta-feira, 11 de novembro de 2016

JBoss Modules with JavaFX

Anton Arhipov made a great post showing a Hello World app with JBoss modules. In his post comments, Ted Won created a "mavenized" version of his hello world. Since my friend Filipe Portes already made a great work by integrating JavaFX with OSGI, I decided to try jboss-modules 

In this post I simply used Ted's project with JavaFX(with some modifications) and it worked great!  

First obvious attempt:

  •  Clone Ted's project: 

git clone

  • Import his maven project on an IDE. I used Eclipe (File -> Import -> Existing Maven Project)

  • Let's develop now. Modify the Hello class to be a JavaFX application class:
  • Now build the project. Go back to the  hello directory in the command line and run mvn clean package
  • Once the project is built, copy the new hello jar to the modules directory: cp hello/target/hello.jar  mods/org/jbugkorea/hello/main/ 
  • Cool, but if you try to run now, you will have an exception:
Exception in thread "main" java.lang.NoClassDefFoundError: Failed to link org/jbugkorea/hello/Hello (Module "org.jbugkorea.hello:main" from local module loader @27ddd392 (finder: local module finder @19e1023e (roots: /opt/projects/hello-jboss-modules/mods))): javafx/application/Application at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance( at sun.reflect.DelegatingConstructorAccessorImpl.newInstance( at java.lang.reflect.Constructor.newInstance( at org.jboss.modules.ModuleClassLoader.defineClass( at org.jboss.modules.ModuleClassLoader.loadClassLocal( at org.jboss.modules.ModuleClassLoader$1.loadClassLocal( at org.jboss.modules.Module.loadModuleClass( at org.jboss.modules.ModuleClassLoader.findClass( at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked( at org.jboss.modules.ConcurrentClassLoader.performLoadClass( at org.jboss.modules.ConcurrentClassLoader.loadClass( at at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke( at sun.reflect.DelegatingMethodAccessorImpl.invoke( at java.lang.reflect.Method.invoke( at at org.jboss.modules.Main.main(

Making it work

The reason why we have this error is because JavaFX is not on JDK classpath. What I am going to say on next steps is for jboss modules and JavaFX learning purposes, you must contact Oracle if you want to ship their JavaFX implementation.

An easier way to solve this is by creating a new module for jfxrt.jar:
  • Create a new directory for the JavaFX module, create a module.xml file and copy the jfxrt.jar to this directory. 
  • JavaFX depends on several JRE classes. I had to create a javax.api module from a Wildfly installation inside mods. I just copied it from a local wildfly installation: 
mkdir -p mods/javax/api/main/
cp /opt/jboss/WILDFLY/wildfly-8.2.0.Final/modules/system/layers/base/javax/api/main/module.xml mods/javax/api/main/
  • JavaFX make use of other internal sun libraries that are not included in javax.api module. You may add it at the end of javax.api modules.xml dependencies declaration:
  • Now make hello dependent on JavaFX module and javaFX module dependent on javafx.api module. See below how your mods directory strucuture should look like:
  • Finally run and you should see JavaFX stage:

This is not a final application for JavaFX with JBoss modules because we may face other ClassNotFound or LinkageError during runtime and javax.api  will have to be adjusted in order to add the new dependencies. It was, however, a fun and useful hack to learn more about jboss modules.

Nenhum comentário:

Postar um comentário