【问题标题】:appassembler-maven-plugin - how to include native library files when generating scripts for Windows and Unixappassembler-maven-plugin - 如何在为 Windows 和 Unix 生成脚本时包含本机库文件
【发布时间】:2023-03-27 04:46:01
【问题描述】:

您好,我正在开发一个使用 appassembler-maven-plugin 构建到分发文件(zip 文件)中的 Java 应用程序。最终用户提取 zip 的内容。

使用这个插件,我们构建了一个分发结构,其中包括所需的 jar 和两个执行脚本(一个用于 unix 的 shell 脚本和一个用于 windows 的批处理脚本)。这些脚本由构建过程自动生成。

pom 文件包含以下内容:

    ...
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <attach>true</attach>
                <descriptors>
                    <descriptor>src/main/resources/distribution.xml</descriptor>
                </descriptors>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <!-- this is used for inheritance merges -->
                    <phase>package</phase>
                    <!-- bind to the packaging phase -->
                    <goals>
                        <goal>assembly</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>appassembler-maven-plugin</artifactId>
            <executions>
                <execution>
                    <id>assemble-standalone</id>
                    <phase>package</phase>
                    <goals>
                        <goal>assemble</goal>
                    </goals>
                    <configuration>
                        <programs>
                            <program>
                                <name>mixnet</name>
                                <mainClass>com.company.products.Application</mainClass>
                            </program>
                        </programs>
                        <repositoryLayout>flat</repositoryLayout>
                        <repositoryName>lib</repositoryName>
                        <configurationDirectory>properties</configurationDirectory>
                        <binFileExtensions>
                            <unix>.sh</unix>
                        </binFileExtensions>
                        <copyConfigurationDirectory>true</copyConfigurationDirectory>
                        <configurationSourceDirectory>src/main/resources</configurationSourceDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
            <executions>
                <execution>
                    <id>attach-distribution</id>
                    <phase>package</phase>
                    <goals>
                        <goal>attach-artifact</goal>
                    </goals>
                    <configuration>
                        <artifacts>
                            <artifact>
                                <file>target/${project.artifactId}-${project.version}-distribution.zip</file>
                                <type>zip</type>
                            </artifact>
                        </artifacts>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>

生成的 shell 脚本包含以下对 Java 进行实际调用的行:

%JAVACMD% %JAVA_OPTS% %EXTRA_JVM_ARGUMENTS% -classpath%CLASSPATH_PREFIX%;%CLASSPATH% -Dapp.name="mixnet" -Dapp.repo="%REPO%" -Dbasedir="%BASEDIR%" com.company.products.Application %CMD_LINE_ARGS%

批处理脚本包含以下对 Java 进行实际调用的行:

exec "$JAVACMD" $JAVA_OPTS \
  $EXTRA_JVM_ARGUMENTS \
 -classpath "$CLASSPATH" \
 -Dapp.name="mixnet" \
 -Dapp.pid="$$" \
 -Dapp.repo="$REPO" \
 -Dapp.home="$BASEDIR" \
 -Dbasedir="$BASEDIR" \
  com.company.products.Application \
  "$@"

我们现在扩展了 Java 程序,使其使用本地库文件,这些文件包含在分发中名为“native”的文件夹中(Windows 的 .dll 文件和 unix 环境的 .so 文件包含在本机中目录)

我想编辑构建过程,以便生成的脚本(unix 的 shell 脚本和 windows 的批处理脚本)包含参数“-Djava.library.path=PATH_OF_LIBRARY_FILES”。

我进行了一些搜索,但在 appassembler 插件中找不到任何有关支持此参数的文档。

我试图通过将“extraJvmArguments”标签添加到应用程序 pom 文件并在那里指定“-Djava.library.path”参数来找到一个“hacky”解决方案,但我遇到了路径分隔符不同的问题在 Windows 和 linux 上(“\”或“/”)。我还考虑过使用“extraJvmArguments”并使用系统变量来指定目录的路径(必须由用户定义),但是这种方法也存在平台问题,因为在 linux 上使用 $VARIABLE_NAME 引用了系统变量,但在 Windows 上使用 %VARIABLE_NAME%。

