How to create a subdirectory within target with Maven2 - maven-2

I need to create a subdirectory within the target directory when compiling with maven2. The reason is that I'm using a plugin which grabs responses to SOAP-requests and store them in /target/xml in the integration-test phase.
The problem is that if I specify the plugin's savepath to (in example): ${basedir}/target/xml the plugin throws a FileNotFoundException. The reason I want the file to be in /target is so that the directory is cleaned when invoking mvn clean.
Any suggestions?

You could create a common abstract base class that your test case classes extend.
Add a static initializer initializer to the abstract base class that checks whether the directory exists and if not then creates it.
The static initializer block will be executed the first time that the base class is loaded, and will be executed before any static initializer blocks or constructors in the test case sub-classes.
EDIT:
OK, then you'll have to uglify your pom with the plugin definition below, which will bind to the generate-test-resources phase, and invoke the antrun plugin to create the directory.
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>generate-test-resources</phase>
<configuration>
<tasks>
<echo message="Creating test output directory"/>
<mkdir dir="./target/xml"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>

Related

Copy dependencies maven war

When I try to use the plugin "maven-war-plugin", it copies all libraries to / WEB-INF/lib, how to copy to another directory? Example: "/ libtest"
I'm not sure to understand why you need to do this but I see two points here:
Avoiding dependencies to get copied into WEB-INF/lib (if not, then just skip the part related to 1.)
Getting them copied to another directory.
For 1. I'm assuming you need the dependencies (because you want to compile against them) but if you don't want the Maven War Plugin to copy them in WEB-INF/lib, you'll have to play with their scope, for example by declaring them as provided.
For 2. the Maven Dependency Plugin will be helpful here and I think you could use dependency:copy-dependencies, for example during the pre-package phase. Use it like this:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>pre-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- configure the plugin here -->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
And configure the outputDirectory (and other parameters you could need).
Use the maven-dependency-plugin.

Maven: How can my mojo access its own resources?

I have a project (here called my-artifact) which needs to generate sources from a model file. I've created a maven-plugin (my-code-generator) which is used as described in the pom.xml excerpt below. It loads and processes the model.xml from my-artifact's resources and generates code using some predefined templates stored within the plugin. The question is how my-code-generator could access these templates as they are not in the project resources but within its own resources.
Thanks in advance
<plugin>
<groupId>my-group</groupId>
<artifactId>my-code-generator</artifactId>
<version>0.0.1-SNAPSHOT</version>
<configuration>
<modelfile>
src/main/resources/model.xml
</modelDir>
</configuration>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>generate-model</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
<sources>
<source>target/generated-sources</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
Just use the ClassLoader, to get resources from the MyCodeGenerator Maven plugin.
Add something like this to your MyCodeGeneratorMojo
URL getTemplate(String fileName) {
return this.getClass().getResource(fileName);
}
Within the MyCodeGenerator Maven plugin, add the template(s) to the src/main/resources directory (don't forget to use the correct package entry (directories) within that directory).
By including them in the jar file for the plugin and referencing them via classpath, via ClassLoader.getResourceAsStream.
By packaging them as another artifact, declaring them as a dependency, and calling the dependency-resolution API, which is a lot more work.

Maven-2: avoid default packaging?

My project uses many assemblies, hence I'm interested only in the assemblies.
On executing mvn install apart from the assemblies, I'm getting the default packaged .jar.
How can I avoid this?
I have a pom.xml similar to the one you have provided.
On executing mvn install, I'm getting App1.jar, App2.jar, and snapshot jar containing all contents
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-2</version>
<executions>
<execution>
<id>assemblyone</id>
<phase>compile</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>App1</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>${basedir}/src/main/resources/assemblies/report.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>assemblytwo</id>
<phase>compile</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>App2</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>${basedir}/src/main/resources/assemblies/src.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
How can I avoid this snapshot (not sure of the exact term) jar and ensure that only assemblies are created?
I can read your question two ways, I've outlined answers for both below. If neither is correct, can you modify your question with a bit more explanation please.
1) Do you mean you have a project with default (jar) packaging, and you want to avoid the creation of the jar when no assembly is defined? If this is the case, what is the build achieving if no assembly is defined?
2) Do you instead mean that you are running mvn assembly:assembly to generate the assembly and want to know how to get that assembly when running the install goal?
For option 2, you can bind the assembly-plugin to a lifecycle phase to ensure it is always run, if you specify that <appendAssemblyId> should be false, then the assembly will replace the default jar.
For example, this configuration will invoke the assembly plugin during the packaging phase and replace the default jar:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/archive.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
For option 1, this is actually quite tricky to do. The best I can think of is to specify that the project has pom packaging and configure the project with the executions normally bound to the jar lifecycle in a profile. The lifecycle bindings you'd need to configure are listed in the introduction to the build lifecycle
I'm not sure that you can really do that in a really simple way.
A solution is to call the clean plugin once the build is achieved, by doing that:
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<executions>
<execution>
<id>auto-clean</id>
<phase>package</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
This way, the JAR created in the target/ directory will be deleted at the end of the Maven2 execution.
However, you will have to define another directory to store the assemblies created by Maven2. Otherwise, it will be deleted by the call of the clean plugin... If you want to store them in the directory assemblies-target/, you can add that in the pom.xml file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-4</version>
<configuration>
...
<!-- Copy the ZIP in target/ of the ROOT directory. -->
<outputDirectory>assemblies-target</outputDirectory>
</configuration>
...
I think it would be much more clear if you showed us your whole POM and the artifacts that are being built. I can only guess as to what the problem is because your terminology is not what I am familiar with. This is my guess as to the problem: you have a POM configured to generated two assembly JARs, but you get a third JAR for the POM itself. In other words, if your POM's artifactId is MyApp, you are getting a MyApp-1.0.0.jar or similar in addition to the two JARs you actually want.
If that is the case, the problem boils down to that you are using Maven to create multiple artifacts from a single module. Maven is designed to produce only one primary artifact from each module. What I would do is change your POM to have a packaging type of "pom" and give it two modules in a <modules> section named App1 and App2. Create sub-directories under your module, one for each App. Give them each a POM configured for a single assembly, with a packaging type of "jar". Move the code/files/etc. as appropriate into each sub-module so there aren't any remaining in the parent module.
With Maven, if you find yourself generating two artifacts from one module (which you are), you should first consider that you are probably violating a Maven best-practice and rearrange things so you only produce one artifact per module.
Please let me know if this doesn't make sense and I will try to clarify.

