lördag 31 mars 2012

JavaFX 2 - Get started with Maven, Eclipse and JavaFX

For a couple of years ago I discovered the power of Maven, and today I can't live without it. Currently I have not found any good Maven plugin for JavaFX. There are a couple which are being developed, but nothing which I find good enough for my needs.

So today we will have a look into how you can setup your own JavaFX project using Maven and Eclipse. Starting with JavaFX dependencies and continue to extend the project so we can build a executable JavaFX JAR.

I assume that you know the basics about Maven and how plugins and dependencies works, otherwise have a look into the "Maven in 5 minutes" totorial, http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html. You will also need to have JDK7 and JavaFX installed on your machine. Otherwise you find them here: http://www.oracle.com/technetwork/java/javafx/downloads/index.html.

First of all we need to create a new project. Start by creating a standard Maven project in Eclipse. If you do not have any Maven plugin in Eclipse I recommend the m2eclipse plugin, http://www.eclipse.org/m2e/. When you have the plugin installed, select a "New project" from the "File" menu, and filter "Maven", select "Maven project".

Select "Maven Project"

Click "Next" and select your workspace, and on the next screen filter for "maven-" and select the quickstart archetype.

Select the "mavenarchetype-quickstart" archetype.

Give you project a group id, artifact id. I used "com.loop81" as group id and "project42" as artifact id. Also assign the package if it is not assign by default. I selected "com.loop81.project42".

Project settings.
Click "Finish" and your project will be created. You will now have a first project structure with a src/main/java, src/test/java folders. Note that you probably will have a warning saying that "Build path specifies execution environment J2SE1-5". Default Maven setup the project with the old Java 1.5 libraries and this is the first thing for us to fix since we like to create a Java 1.7 project.

Open the pom.xml file and select the "pom.xml" tab. After the dependencies add the following:

<build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
    </plugins>
  </build>

This will tell Maven that we like to use Java 1.7 for the source and the compiled results. After the change you need to update you project since you will get a error telling you that the project is not up to date. Right click your project and select "Maven" -> "Update project configuration". You should now have a project without problems. If you have any problems, make sure that you have setup you environment correctly. Under "Installed JREs" (Window -> Preferences -> Java) it should look like:

Installed JREs
Also make sure that you are using the JDK and not the JRE. Without the JDK you will not be able to run Maven as we like, since it requires the tools.jar which is only bundled with the JDK.

If everything has worked you should have a Maven project ready with Java 1.7 enabled. Next thing to do is to add a dependency to JavaFX. Add the following to the pom.xml under dependencies.

<dependency>
      <groupId>com.oracle</groupId>
      <artifactId>javafx-runtime</artifactId>
      <version>2.0.4</version>
      <scope>system</scope>
      <systemPath>C:\Program Files\Oracle\JavaFX 2.0 SDK\rt\lib\jfxrt.jar</systemPath>
    </dependency>

This will add a system dependency to your project. The system path may vary if you have installed the JavaFX binaries in a other folder. Save your pom and you will see that under the "Maven Dependencies" you will have a reference to jfxrt.jar. This means that you now can use JavaFX within your project.

So let's update the "App.java", which Maven created for us to be a JavaFX application. We will only create a simple little application with a label with the text "Maven + JavaFX = true". Update your "App.java" so it looks something like:

public class App extends Application {
 
 @Override
 public void start(Stage stage) throws Exception {
  
  Label label = LabelBuilder.create()
                    .text("Maven + JavaFX = true")
                    .alignment(Pos.CENTER).build();
  
  Scene scene = new Scene(label, 200, 100);
  stage.setScene(scene);
  stage.show();
 }
 
 public static void main(String[] args) {
  Application.launch(args);
 }
}

If you test run your application you should see something like:

I don't think that we will be rich on this application...

Let's imagine that we where done with our application and we would like to give it to the world to run. For that we need a executable JAR. To create this we have three options: Use Netbeans, use Ant or run the command line tool. But we like to use Maven? True so we need to be a bit innovative. When we create a JavaFX application from the command line a couple things are added to our JAR file. Some classes for starting the JavaFX application and a MANIFEST.MF file which tell the WM how it is supposed to run the JAR file. The idea is to use these files with our Maven build to create a executable JavaFX application.

We start by using the command line tool to generate a executable JAR. Open your favorite console. I'm using Cygwin with Mintty on Windows. Navigate to your project and go into the target folder. Type the following:

xxx@main /cygdrive/e/workspace-indigo/project42/target
$ javafxpackager.exe -createjar -appclass com.loop81.project42.App -srcdir classes/ -outfile app

This will create a "app.jar" for you. I will not go into deep of the "javafxpackager" program. More information can be found here: http://docs.oracle.com/javafx/2.0/deployment/packager001.htm#CCHHBCIE. Also to make it run you need to have the bin folder of your JavaFX installation in your path. If you double click "app.jar" it should start and you should see our application. Great now we just need to make Maven build the same for us.

Start by extracting "app.jar". In the extracted content you will find a com folder and a META-INF folder. If you open MANIFEST.MF in the META-INF folder you will find some interesting commands. When you execute a JAR the WM looks for the "Main-Class" property of the file and tries to execute it. In our case we see that it is "com/javafx/main/Main". The "Main" class is the generated JavaFX starter class which the "javafxpackager" created for us. This class control if you jave JavaFX installed on your computer and then starts your application by using the property "JavaFX-Application-Class". Whit this in our mind, couldn't we use this class and let Maven create a MANIFEST.MF for us? Exactly what we will do.

Now we will copy the files under com/javafx to your project. Create a new source folder in Eclipse and name it "src/main/resources/". Place the javafx folder here. If you take a look on the folder in the "Navigator" it should look like:

The copied "FX classes" at the correct place.

These classes will when we build the project be copied into the target folder and be usable like they where in the original JAR archive. We are now close to reach our goal of using Maven to create a executable JavaFX JAR for us, but first we need to tell Maven how to create the MANIFEST.MF.

Open the "pom.xml" and under the pluings add the following:

<plugin> 
 <artifactId>maven-assembly-plugin</artifactId>
   <configuration>
     <archive>
       <manifestEntries>
         <JavaFX-Version>2.0</JavaFX-Version>
         <JavaFX-Application-Class>com.loop81.project42.App</JavaFX-Application-Class> 
          <Main-Class>com/javafx/main/Main</Main-Class>
       </manifestEntries>
     </archive>
     <descriptorRefs>
       <descriptorRef>jar-with-dependencies</descriptorRef>
     </descriptorRefs>                  
   </configuration>
 </plugin>

This will tell Maven to create a manifest which contains the JavaFX main class and our application class, and include all dependencies of our project into the JAR. Now run the maven command assembly:assembly goal to create your JAR. When Maven is done you will find your JAR file in the target folder. My file was named "E:\workspace-indigo\project42\target\project42-0.0.1-SNAPSHOT-jar-with-dependencies.jar". Finally we are there. Try to run your JAR. If everything has worked out well you application should start.

In this post we have seen how we can use Maven to build executable JARs of our JavaFX applications. By using the created classes from the "javafxpackager" we can let Maven create a executable JAR which uses those classes to start our applications.

Inga kommentarer:

Skicka en kommentar