The Enterprise Side of JavaFX: The Missing Part

Setup the Swing client

Move JavaFX template files and add dependencies

Select all files you find in the com.martinandersson.something package in your FXTemplate, and move them to the corresponding package in the SomeApp-app project:

.

Drag and drop files

.

In the dialog box that NetBeans display after this trick, I check the option Move Without Refactoring. When you’re done, you’ll see all hell brake lose in MainFX.java and somethingController.java since some import statements in these files cannot be resolved. Right-click on the SomeApp-app project and select Properties. Click on the Libraries tree node to your left. The tab opened to your right is called Compile. Click on the button labeled Add JAR/Folder. Add the JavaFX Runtime library jfxrt.jar. On my machine, I found the JAR file here:

C:\Program Files\Java\jdk1.7.0_21\jre\lib

The Package checkbox is probably checked. But we don’t need to package the JavaFX Runtime library with our application client. If our end user doesn’t already have the JavaFX Runtime library, it will be downloaded automatically when the user launch the application client through Java Web Start. So uncheck the Package checkbox!

Still in the Project Properties dialog, click on Add Project… and add the SomeApp-lib project! This project, or class library, contains the @Remote annotated interface our application client needs to know about.

Don’t leave the Project Properties dialog just yet. When an application client is launched through Java Web Start, GlassFish should force the client to download all the libraries the Application Client Contained needs. What might be due to the packaging trick we’re doing here, that isn’t the case if you would proceed without adding yet another library. Instead your client would have crashed with an exception being thrown:

java.lang.ClassNotFoundException: javax.persistence.PersistenceUnit

So click on Add JAR/Folder and browse your way to..

C:\glassfish3\glassfish\modules

..or whatever is more applicable on your machine. Select the JAR file that begins with something like javax.persistence. On my machine, I found this JAR file:

javax.persistence_2.0.4.v201112161009.jar

This library should be packaged together with our application client, thus make sure the Package option is checked. Now it is safe for you to click on all OK buttons you see until you get back to the IDE and hopefully all red lines will disappear. They didn’t? Let me know by commenting on this blog post! Try to find a solution first and then share.

Move and customize the JNLP file

Earlier when you built the FXTemplate Project, NetBeans created a JNLP file we shall include with the application client we intend to package together with our EAR package. Begin by clicking on the Files tab in the NetBeans IDE and get a file based view of your projects. Browse to the FXTemplate > dist folder. If you don’t see the file here, or perhaps you don’t even have a dist folder to begin with, try building the project again.

Move the FXTemplate.jnlp file to SomeApp-app > src > conf. After this operation, NetBeans will begin to include this file in the distributed jar file under a subfolder called META-INF. Rename the file to something more appropriate, say custom.jnlp.

Go back to the projects tab and delete the FXTemplate project. This project should by now be completely empty and of no use to us. You should also be able to see the custom.jnlp file in the projects tab under SomeApp-app > Configuration Files.

The contents in custom.jnlp are mostly complete but we need to fix some things. Open custom.jnlp in your IDE and go to line 2. Change the href attribute to custom.jnlp. Decomment if you will, line 7. Write a title on line 4. On line 14, you will see a reference to FXTemplate.jar. Change that file name to SomeApp-app.jar. Also, since the size attribute is most likely wrong, and the size attribute is optional anyways, just remove the size attribute. Rename the name attribute on line 19 and 22. You might wonder what implications the main-class attribute has on line 22. I haven’t figure that out myself, but it seems to not matter much since the holy Oracle documentation says:

The main-class attribute can be omitted if the first JAR file specified in the JNLP file contains a manifest file containing the main class.

Indeed I have with experience proven that the application will work just like we intend for it to work whether we reference the MainFX class or the MainSwing class in this attribute. So I find it convenient to just leave it as is.

Notice how NetBeans produced two XML elements called resources? If you will, you can refactor those into just one. Again my experience taught me there isn’t nothing wrong leaving them duplicated.

When you’re done hacking the file, it should look something like this:

