maven: copy resource from dependent jar to target folder - java

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

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.

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.

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

Related

Changing order of applying maven spring-boot and war plugins

I am using spring-boot-maven-plugin to add spring boot to my application and also >maven-war-plugin to move the generated .war to target (local filesystem) destination.
Unfortunatelly, when I add both of them into pom.xml:
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<outputDirectory>C:/Location</outputDirectory>
</configuration>
</plugin>
</plugins>
What happens is that first the .war is generated. Than moved to C:/Location. And later the original .war in /target of my project build is getting updated with spring-boot-maven-plugin (it can be confirmed both by console output and greater file size of .war inside /target.
So I end up with correct .war in inccorect location and incorrect .war (before adding spring boot) in correct location.
Is there a way to make those steps happen in reverse order? To first apply spring boot and later move the result to C:/Location?
I've tried by adding:
<executions>
<execution>
<phase>package</phase>
</execution>
</executions>
to <plugin> for spring boot and:
<executions>
<execution>
<phase>install</phase>
</execution>
</executions>
for war plugin, but it seems to take no effect whatsoever (spring boot is applied after war plugin):
[INFO] --- maven-war-plugin:3.2.1:war (default-war) # app ---
[INFO] Packaging webapp
[INFO] Assembling webapp [app] in [G:\app\target\app-0.0.1-SNAPSHOT]
[INFO] Processing war project
[INFO] Copying webapp resources [G:\app\src\main\webapp]
[INFO] Webapp assembled in [310 msecs]
[INFO] Building war: C:\Location\app-0.0.1-SNAPSHOT.war
[INFO]
[INFO] --- spring-boot-maven-plugin:2.2.4.RELEASE:repackage (repackage) # app ---
[INFO] Replacing main artifact with repackaged archive

How to prevent Maven from compiling classes in src/test/java, which are generated during the generate-sources phase?

In our jOOQ integration tests, we're using the jOOQ code generation plugin to generate classes into the src/test/java directory. We're doing that because:
We want to check in generated sources, so we can detect regressions in the code generator more easily
The generated classes are used by the tests
So, the (simplified) plugin configuration looks like this:
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<executions>
<execution>
<id>some-id</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<generator>
<target>
<directory>src/test/java</directory>
</target>
</generator>
</configuration>
</execution>
</executions>
</plugin>
Unfortunately, this seems to lead Maven to believe that the classes thus generated need to be compiled as well during the compile phase, as can be seen in the following log output:
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) # ... ---
[INFO] Compiling 25 source files to C:\...\target\classes
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) # ... ---
[INFO] Compiling 25 source files to C:\...\target\test-classes
... which makes no sense at all. Debug output hints at both src/main/java and src/test/java being included as compileSourceRoots:
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile' with basic configurator -->
[DEBUG] (f) compileSourceRoots = [C:\...\src\main\java, C:\...\src\test\java]
For the record, during the testCompile phase, as expected, only src/test/java is placed on the compileSourceRoots path:
[DEBUG] Configuring mojo 'org.apache.maven.plugins:maven-compiler-plugin:3.8.1:testCompile' with basic configurator -->
[DEBUG] (f) compileSourceRoots = [C:\...\src\test\java]
For the record, we're using Maven 3.6.2
How can I prevent the src/test/java directory from being added to the compileSourceRoots variable?
A workaround (not very pretty) is to exclude the test classes from the compiler plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<excludes>
<exclude>com/example/test/**/*.java</exclude>
</excludes>
</configuration>
</plugin>
Another is to use the generate-test-sources phase, which we avoided so far, because of some unrelated side effects that we wanted to test already before the compile phase:
<phase>generate-test-sources</phase>
I'm definitely hoping for a better solution!

Resolution will not be attempted until the update interval of company_repository has elapsed or updates are forced

