Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

maven: copy resource from dependent jar to target folder

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] ------------------------------------------------------------------------
like image 912
Alex Avatar asked May 05 '16 18:05

Alex


2 Answers

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.

like image 117
Alex Avatar answered Nov 15 '22 01:11

Alex


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.

like image 45
raneesh choudhary Avatar answered Nov 15 '22 01:11

raneesh choudhary