Chairperson and Program Coordinator for the Computer Science Technology Program at Dawson College Instructor and Program Consultant for the School of Extended Learning Computer Institute at Concordia University I have been passionate about programming since buying an Apple][+ in 1980. I paid the extra $450 to bring the RAM up to 48K! Ken has posted 16 posts at DZone. You can read more from them at their website. View Full User Profile

NetBeans in the Classroom: You Must Use Maven in the Classroom (Part 3)

08.07.2014
| 2776 views |
  • submit to reddit
Ken Fogel is the Program Coordinator and Chairperson of the Computer Science Technology program at Dawson College in Montreal, Canada. He is also a Program Consultant to and part-time instructor in the Computer Institute of Concordia University's School of Extended Learning. He blogs at omniprogrammer.com and tweets @omniprof. His regular columns about NetBeans in education are listed here.

...and On The Job!

Following on from part 2, in this next article on Maven in the classroom, we will continue looking at the pom.xml file was is created by NetBeans when you chose a Maven JavaFX Application. In the last article we saw that the project was organized into folders according to Maven rather than NetBeans. Sample packages and files were created. Where did they come from?

Maven projects can be defined by templates. They are called Archetypes. These templates can define a pom file, the directory structure and sample files. You can access the archetypes that are included with NetBeans by choosing New Project | Maven | Project from Archetype.

There are a great many Archetypes included in NetBeans. I just want to look at the ones for JavaFX so I used the Search field and entered JavaFX.

The highlighted archetype in the image is ‘javafx’. It is this archetype that NetBeans uses when you create a Maven JavaFX Application. I hope to learn how to create archetypes so that my students can have the modified pom I will present in the next article as part of a Custom Archetype.

Back to the pom.xml

In the pom file the next section belongs to the build tag. The Build is where Plugins are declared. Plugins are modules that can be called upon to perform a particular action during the build of the project. There are four plugins defined in the build section of the pom and they are nested within the plugins tag. The first is the dependency plugin.

<build>
   <plugins>
      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-dependency-plugin</artifactId>
         <version>2.6</version>
         <executions>
            <execution>
               <id>unpack-dependencies</id>
               <phase>package</phase>
               <goals>
                  <goal>unpack-dependencies</goal>
               </goals>
               <configuration>
                  <excludeScope>system</excludeScope>
                  <excludeGroupIds>junit,org.mockito,org.hamcrest</excludeGroupIds>
                  <outputDirectory>${project.build.directory}/classes</outputDirectory>
               </configuration>
            </execution>
         </executions>
      </plugin>

Dependencies are the library files that are required to compile, execute and package the project. The maven-dependency-plugin plugin manages these dependencies. What is interesting about the presence of this plugin is the fact that there are no dependencies defined in this pom. It appears to be here just in case.

This plugin is being used to place the necessary dependency files into the folder called classes. These files will be coming from the local repository. Later in the pom when the project is packaged all of these files will be part of the JAR that the build produces. This action will occur during the package phase of the build when the JAR file is created. I will explain phases in the next article.

There are two exclude tags. The first one, excludeScope, prevents Java system files from being added to the project. The next exclude, excludeGroupIds, list three ids of well know libraries used for unit testing of an application. They should not be included in the executable JAR that will be produced so they are listed here.

One last item to point out. The variable ${project.build.directory} is defined by Maven. There are a number of these variables that Maven defines and NetBeans as well as other IDEs provides the values.

<plugin>
   <groupId>org.codehaus.mojo</groupId>
   <artifactId>exec-maven-plugin</artifactId>
   <version>1.2.1</version>
   <executions>

The exec-maven-plugin plugin is responsible for executing programs during the build, usually the execution of the project itself. There are two programs that are being executed by this plugin.

   <execution>
    <id>unpack-dependencies</id>
    <phase>package</phase>
    <goals>
        <goal>exec</goal>
    </goals>
    <configuration>
        <executable>${java.home}/../bin/javafxpackager</executable>
        <arguments>
            <argument>-createjar</argument>
            <argument>-nocss2bin</argument>
            <argument>-appclass</argument>
            <argument>${mainClass}</argument>
            <argument>-srcdir</argument>
            <argument>${project.build.directory}/classes</argument>
            <argument>-outdir</argument>
            <argument>${project.build.directory}</argument>
            <argument>-outfile</argument>
            <argument>${project.build.finalName}.jar</argument>
        </arguments>
    </configuration>
   </execution>

This first execution section uses the external program javafxpackager to create the executable JAR file. Prior to Java 8 it was the required tool for such a task. The arguments use Maven variables to inform the tool where it can find the files it needs and the information necessary to create the JAR. The argument –noocss2bin indicates that css style sheets will not be stored in the JAR as binary files. They will remain as text files. You can now see why the dependency plugin placed all the dependencies in the classes folder. This is where javafxpackager will find then to include in the jar.

         <execution>
            <id>default-cli</id>
            <goals>
                <goal>exec</goal>                            
            </goals>
            <configuration>
                <executable>${java.home}/bin/java</executable>
                <commandlineArgs>${runfx.args}</commandlineArgs>
            </configuration>
        </execution>
    </executions>  
</plugin>

The second execution section is responsible for running the project. It does this as if it were being run from a command line. This will result in a new instance of the JVM executing on the system and then the JAR is run. The commandLineArgs ${runfx.args} is not a Maven variable. It is defined by NetBeans and unfortunately makes this pom file non-portable and therefore unusable in other IDEs.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.1</version>
    <configuration>
        <source>1.7</source>
        <target>1.7</target>
        <compilerArguments>                           
            <bootclasspath>
                ${sun.boot.class.path}${path.separator}${java.home}/lib/jfxrt.jar
            </bootclasspath>
        </compilerArguments>
    </configuration>
</plugin>

The maven-compiler-plugin permits you to define which version of Java to use for the compiler (source) and what JVM must the class files be compatible with (target). In Java 7 the JavaFX library, jfxrt.jar, was not part of the standard classpath. The bootclasspath adds the library to the path so that the compiler will have access to it.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.16</version>
    <configuration>
        <additionalClasspathElements>                          
            <additionalClasspathElement>
                ${java.home}/lib/jfxrt.jar
            </additionalClasspathElement>
        </additionalClasspathElements>
    </configuration>
</plugin>

The maven-surefire-plugin is responsible for the execution of unit tests. For it to work there must be a dependency on the JUnit library that is not present in this pom file. JUnit testing reports on the success and failure of unit tests. This plugin will write the results into both a text and xml file. If you want some extra pizazz there is an additional plugin that can output the results in HTML.

Now you have some idea about what this pom file does and how it does it. In my next article, I will present a replacement pom file that can only be used with Java 8 but is portable to other IDEs. Plus, it will have dependencies!

Published at DZone with permission of its author, Ken Fogel.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)