java - 使用 Maven 为 SWT 应用程序构建多平台可执行文件

标签 java maven jar swt multi-module

我的问题是:如何使用 maven 一次根据目标操作系统/体系结构为 SWT 应用程序生成多个可执行 Jar 文件(包括依赖项)?

我创建了一个 SWT 应用程序,它必须在不同的操作系统和架构上运行。该项目是一个包含父 POM 的 Maven 多模块项目。

project-pom.xml (packaging = pom, specify SWT dependencies)
`- application-module (inherit SWT dependencies)
   `- pom.xml (packaging = jar)
`- domain-specific-module
   `- pom.xml (packaging = jar)
`- utils-module (inherit SWT dependencies)
   `- pom.xml (packaging = jar)

In the parent POM (project-pom.xml) I've included the SWT dependencies according to my os and architecture using maven profiles which works fine:

<dependencies>
    <dependency>
        <groupId>org.eclipse.swt</groupId>
        <artifactId>${swt.artifactId}</artifactId>
        <version>4.3</version>
    </dependency>
</dependencies>

<repositories>
    <repository>
        <id>EclipseSwtRepository</id>
        <url>https://swt-repo.googlecode.com/svn/repo/</url>
    </repository>
</repositories>

<profiles>
    <profile>
        <id>unix-amd64</id>
        <activation>
            <os>
                <family>unix</family>
                <arch>amd64</arch>
            </os>
        </activation>
        <properties>
            <swt.artifactId>org.eclipse.swt.gtk.linux.x86_64</swt.artifactId>
        </properties>
    </profile>
    <profile>
        <id>windows-x86</id>
        <activation>
            <os>
                <family>windows</family>
                <arch>x86</arch>
            </os>
        </activation>
        <properties>
            <swt.artifactId>org.eclipse.swt.win32.win32.x86</swt.artifactId>
        </properties>
    </profile>
    <profile>
        <id>windows-x86_64</id>
        <activation>
            <os>
                <family>windows</family>
                <arch>x86_64</arch>
            </os>
        </activation>
        <properties>
            <swt.artifactId>org.eclipse.swt.win32.win32.x86_64</swt.artifactId>
        </properties>
    </profile>
</profiles>

现在 maven 选择正确的 SWT 依赖项,例如用于编译应用程序。我已经使用 Maven 命令 mvn help:active-profiles 检查了 Activity 配置文件。

现在我想为目标平台 linux_x86_64/amd64、windows_x86 和 windows_x86_64 生成可执行 Jars。在第一步中,我使用了 maven-jar-plugin生成 Jar 和 list 文件 (application-module/pom.xml):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.4</version>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <classpathPrefix>libs/</classpathPrefix>
                 <mainClass>qualified.path.to.MyApplication</mainClass>
            </manifest>
        </archive>
    </configuration>
</plugin>

这很好用。 Jar 已生成, list 在其中。如您所见,我的意图是将所有依赖项放在名为 lib/ 的目录中。但是 Jar 文件不可执行(缺少库)。

下一步(理论上)是在 package 阶段找到依赖项并将它们复制到 die lib/ 目录中。对于这一步,我(试图)使用 maven-dependency-plugin (application-module/pom.xml):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>2.8</version>
    <executions>
        <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/libs</outputDirectory>
                <overWriteReleases>false</overWriteReleases>
                <overWriteSnapshots>false</overWriteSnapshots>
                <overWriteIfNewer>true</overWriteIfNewer>
            </configuration>
        </execution>
    </executions>
</plugin>

如果我运行命令 mvn package 没有任何反应(没有在 target/ 或其他地方创建目录)。为了检查插件是否正常工作,我使用了命令 mvn dependency:copy-dependencies 它创建了一个名为 dependency 的目录(我假设这个插件的默认值)并放置所有相关的 Jar 文件都在那里。

这是我遇到的第一个问题。下一个问题是,我如何根据我的 SWT 应用程序的目标操作系统/体系结构同时创建多个(不仅仅是一个)可执行 Jar 文件(使用一个命令,如 mvn package)?构建目录的结果结构应类似于以下内容:

target/
`- linux_x86_64/
   `- application-version_linux_x86_64.jar
   `- libs/
      `- org.eclipse.swt.gtk.linux.x86_64-4.3.jar
      `- ...
`- windows_x86/
   `- application-version_windows_x86.jar
   `- libs/
      `- org.eclipse.swt.win32.win32.x86-4.3.jar
      `- ...
`- windows_x86_64/
   `- application-version_x86_64.jar
   `- libs/
      `- org.eclipse.swt.win32.win32.x86_64-4.3.jar
      `- ...

另一种解决方案是将依赖项直接放在 Jar 文件中,但目前我不知道如何做到这一点。

我在这方面阅读了一些其他插件(maven-assembly-plugin、maven-shade-plugin),但目前这些信息对我来说太多了,无法检查它是否有效。谁能告诉我哪个插件最适合我的目的?

最终完成后,我想使用 launch4j-maven-plugin生成 native windows 可执行文件(最终用户不喜欢非 native 可执行文件的感觉)使用之前生成的 windows 可执行 Jar 文件。

我希望这些信息足够了。

最佳答案

我通过研究 JackRabbit 使用 Maven 完成了此操作的设置。 JackRabbit 以各种形式(独立、OSGi bundle 、web 应用程序等)交付,并且全部通过一个聚合器 pom 完成。

第一步是将带有配置文件和公共(public)依赖项的父 pom 与定义项目子模块(顺序)的聚合器 pom 分开。聚合器 pom 中的第一个子模块通常是父 pom。聚合器 pom 的优点是您可以使用聚合器 pom 运行 Maven,一次性为您的项目构建所有内容。

接下来我创建了一个“公共(public)程序集资源”项目,它生成一个包含所有资源(例如自述文件、手册、图片等)的 jar,这些资源在平台的所有程序集中使用。每个平台组装项目都会提取这个 jar,然后将提取的文件复制到适当的位置。据我所知,JackRabbit 不会这样做,因此您可以跳过这一步。

最后,为每个平台创建一个单独的平台组装子模块。在平台组件中,您可以设置您想要和不想要的依赖项。子模块可以包含特定于平台的文件(例如,Windows 的批处理文件、Linux 的 .sh 文件)。程序集形式可以特定于平台(例如 Windows 的 .zip 和 Linux 的 .tar.gz)。对于 Windows,我还包括了 NSIS创建一个 setup.exe(您也可以在安装了 NSIS 软件包的 Linux 上构建它)。

我在不同阶段的设置中大量使用了 maven-dependency-plugin。我经常使用的一个是 process-resources 阶段,您可以尝试使用 package 阶段。

关于java - 使用 Maven 为 SWT 应用程序构建多平台可执行文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21285598/

相关文章:

java - Struts 2 "<s:if>"标签无法按预期工作

java - 无法初始化类 com.amazonaws.services.sqs.AmazonSQSClient

java - Maven 构建不同于依赖树

android - 如何找出apk文件中使用的Jar?

java - 从同一文件夹中的 JAR 访问文件

java - 具有适当终止条件的 java.lang.StackOverflowError 的原因是什么?

java - 云Firestore : Add Field Value To Document

java - android-哪个线程在SensorChanged上运行?

java - 如何解决错误 : java. lang.BootstrapMethodError : java. lang.NoClassDefFoundError: io/vertx/core/Promise

java - 来自现有 jar 的 Eclipse 插件