英文:
maven dylib resource put in sources jar file, not "compiled" jar file
问题
当我使用mvn package
构建我的包并使用mvn install
本地安装时,它会将我在编译的JAR中指定的资源包含在内。
安装的文件:
存档:~/.m2/repository/cam/narzt/getargv/Getargv/0.1-SNAPSHOT/Getargv-0.1-SNAPSHOT.jar
长度 日期 时间 名称
--------- ---------- ----- ----
0 2023-03-03 11:25 META-INF/
81 2023-03-03 11:25 META-INF/MANIFEST.MF
0 2023-03-03 11:18 cam/
0 2023-03-03 11:18 cam/narzt/
0 2023-03-03 11:18 cam/narzt/getargv/
0 2023-03-03 11:25 META-INF/maven/
0 2023-03-03 11:25 META-INF/maven/cam.narzt.getargv/
0 2023-03-03 11:25 META-INF/maven/cam.narzt.getargv/Getargv/
1542 2023-03-03 11:18 cam/narzt/getargv/Main.class
3596 2023-03-03 11:18 cam/narzt/getargv/NativeLoader.class
4350 2023-03-03 11:18 cam/narzt/getargv/Getargv.class
34152 2023-03-03 11:25 libcam_narzt_getargv_Getargv.dylib
10309 2023-03-03 11:18 META-INF/maven/cam.narzt.getargv/Getargv/pom.xml
66 2023-03-03 11:19 META-INF/maven/cam.narzt.getargv/Getargv/pom.properties
--------- -------
54096 14个文件
但是当我将我的包发布到Maven中央仓库时,使用mvn release:clean release:prepare && mvn release:perform
,它会将资源放在源代码JAR中,如何指示它们应该包含在编译的JAR中?
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>cam.narzt.getargv</groupId>
<artifactId>Getargv</artifactId>
<version>0.2-SNAPSHOT</version>
<name>${project.artifactId}</name>
<url>https://getargv.narzt.cam</url>
<description>JNI bindings for libgetargv</description>
<inceptionYear>2023</inceptionYear>
<organization>
<name>Getargv</name>
<url>https://github.com/getargv</url>
</organization>
<developers>
<developer>
<id>CamJN</id>
<name>Camden Narzt</name>
<email>getargv@narzt.cam</email>
<url>https://getargv.narzt.cam</url>
<organization>Getargv</organization>
<organizationUrl>https://https://github.com/getargv</organizationUrl>
<roles>
<role>developer</role>
</roles>
<timezone>America/Edmonton</timezone>
<properties>
<picUrl>https://avatars.githubusercontent.com/u/6243207</picUrl>
</properties>
</developer>
</developers>
<issueManagement>
<system>Github</system>
<url>https://github.com/getargv/getargv.java/issues/</url>
</issueManagement>
<ciManagement>
<system>Github</system>
<url>https://github.com/getargv/getargv.java/actions</url>
</ciManagement>
<scm>
<connection>scm:git:https://github.com/getargv/getargv.java.git</connection>
<developerConnection>scm:git:ssh://github.com/getargv/getargv.java.git</developerConnection>
<tag>HEAD</tag>
<url>https://github.com/getargv/getargv.java</url>
</scm>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
<licenses>
<license>
<name>BSD-3-Clause</name>
<url>https://spdx.org/licenses/BSD-3-Clause.html</url>
<distribution>repo</distribution>
<comments>Allows: Commercial use, Distribution, Modification, and Private use; License and copyright notice required</comments>
</license>
</licenses>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>$(java.specification.version)</maven.compiler.target>
<maven.compiler.release>${java.specification.version}</maven.compiler.release>
<exec.mainClass>${project.groupId}.Main</exec.mainClass>
<fqn_underscores>cam_narzt_getargv_${project.artifactId}</fqn_underscores>
<fqn_slashes>cam/narzt/getargv/${project.artifactId}</fqn_slashes>
<gpg_keyname>E45D816B</gpg_keyname>
<javah_cli_args>-h ${project.build.directory}/native/include -d ${java.io.tmpdir} --source-path ${project.build.sourceDirectory} ${project.build.sourceDirectory}/${fqn_slashes}.java</javah_cli_args>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.9.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies
<details>
<summary>英文:</summary>
When I build my package with `mvn package` and install locally with `mvn install`, it includes the resources I specify in the compiled jar.
Files that get installed:
Archive: ~/.m2/repository/cam/narzt/getargv/Getargv/0.1-SNAPSHOT/Getargv-0.1-SNAPSHOT.jar
Length Date Time Name
0 03-03-2023 11:25 META-INF/
81 03-03-2023 11:25 META-INF/MANIFEST.MF
0 03-03-2023 11:18 cam/
0 03-03-2023 11:18 cam/narzt/
0 03-03-2023 11:18 cam/narzt/getargv/
0 03-03-2023 11:25 META-INF/maven/
0 03-03-2023 11:25 META-INF/maven/cam.narzt.getargv/
0 03-03-2023 11:25 META-INF/maven/cam.narzt.getargv/Getargv/
1542 03-03-2023 11:18 cam/narzt/getargv/Main.class
3596 03-03-2023 11:18 cam/narzt/getargv/NativeLoader.class
4350 03-03-2023 11:18 cam/narzt/getargv/Getargv.class
34152 03-03-2023 11:25 libcam_narzt_getargv_Getargv.dylib
10309 03-03-2023 11:18 META-INF/maven/cam.narzt.getargv/Getargv/pom.xml
66 03-03-2023 11:19 META-INF/maven/cam.narzt.getargv/Getargv/pom.properties
54096 14 files
But when I release my package to maven central `mvn release:clean release:prepare && mvn release:perform`, it puts the resources in the sources jar instead, how can i indicate that they should go in the compiled jar?
pom.xml:
```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>cam.narzt.getargv</groupId>
<artifactId>Getargv</artifactId>
<version>0.2-SNAPSHOT</version>
<name>${project.artifactId}</name>
<url>https://getargv.narzt.cam</url>
<description>JNI bindings for libgetargv</description>
<inceptionYear>2023</inceptionYear>
<organization>
<name>Getargv</name>
<url>https://github.com/getargv</url>
</organization>
<developers>
<developer>
<id>CamJN</id>
<name>Camden Narzt</name>
<email>getargv@narzt.cam</email>
<url>https://getargv.narzt.cam</url>
<organization>Getargv</organization>
<organizationUrl>https://https://github.com/getargv</organizationUrl>
<roles>
<role>developer</role>
</roles>
<timezone>America/Edmonton</timezone>
<properties>
<picUrl>https://avatars.githubusercontent.com/u/6243207</picUrl>
</properties>
</developer>
</developers>
<issueManagement>
<system>Github</system>
<url>https://github.com/getargv/getargv.java/issues/</url>
</issueManagement>
<ciManagement>
<system>Github</system>
<url>https://github.com/getargv/getargv.java/actions</url>
</ciManagement>
<scm>
<connection>scm:git:https://github.com/getargv/getargv.java.git</connection>
<developerConnection>scm:git:ssh://github.com/getargv/getargv.java.git</developerConnection>
<tag>HEAD</tag>
<url>https://github.com/getargv/getargv.java</url>
</scm>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
<licenses>
<license>
<name>BSD-3-Clause</name>
<url>https://spdx.org/licenses/BSD-3-Clause.html</url>
<distribution>repo</distribution>
<comments>Allows: Commercial use, Distribution, Modification, and Private use; License and copyright notice required</comments>
</license>
</licenses>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>$(java.specification.version)</maven.compiler.target>
<maven.compiler.release>${java.specification.version}</maven.compiler.release>
<exec.mainClass>${project.groupId}.Main</exec.mainClass>
<fqn_underscores>cam_narzt_getargv_${project.artifactId}</fqn_underscores>
<fqn_slashes>cam/narzt/getargv/${project.artifactId}</fqn_slashes>
<gpg_keyname>E45D816B</gpg_keyname>
<javah_cli_args>-h ${project.build.directory}/native/include -d ${java.io.tmpdir} --source-path ${project.build.sourceDirectory} ${project.build.sourceDirectory}/${fqn_slashes}.java</javah_cli_args>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.9.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>${project.build.directory}/native/lib</directory>
<includes>
<include>**</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.13</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://s01.oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>true</autoReleaseAfterClose>
</configuration>
</plugin>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.0</version>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
<configuration>
<keyname>${gpg_keyname}</keyname>
</configuration>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<target>
<delete dir="${project.build.directory}/native/lib" />
<mkdir dir="${project.build.directory}/native/lib" />
</target>
</configuration>
<executions>
<execution>
<id>createLibDir</id>
<phase>process-resources</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>1.0-alpha-11</version>
<extensions>true</extensions>
<configuration>
<jdkIncludePath>${java.home}/include</jdkIncludePath>
<sources>
<source>
<directory>${basedir}/src/main/native</directory>
<fileNames>
<fileName>${fqn_underscores}.c</fileName>
</fileNames>
</source>
<source>
<directory>${project.build.directory}/native/include</directory>
</source>
</sources>
<compilerProvider>generic</compilerProvider>
<compilerExecutable>clang</compilerExecutable>
<compilerStartOptions>
<compilerStartOption>-fPIC</compilerStartOption>
</compilerStartOptions>
<compilerMiddleOptions>
<compilerMiddleOption>-g</compilerMiddleOption>
</compilerMiddleOptions>
<compilerEndOptions>
<compilerEndOption>-I</compilerEndOption>
<compilerEndOption>${java.home}/include</compilerEndOption>
<compilerEndOption>-I</compilerEndOption>
<compilerEndOption>${java.home}/include/darwin</compilerEndOption>
</compilerEndOptions>
<linkerExecutable>clang</linkerExecutable>
<linkerStartOptions>
<linkerStartOption>-dynamiclib</linkerStartOption>
</linkerStartOptions>
<linkerMiddleOptions>
<linkerMiddleOption>-g</linkerMiddleOption>
</linkerMiddleOptions>
<linkerEndOptions>
<linkerEndOption>-lgetargv</linkerEndOption>
</linkerEndOptions>
<linkerOutputDirectory>${project.build.directory}/native/lib</linkerOutputDirectory>
<linkerFinalName>lib${fqn_underscores}</linkerFinalName>
<linkerFinalNameExt>dylib</linkerFinalNameExt>
</configuration>
<executions>
<execution>
<id>dylib</id>
<phase>compile</phase>
<goals>
<goal>initialize</goal>
<goal>compile</goal>
<goal>link</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
<extensions>true</extensions>
<configuration>
<executable>javac</executable>
<commandlineArgs>${javah_cli_args}</commandlineArgs>
<useMavenLogger>true</useMavenLogger>
</configuration>
<executions>
<execution>
<id>generate-native-header</id>
<phase>generate-sources</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M9</version>
<configuration>
<argLine>-Djava.library.path=${project.build.directory}/native/lib</argLine>
<excludes>
<exclude>**/*TestHelper.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>4.0.0-M5</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.4.2</version>
</plugin>
</plugins>
</build>
</project>
答案1
得分: 0
以下是代码部分的翻译:
-
"
${project.build.directory}/native/lib
"目录中构建本机库的意图似乎是在“compile”阶段进行的,并且然后在“package”阶段将编译后的库添加到最终的JAR文件中。这不起作用的原因是因为存在一个被忽略的附加步骤。在“package”阶段,默认情况下,Maven JAR插件从“${project.build.outputDirectory}
”中打包文件。在POM中的“project/build/resources”部分列出的源文件在“process-resources”阶段之前复制到此目录。Maven默认生命周期中的“process-resources”阶段在“compile”阶段之前运行。这意味着动态库被编译到“${project.build.directory}/native/lib
”目录之后,该目录已被复制到“${project.build.outputDirectory}
”。 -
如果在运行“mvn package”时似乎能够正常工作,这很可能是因为在“process-resources”阶段运行时已经存在一个已编译的库。如果改为运行“mvn clean package”,我认为你会发现该库在JAR文件中缺失。
-
运行“mvn release:clean release:prepare & mvn release:perform”_不会_获取现有的已编译库的原因是,Maven Release插件在执行发布时会从源代码控制中创建项目的新副本并使用单独的构建输出目录。这是为了避免在发布机器上仅因巧合而存在的文件的可能性。所以它按照意图正常工作。
-
它包括库在源JAR中的原因是
source:jar-no-fork
目标绑定到“package”生命周期阶段,它在“compile”之后运行。因为它旨在打包源代码,所以它会添加来自原始源目录和资源目录(包括额外的“${project.build.directory}/native/lib
”资源目录)的文件,而不是构建输出目录中的文件。 -
Native Maven插件的预期用途是将每个本机库视为单独的模块,但在这种情况下,本机代码与Java代码在同一个项目中。一个可能的解决方案,而不需要重构整个项目,是将
native-maven-plugin
执行绑定到更早的生命周期阶段,比如“generate-resources”:
<executions>
<execution>
<id>dylib</id>
<phase>generate-resources</phase>
<goals>
<goal>initialize</goal>
<goal>compile</goal>
<goal>link</goal>
</goals>
</execution>
</executions>
-
另一个选择可能是将Native Maven插件的“linkerOutputDirectory”参数配置为直接输出到“
${project.build.outputDirectory}
”,并删除对“${project.build.directory}/native/lib
”的使用。如果你不想在源JAR中包含该库,这可能是更好的选择。
英文:
It looks like the intention is to build a native library into the ${project.build.directory}/native/lib
directory during the compile
phase, and then have the compiled library added into the final JAR during the package
phase. The reason this doesn't work is that there is an additional step that is being missed. During the package
phase, the Maven JAR Plugin packages files from the ${project.build.outputDirectory}
(by default). An earlier process-resources
phase copies project resources to this directory from the sources listed in the project/build/resources
section of the POM. The process-resources
phase runs before the compile
phase in the Maven default lifecycle. That means that the dynamic library is compiled into the ${project.build.directory}/native/lib
directory after that directory has been copied to ${project.build.outputDirectory}
.
If it seems to work when running mvn package
, this is most likely because an existing compiled library already exists in this directory when the process-resources
phase runs. If you run mvn clean package
instead, I think you'll find that the library is missing from the JAR.
The reason that running mvn release:clean release:prepare && mvn release:perform
does not pick up the existing compiled library is that the Maven Release Plugin creates a fresh clone of the project from source control into a new directory when performing a release, and uses a separate build output directory. This is specifically to avoid the possibility of releasing files that only exist by coincidence on the release machine. So it's working as intended.
The reason that it does include the library in the sources JAR is that the source:jar-no-fork
goal binds to the package
lifecycle phase, which runs after compile
. Because it is intended to package source code, it adds files from the original sources and resources directories (including the additional ${project.build.directory}/native/lib
resources directory) rather than the build output directory.
The intended use of the Native Maven Plugin is to treat each native library as a separate module, but in this case, the native code is in the same project as the Java code. One possible solution, without restructuring the entire project, would be to bind the native-maven-plugin
executions to an earlier lifecycle phase, such as generate-resources
:
<executions>
<execution>
<id>dylib</id>
<phase>generate-resources</phase>
<goals>
<goal>initialize</goal>
<goal>compile</goal>
<goal>link</goal>
</goals>
</execution>
</executions>
An alternative option may be to configure the linkerOutputDirectory
parameter of the Native Maven Plugin to output directly into ${project.build.outputDirectory}
, and remove uses of ${project.build.directory}/native/lib
. This could be a better option if you prefer not to include the library in the sources JAR.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论