I already have seen answers to this problems several time and I tried them too.
I am trying to use grooy-all and groovy-maven-plugin in my project and the dependencies in pom.xml is:
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-all</artifactId>
<version>2.5.2</version>
<executions>
<execution>
<id>Kryst-reports-flex</id>
<phase>prepare-package</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<scriptpath>
<element>src/main/resources</element>
</scriptpath>
<source>ReportsAssembly.buildFlex(ant, project)
</source>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>groovy-maven-plugin</artifactId>
<executions>
<execution>
<id>Kryst-reports-flex</id>
<phase>prepare-package</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<scriptpath>
<element>src/main/resources</element>
</scriptpath>
<source>ReportsAssembly.buildFlex(ant, project)
</source>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.5.2</version>
</dependency>
</dependencies>
</plugin>
I am getting error when I am trying to do mvn package or mvn install on this project. The error is:
Failure to find org.codehaus.gmaven:groovy-all:jar:2.5.2 in http://myrepo:9090/nexus/content/groups/public was cached in the local repository, resolution will not be reattempted until the update interval of Z-nexus-public has elapsed or updates are forced pom.xml /cockpit-repo line 1 Maven Configuration Problem
I tried to do mvn clean install -U and right click on project -> Maven -> update project with Update snapshots.
But nothing has worked till now.
Could anyone please help me regarding this?
Thanks in advance
PS: I tried mvn dependency:purge-local-repository clean install . It also gives error:
INFO] Downloading from : http://myrepo:9090/nexus/content/groups/public/org/codehaus/gmaven/groovy-maven-plugin/maven-metadata.xml
[INFO] Downloading from : http://myrepo:9090/nexus/content/groups/public-snapshots/org/codehaus/gmaven/groovy-maven-plugin/maven-metadata.xml
[INFO] Downloading from : https://repo.maven.apache.org/maven2/org/codehaus/gmaven/groovy-maven-plugin/maven-metadata.xml
[INFO] Downloaded from : https://repo.maven.apache.org/maven2/org/codehaus/gmaven/groovy-maven-plugin/maven-metadata.xml (368 B at 1.0 kB/s)
[INFO] Downloaded from : http://myrepo:9090/nexus/content/groups/public/org/codehaus/gmaven/groovy-maven-plugin/maven-metadata.xml (368 B at 511 B/s)
[INFO]
[INFO] ---------------< com.zetes.crystal:cockpit-reports-flex >---------------
[INFO] Building Cockpit reports Flex components 3.2.1-MB-18
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] Downloading from : http://myrepo:9090/nexus/content/groups/public/org/codehaus/gmaven/groovy-all/2.5.2/groovy-all-2.5.2.pom
[INFO] Downloading from : https://repo.maven.apache.org/maven2/org/codehaus/gmaven/groovy-all/2.5.2/groovy-all-2.5.2.pom
[WARNING] The POM for org.codehaus.gmaven:groovy-all:jar:2.5.2 is missing, no dependency information available
[INFO] Downloading from : http://myrepo:9090/nexus/content/groups/public/org/codehaus/gmaven/groovy-all/2.5.2/groovy-all-2.5.2.jar
[INFO] Downloading from : https://repo.maven.apache.org/maven2/org/codehaus/gmaven/groovy-all/2.5.2/groovy-all-2.5.2.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.816 s
[INFO] Finished at: 2018-08-30T14:25:55+02:00
[INFO] ------------------------------------------------------------------------
[ERROR] Plugin org.codehaus.gmaven:groovy-all:2.5.2 or one of its dependencies could not be resolved: Could not find artifact org.codehaus.gmaven:groovy-all:jar:2.5.2 in Z-nexus-public (http://myrepo:9090/nexus/content/groups/public) -> [Help 1]
First try a forced update:
mvn clean install -U
If the forced update does not work there IS something wrong.
Check the following things:
Broken local artifacts - go to you local maven repository and search for the artifact and delete the folder. (in win usually under C:\Documents and Settings{your-username}.m2, in linux ~/.m2)
Is the artifact ACTUALLY on the repo, check spelling, version, everything!
Is the connection to the repo possible, watchout for proxy settings!

Maven add javadoc

I'm working in a Maven multimodule project and I'm not able to download javadocs for some dependencies. I'll describe my failed attempts:
I'm working with Netbeans so the first option was Right click in Dependencies -> Download Javadocs and some javadocs were dowoloaded but some other not.
Next option was to use mvn eclipse:eclipse but the result was the same (some javadocs were still missing). Also I saw that mvn eclipse plugin is deprecated
Last option was to use mvn dependency:resolve -Dclassifier=javadoc but the result is the same
I configured the maven-javadoc-plugin in my pom.xml but nothing happens. The configuration is the following:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.3</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
I don't want to use this option because implies a manual downloading. The third option gave me the following output:
[INFO] The following files have NOT been resolved:
[INFO] dom4j:dom4j:jar:javadoc:1.6.1:test
[INFO] org.jboss:jandex:jar:javadoc:1.1.0.Final:test
[INFO] org.hibernate:hibernate-entitymanager:jar:javadoc:4.3.1.Final:test
[INFO] org.hibernate:hibernate-validator:jar:javadoc:5.2.4.Final:provided
[INFO] xml-apis:xml-apis:jar:javadoc:1.0.b2:test
[INFO] org.hibernate.common:hibernate-commons-annotations:jar:javadoc:4.0.4.Final:test
[INFO] org.hibernate:hibernate-core:jar:javadoc:4.3.1.Final:test
[INFO] antlr:antlr:jar:javadoc:2.7.7:test
[INFO] javax.activation:activation:jar:javadoc:1.1:provided
Any help is appreciated, also if someone tells me that there's no other option but to install the artifacts manually.
Thanks in advance.

Automatically executing dependency:build-classpath in maven

I am literally trying to do exactly this:
http://maven.apache.org/plugins/maven-dependency-plugin/usage.html#The_dependency:build-classpath_mojo
What's amazing is that after finding an explicit example of exactly what I want Maven to do.. I still can't get it to work.
From the command line, I can run ...
mvn -Dmdep.outputFile=classpath.txt dependency:build-classpath
... which does indeed produce a file called classpath.txt with the information I'd like.
I would like to be able to issue a command like "mvn compile" and have the production of this classpath.txt file be a part of that process. The example provided at the link above associates it with generate-sources, which to my understanding should suffice.
When executing a command like "mvn compile" with this pom snippet below, nothing regarding the build-classpath goal seems to execute.
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>build-classpath</id>
<phase>generate-sources</phase>
<goals>
<goal>build-classpath</goal>
</goals>
<configuration>
<outputFile>myfile.txt</outputFile>
<mdep.outputFile>myFile1.txt</mdep.outputFile>
<ihavenoidea>whatgoeshere</ihavenoidea>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
And here is what I end up with:
$ mvn compile
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building someproj 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) # someproj ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) # someproj ---
[INFO] Nothing to compile - all classes are up to date
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.600s
[INFO] Finished at: Fri Jan 31 14:05:29 CST 2014
[INFO] Final Memory: 9M/156M
[INFO] ------------------------------------------------------------------------
$ ls
bin html log pom.xml resources sql src target test-output wwwroot
Your plugin definition is inside <pluginManagement>, which means that when you will declare a "real" execution of that plugin inside a pom that has this pom as parent (or this pom itself), it will use that configuration.
This is generaly a good idea to use <pluginManagement> when a common configuration has to be applied on multiple execution, through multiple modules in the same global project.
Here, I would personally keep the compiler plugin inside <pluginManagement>, as you probably always want that plugin to be configured like this, but I woul move the dependency-plugin inside the <plugins> section (outside the <pluginManagement> section, well yes, this can be confusive...)
You may think of <pluginManagement> as a kind of template. It's often used in parent POMs to define a common configuration. Only plugins in <build><plugins> are included in the build.
That said, Maven does do some "magic" depending on the packaging type. I answered a similar question here.

Categories

Resources