Maven doesn't copy untracked resources while r

2019-07-12 15:25发布

问题:

My problem is about resources to be included in the jar file when doing release with maven.

I am using maven to build my project and when I run

$ mvn package

resources are included in the output jar. But when I run

$ mvn release:prepare

$ mvn release:perform

these resources are not included in the release jar.

Resources are located in maven default directory, src/main/resources, but they are outside of source control (ignored via .gitignore). From the output made by maven I realize that maven does git checkout to different folder and resources are not copied to that folder. This is why maven release plugin doesn't package it to release jar.

My question is what is the best way to deal with such a case?

  1. Make a symlink for resources folder during release process? how?

  2. Copy resources? how?

  3. Or putting resources into SCM is the only way to make them available in released package?

I prepared small testcase for this:

#!/bin/sh
# here is pom.xml
cat >pom.xml <<EOF
<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.domain</groupId>
  <artifactId>artifact</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>artifact</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <scm>
    <developerConnection>scm:git:file://$(pwd)</developerConnection>
  </scm>

  <distributionManagement>
    <repository>
      <id>internal.repo</id>
      <name>Example Internal Repository</name>
      <url>file://$(pwd)/deploy</url>
    </repository>
  </distributionManagement>

</project>
EOF

#here is src/main/java/Main.java
mkdir src
mkdir src/main
mkdir src/main/java
mkdir src/main/resources

cat >src/main/java/Main.java <<EOF
import java.io.InputStream;

public class Main
{
    public static void main(String args[])
    {
        boolean ok = false;
        InputStream is = new Main().getClass().getResourceAsStream("/some_file_outside_scm");
        ok = is != null;

        System.out.println("ok=" + ok);
    }
}
EOF

#some data in src/main/resources/some_file_outside_scm
cat >src/main/resources/some_file_outside_scm <<EOF
123
456

EOF

#file src/main/resources/.gitignore
cat >src/main/resources/.gitignore <<EOF
some_file_outside_scm
EOF


#.gitignore in the project root
cat >.gitignore <<EOF
target
deploy
EOF

git init .
git add pom.xml
git add src/main/java/Main.java
git commit -m "first commit"

#The test case can be tested with these commands

mvn package
echo !!!!!!!!!!!!!!!!!
echo contents of the packaged jar
jar tf target/artifact-0.0.1-SNAPSHOT.jar
#The file 'some_file_outside_scm' is packaged into jar.

echo !!!!!!!!!!!!!!!!!
echo after mvn package
java -cp target/artifact-0.0.1-SNAPSHOT.jar Main
# ok=true
echo !!!!!!!!!!!!!!!!!

mvn release:prepare
mvn release:perform

echo !!!!!!!!!!!!!!!!!
echo but after mvn release
java -cp deploy/com/domain/artifact/0.0.1/artifact-0.0.1.jar Main
# ok=false

#the file is not included in the release jar
echo !!!!!!!!!!!!!!!!!
echo contents of the release jar
jar tf deploy/com/domain/artifact/0.0.1/artifact-0.0.1.jar

回答1:

If you are not putting the resources into SCM, you can't release them as part of this project, as mentioned by others.

You might try moving the resources into a separate project and using maven-remote-resources-plugin:bundle to build a resource bundle (jar). Any time you change a resource in that project you would need to manually bump the version number in your POM and do a mvn deploy to get the changes into your artifact repo.

Then, in your current project, you use maven-remote-resources-plugin:process to retrieve the resources and put them in the proper location in your artifact before it is built. process is bound to the generate-resources phase by default; adjust this to meet your needs.



回答2:

Resources must be in your SCM, cause they are part of your project. Otherwise your project will not work whatever resources these are. So you don't put them under version control into src/main/resources as the rest project so they will never been packaged into the jar.



回答3:

The release-plugin activates during release:perform the profile release-perform. You can use the resource-plugin for that profile to copy your resources.