10

I need to copy a resource file (menu.xml) from the root of a dependent jar file to the root of the output directory of my current project, before the tests are executed during the build. The file must be available for the tests but also later for the main program using ...getClassLoader().getResourceAsStream("menu.xml").

I'm trying the solution suggested in this question but it's not working.

This is how the pom file looks like:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
      <execution>
        <id>resource-dependencies</id>
        <phase>process-test-resources</phase>
        <goals>
          <goal>unpack-dependencies</goal>
        </goals>
        <configuration>
          <type>jar</type>
          <includeArtifactIds>pm1j-jar</includeArtifactIds>
          <includes>menu.xml</includes>
          <outputDirectory>${project.build.outputDirectory}</outputDirectory>
        </configuration>
      </execution>
    </executions>
  </plugin>

When I execute mvn clean process-test-resources I see the following output:

[INFO] --- maven-resources-plugin:2.7:testResources (default-testResources) @ pm1-config ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 3 resources
[INFO]
[INFO] --- maven-dependency-plugin:2.8:unpack-dependencies (resource-dependencies) @ pm1-config ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.709 s
[INFO] Finished at: 2016-05-05T15:01:06-03:00
[INFO] Final Memory: 30M/458M
[INFO] ------------------------------------------------------------------------

The file menu.xml is not copied to the target folder. How can I see what could be possibly wrong? I tried to run maven on debug log level and could see that the configuration was parsed correctly, but the plugin doesn't log any additional information of what is happening.

...
[DEBUG]   (f) includeArtifactIds = pm1j-jar
[DEBUG]   (s) includes = menu.xml
...
[DEBUG]   (f) outputAbsoluteArtifactFilename = false
[DEBUG]   (s) outputDirectory = c:\Dev\workspaces\config\pm1j\pm1-config\target\classes
...
[DEBUG]   (f) project = MavenProject: com.expersoft.pm1j:pm1-config:3-SNAPSHOT @ c:\Dev\workspaces\config\pm1j\pm1-config\
pom.xml
[DEBUG] -- end configuration --
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10.014 s
[INFO] Finished at: 2016-05-05T15:09:29-03:00
[INFO] Final Memory: 27M/328M
[INFO] ------------------------------------------------------------------------
Community
  • 1
  • 1
Alex
  • 1,126
  • 1
  • 11
  • 24
  • is menu.xml directly in the root of the dependant jar? Do you have that jar in the dependencies list? Have you tried something like **/menu.xml as mentioned in the docs https://maven.apache.org/plugins/maven-dependency-plugin/unpack-dependencies-mojo.html#includes - and if you load the file from the classpath anyway, way unpack it at all? – wemu May 05 '16 at 19:13
  • Why do you need to do that? You don't need to do that. If the resource is at the root of a JAR in the classpath, it is in the root of your classpath so what you "want" serves absolutely no purpose. Hence: what do you _really_ want to do? What's the real problem you want to solve? – Tunaki May 05 '16 at 19:45
  • Yes, the file is in the root of the dependent jar. I now figured out the issue. The jar is not in the dependencies list. The confusion started because I first tried the **unpack** goal of the plugin, which downloads the jar from the repository, which worked well. However in this case I can't use the file for tests because it happens in a later life cycle phase. I guess I'll have to fall back to the previous solution, which was copying the file from the other project's source folder using the maven-resources-plugin. – Alex May 05 '16 at 20:59

3 Answers3

18

After some help from the comments, I could figure out the issue. The jar holding the menu.xml file is not in the dependencies list of my project.

Here is a better explanation of what I was trying to achieve for better understanding:

My project is inside a maven multi module, and I need the information of this menu.xml which is maintained on another project of the same multi module. Apart from this file there's no other dependency to this other project, therefore, there's also no maven dependency to the jar.

In order to avoid duplication of the file in my project, I helped myself so far with the maven-resources-plugin, which copies the file from the source directory of the other project. I never really liked this solution though, because it's dependent on having the source of this other project on the file system.

  <plugin>
    <artifactId>maven-resources-plugin</artifactId>
    <executions>
      <execution>
        <id>copy-resources</id>
        <phase>validate</phase>
        <goals>
          <goal>copy-resources</goal>
        </goals>
        <configuration>
          <outputDirectory>${project.basedir}/src/main/resources</outputDirectory>
          <resources>          
            <resource>
              <directory>${project.basedir}/../pm1-jJar/src/main/resources</directory>
              <includes>
                <include>menu.xml</include>
              </includes>
            </resource>
          </resources>              
        </configuration>            
      </execution>
    </executions>
  </plugin>

Then I discovered the maven-depency-plugin and the unpack goal which can extract the file out of the downloaded jar from the repository. This looked like a much cleaner solution. I tried it out and it worked actually well. The problem with this solution though was that the unpack plugin acts only in a later maven phase after testing and I do have some tests using the file as well.

After some more research, I found the resource-dependencies plugin with the unpack-dependencies goal which looked like the perfect solution but at this stage I had completely forgotten that I actually don't have a dependency to the jar.

Community
  • 1
  • 1
Alex
  • 1,126
  • 1
  • 11
  • 24
9

A nice way to copy files from your dependency is to use Goal unpack :

you can mention your files /directories in dir/** --> include everything from a directory

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>resource-dependencies</id>
            <phase>compile</phase>
            <goals>
                <goal>unpack</goal>
            </goals>
            <configuration>
                <artifactItems>
                <artifactItem>
                    <groupId>group_id</groupId>
                    <artifactId>artifact_id</artifactId>
                    <version>1.0.0</version>
                    <type>jar</type>
                    <overWrite>true</overWrite>
                    <outputDirectory>${project.build.directory}</outputDirectory>
                </artifactItem>
                </artifactItems>
                <includes>directory_to_include/**</includes>
                <outputDirectory>${project.build.outputDirectory}</outputDirectory>
            </configuration>
        </execution>
    </executions>
</plugin>

I attached goal unpack to the phase compile. Customise as per your need.

  • And if you just have a "thing" that you don't want unzipped (e.g. an exe you've uploaded to maven) you can use the copy goal from that same plugin – Richard Tingle Sep 07 '21 at 09:50
-1

In order to use the maven-depency-plugin to unpack a jar before testing, the workaround is to use failsafe instead of surefire to have tests run after the unpacking.

Simon

Simon
  • 11