我们可以要求最终用户在执行脚本之前自己编辑执行脚本,但如果该过程是自动的,并且对最终用户完全透明,那就更好了。这样,最终用户甚至不会知道他们正在运行一个 Java 应用程序,该应用程序正在使用 JNI 调用本机库。

我不知道任何平台中立的解决方案。 appassembler 是否已经支持此要求?或者应该如何处理?

【问题讨论】:

  • 你能证明 pom 文件可能是一个不能按你喜欢的方式工作的示例项目吗?
  • 我添加了 pom 内容

标签: maven jvm building appassembler


【解决方案1】:

根据maven-assembly-pluginsourcesherehere,单一设置&lt;repositoryName&gt;lib&lt;/repositoryName&gt;同时控制java.library.path和jar类路径目录。

请随意投票支持功能请求以将它们分开:

Option to have native libraries in separate directory, not visible in classpath #62

【讨论】:

    【解决方案2】:

    我找到了一种获得所需结果的方法,但它涉及复制 pom.xml 的很大一部分。我复制了执行部分,并在每次执行中添加了一个特定于平台的 extraJvmArguments 值,如下所示。然后,构建过程会使用正确的平台特定路径构建执行脚本。

                <executions>
                    <execution>
                        <id>assemble-standalone-windows</id>
                        <phase>package</phase>
                        <goals>
                            <goal>assemble</goal>
                        </goals>
                        <configuration>
                            <extraJvmArguments>-Djava.library.path=.\..\native\lib</extraJvmArguments>
                            <programs>
                                <program>
                                    <platforms>
                                        <platform>windows</platform>
                                    </platforms>
                                    <name>mixnet</name>
                                    <mainClass>com.company.products.Application</mainClass>
                                </program>
                            </programs>
                            <repositoryLayout>flat</repositoryLayout>
                            <repositoryName>lib</repositoryName>
                            <configurationDirectory>properties</configurationDirectory>
                            <binFileExtensions>
                                <unix>.sh</unix>
                            </binFileExtensions>
                            <copyConfigurationDirectory>true</copyConfigurationDirectory>
                            <configurationSourceDirectory>src/main/resources</configurationSourceDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>assemble-standalone-unix</id>
                        <phase>package</phase>
                        <goals>
                            <goal>assemble</goal>
                        </goals>
                        <configuration>
                            <extraJvmArguments>-Djava.library.path=./../native/lib</extraJvmArguments>
                            <programs>
                                <program>
                                    <platforms>
                                        <platform>unix</platform>
                                    </platforms>
                                    <name>mixnet</name>
                                    <mainClass>com.scytl.products.ov.mixnet.Application</mainClass>
                                </program>
                            </programs>
                            <repositoryLayout>flat</repositoryLayout>
                            <repositoryName>lib</repositoryName>
                            <configurationDirectory>properties</configurationDirectory>
                            <binFileExtensions>
                                <unix>.sh</unix>
                            </binFileExtensions>
                            <copyConfigurationDirectory>true</copyConfigurationDirectory>
                            <configurationSourceDirectory>src/main/resources</configurationSourceDirectory>
                        </configuration>
                    </execution>
                </executions>
    

    如果您知道解决问题的更好方法,请分享。

    【讨论】:

      【解决方案3】:

      这是来自官方网站的示例:https://maven.apache.org/plugins/maven-assembly-plugin/usage.html

              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-assembly-plugin</artifactId>
                  <version>2.5.1</version>
                  <configuration>
                      <descriptorRefs>
                          <descriptorRef>jar-with-dependencies</descriptorRef>
                      </descriptorRefs>
                      <archive>
                          <manifest>
                              <mainClass>your main class</mainClass>
                          </manifest>
                      </archive>
                  </configuration>
                  <executions>
                      <execution>
                          <id>make-assembly</id> <!-- this is used for inheritance merges -->
                          <phase>package</phase> <!-- bind to the packaging phase -->
                          <goals>
                              <goal>single</goal>
                          </goals>
                      </execution>
                  </executions>
              </plugin>
      

      【讨论】:

      • 这与问题有什么关系?
      猜你喜欢
      • 2011-01-06
      • 1970-01-01
      • 1970-01-01
      • 2013-10-25
      • 2019-09-11
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2021-01-07
      相关资源
      最近更新 更多