如何加速JavaFX应用程序的maven构建?

时间:2014-08-05 09:48:24

标签: java spring maven netbeans javafx

我可以通过在Netbeans 8中创建一个新项目来重现我的问题:

新项目>> Maven>> JavaFX应用程序

然后添加org.springframework spring-context依赖项。

构建时间从几秒钟增加到超过半分钟,其中大部分时间是由于运行javafxpackager。

我可以使用缓慢版本的构建,但是如何加快我的开发构建呢?

这是我的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>

谢谢! 丹尼尔

5 个答案:

答案 0 :(得分:3)

您可以在默认情况下处于非活动状态的配置文件中定义插件。然后,为了进行生产构建,您必须手动指定该配置文件的激活(或activate以任何其他标准方式激活它。)

你的pom会像(只显示差异):

<?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>

在生产运行中mvn ... -Pjavafxpackager

答案 1 :(得分:3)

完成Nikos&#39;回答,这是maven-assembly-plugin的配置,它为正常构建创建存档。

<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>

答案 2 :(得分:2)

以上解决方案不起作用。这个问题与javafxpackager无关。原因在于maven标准配置。在每个项目运行中,Maven默认执行项目清理。这会删除targets / classes /文件夹。这是放置依赖项的所有解压缩jar文件的同一文件夹。如果在每次新的运行中都删除了那些,那么必须一遍又一遍地解压缩它们。无论如何,继承人如何防止干净发生:

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

将此添加到您的POM.xml。确保你的版本正确你可以在有效的pom中检查你的maven clean插件的版本(那就是父pom +项目POM的组合)。在netbeans中,当您打开项目的pom.xml文件时,您可以在有效选项卡下查看只读有效的pom.xml。

请给我一些+ 1我希望获得50分,这样我才能最终评论其他人的答案。谢谢!

编辑:

还要将skip添加到default-cli以避免错误

                <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>

编辑2:

对于那些想要保留清理干扰的人,另一种方法可以阻止maven插件删除所有jar文件:

<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>

再次,确保正确

答案 3 :(得分:0)

TL; DR:

为避免解包依赖关系,您根本不需要修改默认的pom.xml。只需在按Run(或Debug)时更改Netbeans的调用即可。在nbactions.xml中进行更改:

  • runfx.args :将-jar "${project.build.directory}/${project.build.finalName}.jar"替换为-cp %classpath ${mainClass}。这样,exec目标将不会尝试执行任何jar,而是从target/classes目录运行您的项目。因此根本不需要构建jar。
  • 目标:用“流程类”(或“测试”或您想要的任何阶段)替换“包装”目标。我们不需要jar,因此不需要运行打包阶段。而且没有包装阶段也意味着没有拆包/重新包装等。

如果您需要具有所有依赖项的jar文件,只需在Netbeans中选择“清理并构建”或运行mvn clean install

背景

在标准Netbeans JavaFX maven项目中按运行时会发生以下情况:

  • 干净的软件包exec-在nbactions.xml中定义,在pom.xml中配置:
    • 干净:照常-删除目标目录
    • 包装:
      • 像往常一样首先-复制资源并将源代码编译为目标/类,然后将所有内容打包到jar中而没有依赖项
      • maven-dependency-plugin将所有依赖项jar文件解压缩到目标/类
      • exec-maven-plugin:unpack-dependencies(ID“ unpack-dependencies”误导性,应该类似于“ jar-with-dependencies”)执行javapackager,该Javapackager生成了一个jar,其依赖项覆盖了第一个jar
    • exec:
      • 使用$ {runfx.args}作为参数(在nbactions.xml中定义)执行Java,即运行jar

上述更改后会发生什么:

  • clean process-classes exec-在nbactions.xml中定义,在pom.xml中配置:
    • 干净:照常-删除目标目录
    • 流程类:
      • 照常-复制资源并将源编译为目标/类
    • exec:
      • 使用$ {runfx.args}作为参数(在nbactions.xml中定义)执行Java,即运行类target / classes / path / to / your / MainClass

更好:

您可能要从nbactions.xml中删除“干净”目标。这样,就不会一次又一次地复制所有资源文件(尽管资源插件仍然会说“正在复制X资源”-请参见https://stackoverflow.com/a/33700970/3519572下的注释)。

现在,您可能还想通过添加useIncrementalCompilation=false(例如,像<goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec -Dmaven.compiler.useIncrementalCompilation=false</goal>)来仅重新编译已更改的类,而不是整个项目。但是请务必阅读https://stackoverflow.com/a/49700942/3519572

因此,您可能还希望向“清理”目标添加工具栏按钮,以便能够随时轻松手动运行它:https://stackoverflow.com/a/26546551/3519572

顺便说一句:

最后,您可能仍然想更改NetBeans生成的pom.xml。至少我的NB 8.2引用了不推荐使用的javafxpackager(重命名为javapackager)。而且<bootclasspath>..../lib/jfxrt.jar</bootclasspath>部分似乎在Java 8中不是必需的。如果我从终端运行它,实际上会破坏我的构建。删除它似乎可以解决问题,并且从NB开始似乎也不会造成任何麻烦。

答案 4 :(得分:0)

您还可以使用并行Maven构建功能来加快速度。

默认情况下,Maven不使用硬件的全部功能。它顺序地而不是并行地构建所有模块。但是,通常您的项目设置不需要顺序设置。通常,您可以命令Maven分析您的项目(包括依赖图),并在可能的情况下并行构建项目。您可以指定用于构建项目的确切线程数,也可以使用该参数的可移植版本,并根据计算机上可用的CPU来指定线程数。

mvn -T 4 install -- will use 4 threads
mvn -T 1C install -- will use 1 thread per available CPU core

有关详情,请参见:https://zeroturnaround.com/rebellabs/your-maven-build-is-slow-speed-it-up/