.
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0" xmlns:jfx="http://javafx.com" href="custom.jnlp">
  <information>
    <title>JavaFXApp</title>
    <vendor>Martin Andersson</vendor>
    <description>Sample JavaFX 2.0 application.</description>
    <!--<offline-allowed/>-->
  </information>
  <resources>
    <jfx:javafx-runtime version="2.2+" href="http://javadl.sun.com/webapps/download/GetFile/javafx-latest/windows-i586/javafx2.jnlp"/>
    <j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se"/>
    <jar href="SomeApp-app.jar" download="eager" />
  </resources>
<security>
  <all-permissions/>
</security>
  <applet-desc  width="800" height="600" main-class="com.javafx.main.NoJavaFXFallback"  name="JavaFXApp" >
    <param name="requiredFXVersion" value="2.2+"/>
  </applet-desc>
  <jfx:javafx-desc  width="800" height="600" main-class="com.martinandersson.something.MainFX"  name="JavaFXApp" />
  <update check="always"/>
</jnlp>
.

10 thoughts on “The Enterprise Side of JavaFX: The Missing Part

  1. mauro

    hi your blog it is very very interessant.
    But how you resolve the problem with the call at remote ejb or application client on a glassfish behind a firewall ?

    For example i would download and use the appclient and the glassfish it is on a another macheine extenal at the internal net but on intenet .
    go at :
    https://www.java.net//forum/topic/glassfish/glassfish/ejb-remote-deployed-gf-31-behind-nat-unaccessible
    for view the problem .
    tanl you very much for your attention
    Mauro

    Reply
    1. martinandersson.com Post author

      I have no solution to your problem. Actually I haven’t read your URL:s, just looked over them briefly. However, all kinds of remoting is always troublesome if you’re behind a firewall. HTTP wired web services has no issue since they talk on port 80, almost always unblocked, and I believe this is the chief reason they have gained so much in popularity. So the moment a firewall gives you a headache, just expose the EJB as a web service. There is nothing stopping you from combining @WebService with @Stateless.

      Reply
  2. Pingback: JavaFX links of the week, July 22 // JavaFX News, Demos and Insight // FX Experience

  3. AFX

    Grymt martin! Keep it up!
    Nice kodat, och nu ska jag ta och kolla igenom resten av bloggen;) Man blir ju sugen på att börja koda själv fan. Verkar skitkul.

    Reply
  4. R

    Hi. Thanks for this blog post. It is really helpful. I’ve managed to run it inside the Netbeans. Unfortunately I’ve failed to do it outside the Netbeans. I used Glassfish appclient. I have the following errors……


    Exception in thread "main" java.lang.NoClassDefFoundError: javafx/application/Application
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.access$100(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at org.glassfish.appclient.client.acc.ACCClassLoader.findClass(ACCClassLoader.java:212)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at com.joy.azura.Sly.main(Sly.java:23)
    Caused by: java.lang.ClassNotFoundException: javafx.application.Application
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at org.glassfish.appclient.client.acc.ACCClassLoader.findClass(ACCClassLoader.java:212)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 13 more

    In line 14 (Sly.java:23) my code is

    javafx.application.Application.launch(SlyFX.class, args);

    I’m able to execute it inside the Netbeans. Thus, I think there is a way to do it outside of the Netbeans.

    Reply
    1. martinandersson.com Post author

      Could it be that the Application Client Container (ACC) cannot find your JavaFX runtime? And when you say “outside of NetBeans”, I hope you mean using Java Web Start? Please review page 8 and see if it helps. And be sure to upgrade your JDK installed if it is anywhere below 1.7.0_6.

      Reply
      1. R

        Thanks for your prompt reply. I was using the old next to obsolete method. “asadmin …get-client-stubs… appclient …” so you will have the lighter Glassfish on the client’s computer. Then to execute the Client side type “appclient.bat -jar MyApp-Client.jar” in command line. I have a fat client which needed to work offline. Fortunately requirements have changed. Now I have decided to switch to RESTful Web Service. That one has much better option. Thanks again.

        Reply
  5. Jeff

    Hi

    Is this still required/workable in Java/JavaFX 8, Glassfish 4.1 and netbeans 8.02?

    I quickly run through this tutorial in them and could not get it to work. I get a non specific security violation when the webstart finishes downloading and attempts to run it.

    Thanks!

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *