Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I speed up maven builds of JavaFX application?

My problem can be reproduced by creating a new project in Netbeans 8:

New Project >> Maven >> JavaFX Application

Then adding the org.springframework spring-context dependency.

Build times go up from a few seconds to more than half a minute, most of it due to running javafxpackager.

I can live with slow release builds but how can I speed up my development builds?

This is my pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org    /2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0     http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.mycompany</groupId>
<artifactId>mavenproject1</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>mavenproject1</name>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <mainClass>com.mycompany.mavenproject1.MainApp</mainClass>
</properties>

<organization>
    <!-- Used as the 'Vendor' for JNLP generation -->
    <name>Your Organisation</name>
</organization>

<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>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.2.1</version>
            <executions>
                <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>
                <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>
        <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>
        <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>
    </plugins>
</build>
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.0.6.RELEASE</version>
    </dependency>
</dependencies>

Thanks! Daniel

like image 495
undertow Avatar asked Aug 05 '14 09:08

undertow


People also ask

Can you use JavaFX with Maven?

If you want to develop JavaFX applications using Maven, you don't have to download the JavaFX SDK. Just specify the modules and the versions you want in the pom.xml , and the build system will download the required modules, including the native libraries for your platform.

Why Maven takes much time for 1st execution and from 2nd execution it will take less time?

Depending on how many dependencies (and its dependencies, called indirect dependencies) your project has it will download all plus the needed dependencies for maven plugins itself. The ones configured in your project and the ones for the normal goals you are executing.

Does Maven support incremental builds?

4) Apache Maven doesn't support incremental builds very well. Because of that fact, most people use mvn clean compile instead of mvn compile for example. This is pretty time consuming and can be improved a lot. The goal is to make mvn compile , mvn verify , mvn install , ...

What does mvn clean do?

mvn clean: Cleans the project and removes all files generated by the previous build. mvn compile: Compiles source code of the project. mvn test-compile: Compiles the test source code. mvn test: Runs tests for the project.


3 Answers

You could define the plugin in a profile that is inactive by default. Then, in order to make the production build, you would have to manually specify the activation of that profile (or activate it in any other standard way).

You pom would be something like (only diffs shown):

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
    ...
    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                ...
                <executions>
                    <!-- take this out of here
                    <execution>
                        <id>unpack-dependencies</id>
                        ...
                    </execution>
                    -->
                    <execution>
                        ...
                    </execution>
                </executions>
            </plugin>
            ...
        </plugins>
    </build>
    <profiles>
        <profile>
            <id>javafxpackager</id>
            <build>
                <plugins>
                    <!-- INSERT THE exec-maven-plugin HERE, ONLY
                         WITH THE unpack-dependencies EXECUTION -->
                </plugins>
            </build>
        </profile>
    </profiles>
</project>

In production run mvn ... -Pjavafxpackager

like image 143
Nikos Paraskevopoulos Avatar answered Oct 03 '22 09:10

Nikos Paraskevopoulos


To complete Nikos' answer, this is the configuration of the maven-assembly-plugin which creates the archive for normal builds.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <appendAssemblyId>false</appendAssemblyId>
        <archive>
            <manifest>
                <mainClass>${mainClass}</mainClass>
            </manifest>
        </archive>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
    </configuration> 
    <executions>
        <execution>
            <id>my-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>assembly</goal>
            </goals>
        </execution>
    </executions>
</plugin>
like image 25
undertow Avatar answered Oct 03 '22 07:10

undertow


above solutions dont work. The problem has nothing to do with javafxpackager whatsoever. The cause lies in the maven standard configuration. On every project run Maven performs a project clean by default. This deletes the targets/classes/ folder. Thats the same folder where all the unpacked jar files of your dependencies are placed. If those get deleted on every new run then they have to be unpacked over and over again. Anyway, heres how you can prevent the clean from happening:

    <plugin>
  <artifactId>maven-clean-plugin</artifactId>
  <version>2.4.1</version>
  <configuration>
    <skip>true</skip>
  </configuration>
</plugin>

Add this to your POM.xml. Make sure you get the version correct You can check the version of your maven clean plugin in the effective pom (thats parent pom + project POM combined). In netbeans you can watch the readonly effective pom.xml under the effective tab when you've opened the pom.xml file of your project.

please give me a few +1's i want to get 50 points so that i can finally comment on other peoples answers. Thank you!

EDIT:

Also add skip to default-cli to avoid errors

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

EDIT 2:

For those of you who would like to retain the ability to clean heres another method to prevent the maven plugin from deleting all jar files:

<plugin>
<artifactId>maven-clean-plugin</artifactId>
     <version>2.4.1</version>
<configuration>
    <excludeDefaultDirectories>true</excludeDefaultDirectories>
    <filesets>
        <!-- delete directories that will be generated when you 
             start the develpment server/client in eclipse  
        -->
        <fileset>
            <directory>target/classes</directory>
            <excludes>
                <exclude>**/*</exclude>
            </excludes>
        </fileset>
    </filesets>
</configuration>

Again, make sure is correct

like image 29
Maurice Avatar answered Oct 03 '22 08:10

Maurice