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