Maven configuration for two projects

I am having a project A being built with mvn assembly:assembly which gives me a jar file with dependencies. This project basically gets a file path and converts it to XML.
Now I need to create a new project B which will wrap A by walking a directory and calling several times to A. NOTE: They must be different applications. I am not able to modify A changing it's parameters.
I would like that when B builds, it will first build A and gets it's jar file.
Which is the best way to configure this in a pom file? Should I have two poms?
Same pom but two jars being build?
Thanks for reading!
I would handle this by adding an aggregator POM with A and B as modules. Then you simply build the aggregator each time to have A built before B. This gives you the flexibility to build A and B individually as well as both together.
If you are determined to invoke A's build from within B, it could be done by using the maven-exec-plugin to invoke another Maven instance.
For example:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>mvn</executable>
<!--specified as a property below-->
<workingDirectory>${projectA.path}</workingDirectory>
<arguments>
<argument>clean</argument>
<argument>install</argument>
</arguments>
</configuration>
</plugin>
...
<properties>
<projectA.path>/path/to/project/a</projectA.path>
</properties>

Compiling Test classes:not working

I wanted to package the class files under target/test-classes(ie src/test/java) as one assembly.
When I am running the maven command,i am getting the error:
Reason: Failed to create assembly: Error creating assembly archive : You must set at least one file.
My assembly desciptor is :
<assembly>
<id>stress-client</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.testOutputDirectory}
</directory>
<includes>
list of files to be included
</includes>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
i find test-classes empty.Why the test files are not getting compiled?
Please help
I'm guessing the assembly is trying to run before the test-compile phase, in which case there will be no classes to include. Or you are running mvn assembly:assembly, in which case the default lifecycle will not be run and the test classes not compiled. You could bind the execution of the assembly plugin to a later phase (e.g. package) to ensure the processing is completed before the assembly is constructed.
However you don't need to use an assembly to package test-classes. This can be done by configuring the jar plugin to package the test jar as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
By default the test jar will be attached to the project, and when installed/deployed will have the classifier tests.
If you must use the assembly, here is how you bind it to the default lifecycle so that it will be run when package is called.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/test-assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-test-assembly</id>
<phase>package</phase> <!-- append to the packaging phase. -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
If this still does not work, it suggests you are using a non-standard packaging type that doesn't perform the relevant goals for test processing, or your test sources are defined in a non-standard location so they are not being processed. If you are still having trouble can you append the output from your build to your question?
Another thing to check is that the pom does not have packaging pom. If packaging is pom the test compilation will not be triggered.