Setting up maven resources when testing - maven-2

I need resource goal of resource plugin to be set up differently for
test phase, than for build phase. When testing I need to exclude stuff
from src/main/resources. It seems it can't be done, testResources goal
is irrelevant for what I need and resource goal can have only one
setting in pom definition, that takes effect in both test and build
phase...
For example, I'd need following settings to look differently (some
excludes) in testing phase :
<resources>
<resource>
<directory>${project.basedir}/src/main/java</directory>
<includes>
<include>**/*.java</include>
<include>service.properties</include>
</includes>
</resource>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
The ideal behavior would be if I could define "src/main/*" in
<testResources> but it unfortunately can't be done right now
Please help, I'd have to do tons of code modification if I didn't figure it out.

You would probably have to have the resources as a separate project that is not included at test time, which is a mess.
I can imagine why you would want to do this, but you aren't really testing the artifact at that point.
This is where IoC really shines. Your components get their resources injected instead of the component having to have runtime selection code of which resource (test or actual) that should be chosen. This is important because the test code can't test the code that chooses the test. If you see what I mean :-)
If you are using Spring, you can create a test-context.xml containing bean overrides for the changes you want to make, then load that after loading all your other contexts. When it is loaded, you will get a warning that the beans are being overridden, look at them closely the first time to be sure the test bean is overriding the production bean. Then that bean should be injected as you expect.

Related

Arquillian and Open Liberty requires existing installation?

I'm familiar with Tomcat/TomEE and testing applications using Arquillian. Now were are switching to Open Liberty. I see there is a module for Arquillian using embedded Open Liberty but it seems to require an existing Open Liberty installation whose path is provided in the configuration. This makes it non-portable and therefore unsuitable for automated testing since the installation has to be present at the exact same path. Arquillian and TomEE are self-contained, no installation required. Therefore my question is why this isn't also possible with Open Liberty? And is this planned for the future?
For reference this is how you use Arquillian with TomEE/Tomcat:
<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://jboss.org/schema/arquillian"
xsi:schemaLocation="http://jboss.org/schema/arquillian http://www.jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="tomee" default="true">
<configuration>
<property name="httpPort">-1</property>
<property name="stopPort">-1</property>
<property name="users">user=pass</property>
</configuration>
</container>
</arquillian>
As you can see, there is no path to a local installation required to run the tests. The only thing you need to do is a add a couple of Maven dependencies in test scope that pull in TomEE (embedded). If the same would work for Open Liberty that would be great.
Going further..so the above is how we do automated testing
but it still uses the location.
I see, regarding not needing any location specified at all, you say:
"The only thing you need to do is a add a couple of Maven dependencies in test scope that pull in TomEE (embedded). If the same would work for Open Liberty that would be great."
So, thinking, maven will put a bunch of classes on the classpath due to the TomEE
dependancies and then the test run will find the appropriate container to
run the tests on.
I will raise an issue over on
https://github.com/OpenLiberty/liberty-arquillian/issues/39
to cover the requirement please feel free to add remarks etc.
If you have a look at https://github.com/OpenLiberty/open-liberty/blob/integration/dev/com.ibm.ws.microprofile.config.1.2_fat_tck/publish/tckRunner/tck/src/test/resources/arquillian.xml
you will see an example arquillian.xml that sets $wlpHome
<property name="wlpHome">${wlp}</property>
from an environment variable $wlp.
('wlp' is short for Websphere Liberty Profile)
The wlpHome variable is used in the managed/local container here:
https://github.com/OpenLiberty/liberty-arquillian/blob/42cb523b8ae6596a00f2e1793e460a910d863625/liberty-managed/src/main/java/io/openliberty/arquillian/managed/WLPManagedContainer.java#L224
An example that does this dynamically is the setting of the
system property ${wlp} here:
https://github.com/OpenLiberty/open-liberty/blob/95c266d4d6aa57cf32b589e7c9d8b39888176e91/dev/fattest.simplicity/src/componenttest/topology/utils/MvnUtils.java#L161
If you have any more queries please post them...
and hope you love OpenLiberty - it rocks!
Gordon
The result you seem to be trying to achieve is a embedded runtime for liberty using arquillian. However, all as far as I can see, the openliberty team only provides a remote container adapter and a managed container adapter at the moment.
With us having a similar need, wanting to run automated integration tests where we wouldnt necessarily have a Openliberty server in-place. We managed to work-around this using liberty-maven-plugin.
The build/testing process would then be:
Running mvn verify, liberty-maven-plugin would generate the specified openliberty which we want to run our tests against.
<plugin>
<groupId>net.wasdev.wlp.maven.plugins</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>${version.liberty-maven-plugin}</version> <!-- plugin version -->
<configuration>
<assemblyArtifact> <!-- Liberty server to run test against -->
<groupId>io.openliberty</groupId>
<artifactId>openliberty-runtime</artifactId>
<version>18.0.0.4</version>
<type>zip</type>
</assemblyArtifact>
<configDirectory>src/liberty/${env}/</configDirectory>
<configFile>src/liberty/server.xml</configFile>
<serverName>defaultServer</serverName>
</configuration>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>create-server</goal>
</goals>
</execution>
</executions>
</plugin>
As liberty-maven-plugin per default adds the Liberty server to the target/folder
<arquillian xmlns="http://jboss.org/schema/arquillian">
<container qualifier="liberty-managed" default="true">
<configuration>
<property name="wlpHome">target/liberty/wlp</property>
<property name="serverName">defaultServer</property>
</configuration>
</container>
</arquillian>
This way we can assure that a runnable liberty server according to our liking is always existant in our local environment or e.g. our Jenkins CI/CD Server, essentially getting the same effect as having a embedded container.

Detect and weave dependencies automatically with AspectJ

We have a Maven project with multiple compile dependencies and every time a new <dependency> is added, we need to create an equivalent <weaveDependency> entry in
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<configuration>
<weaveDependencies>
<weaveDependency>
<groupId>a-group</groupId>
<artifactId>new-dependency</artifactId>
</weaveDependency>
</weaveDependencies>
<weaveDirectories>
<weaveDirectory>${project.build.directory}/classes/</weaveDirectory>
</weaveDirectories>
<complianceLevel>${java.version}</complianceLevel>
<showWeaveInfo>true</showWeaveInfo>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
This is being done exactly as described in
http://mojo.codehaus.org/aspectj-maven-plugin/examples/weaveJars.html
But this could easily lead to problems if it's needed to weave everything because someone could forget to add the <weaveDependency> after adding a new <dependency>, so is there a way of detecting and weaving all compile dependencies automatically? Maybe with another plugin?
AFAIK there is no such option or plugin, unless you decide to write one or open a ticket for AspectJ Maven.
One question before we continue: Are you really sure you want to weave all dependencies? What about libraries such as JUnit or Log4J in your aspect POM?
The way I usually go about weaving my aspects into the code - if they are production and not just development, debugging or profiling aspects, that is - is that I do it the other way around than you: I use the AspectJ Maven Plugin in each of my modules to directly compile the aspects into my code from source. So in my case each Java module depends on an aspect module, using it as an aspect library. Because usually I have way fewer aspect libs than Java modules, I cannot so easily forget to include them. Okay, I have to do it in each module, but this is a no-brainer with a good IDE (global search and replace on all pom.xml files in my project).
If you really want to do it even more cleanly and nicely, you can use the approach explained in Strategies for using AspectJ in a Maven multi-module reactor, i.e. you create a normal root POM and an aspect root POM which has the root pom as its parent. Then each Java module which needs the aspects can use the aspect root POM as its parent, other Java modules use the root POM directly.
The advantage of compiling the aspects into your artifacts right away is that there are no two class file versions of each artifact: an original without aspects and a woven version with aspects in the aspect module's target directory. The only reason why you would not do it they way I explained is if for some reason you also need artifact versions without aspect code. But then, as I said, you probably use development, debugging or profiling aspects. Be it as it might, you can still use my approach for production aspects and your old approach for the development stuff.

How to override maven-release-plugin config in one child module

I have a multi-module maven build where one of the child modules requires an extra goal to be executed as part of a release. But it looks as though any configuration of the maven-release-plugin in the child module is ignored in favour of the default configuration in the parent module.
This is the snippet from the child module. The plugin configuration is the same in the pluginManagement section of the parent pom, but without the custom element.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.1</version>
<configuration>
<tagBase>http://mycompany.com/svn/repos/myproject/tags</tagBase>
<goals>deploy myCustomPlugin:myCustomGoal</goals>
</configuration>
</plugin>
So is it possible for a child module to override the parent's configuration and add extra goals?
Maven version 2.2.1
Use combine.children="append" combine.self="override"
Parent POM
<configuration>
<items>
<item>parent-1</item>
<item>parent-2</item>
</items>
<properties>
<parentKey>parent</parentKey>
</properties>
</configuration>
Child pom
<configuration>
<items combine.children="append">
<!-- combine.children="merge" is the default -->
<item>child-1</item>
</items>
<properties combine.self="override">
<!-- combine.self="merge" is the default -->
<childKey>child</childKey>
</properties>
</configuration>
Result
<configuration>
<items combine.children="append">
<item>parent-1</item>
<item>parent-2</item>
<item>child-1</item>
</items>
<properties combine.self="override">
<childKey>child</childKey>
</properties>
</configuration>
See this blog for further details
Yes and no. Certainly a child pom can override the configuration of a plugin specified by its parent, and I have to assume you've done so correctly because there's nothing really hard about it. If you check the output of mvn help:effective-pom, you should be able to see plainly that this module has different settings for the release plugin.
The problem you're having is with the behavior of the release plugin. Typically, if you run a goal or phase--mvn compile, for example--from the root module of your project, it first runs that goal/phase on the root module, then on all the modules in reactor order, almost as if you'd run it in each module yourself. Any customizations you've added to child modules take effect as expected. When you run the release plugin, it runs only at the root module. It doesn't run in any of the child modules. Instead, running it at the root module forks a new build using the same settings as the root module, which runs for all the other modules in nearly the same way, except that it uses the root module's configuration for all the modules. I don't know the exact semantics, but I believe this is analogous to you manually running the release goals in each child and specifying the configuration options as system properties at the command line: regardless of how a child module configures the release plugin, the command line args win.
I've never dealt with this problem myself, and it's hard to say without knowing exactly what you're trying to accomplish. Perhaps if you can express what you want to do in this special module as a profile, then you could add a profile to your goals and or preparationGoals. Alternately, there's an arguments option to both the prepare and perform goals that you might be able to pull some tricks with.

Maven Plugin error

Im a new user in maven. I have few doubts.
I have some BAT files that has to executed via maven
While executing my default commands, I need to echo the status like "Started first task"
When the task gets failed user should get error message popup etc.,
Automatic repository update through maven
Maven calling ant to build *.war
Copying the new created build file(*.war) to local folder with date/time
Auto upload/deploy from build machine to server
Testing particular URLs/products to test the site flow
Sending mail regarding deployment status
Below is my example pom.xml, which trying only (a)
<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.example.maven</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>test</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1.1</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<!--echo>Starting CVS Update</echo-->
<configuration>
<tasks>
<exec>
<directory>D:\</directory>
<executable>"D:\test.bat"</executable>
<!--failonerror="true" -->
<!-- optional -->
<!--workingDirectory>"cd C:\repo\projects\mcsandbox"</workingDirectory-->
</exec>
</tasks>
</configuration>
</plugin>
</plugins>
</build>
</project>
I guess this is not the expected answer but I don't think that you're on the right path and I don't see the point of using Maven the way you'd like to use it. From your description, my impression is that you aren't really adopting Maven but rather trying to insert something existing into it and, believe me, this isn't the easiest way to get started with Maven:
This is going to add an extra layer of complexity.
This requires a deeper understanding of the way maven works than "just" adopting it.
You're going to fight against the tool (and there are good chances that the tool will win).
This will generate more troubles than benefits.
I don't really know where to start so I'll just try to quickly cover your points first:
I have some BAT files that has to executed via maven
This is possible but this is not really the Maven way (depending on the logic, you should move it to Maven or keep it outside maven), and I don't think this is going to be very robust (might be wrong though). On top of that, this already requires some knowledge of the build lifecycle (where to hook things) and of plugin configuration. And from what I've seen (I do not mean to be rude), you don't have it.
While executing my default commands, I need to echo the status like "Started first task"
This is not how things work with Maven. Maven isn't procedural like Ant, Maven has conventions, Maven is declarative, Maven has a lifecycle.
When the task gets failed user should get error message popup etc.,
User? Popup? Maven is not really targeted at end users, Maven is a developer tool and what you get in case of an error is a message in a console.
Automatic repository update through maven
Do you mean a CVS update? This is not impossible but is usually not Maven's job (it's more a Continuous Integration engine task).
Maven calling ant to build *.war
This is possible using the Maven Antrun Plugin but that's not the spirit and may go against some maven rules (like one artifact per project). Also, Maven will not magically be aware of things built by Ant. Why don't you just stick with Ant?
Copying the new created build file(*.war) to local folder with date/time
Possible. But that's not how things work by default.
Auto upload/deploy from build machine to server
Maven has plugins (e.g. Cargo) that can help at doing this but you have to tell him to.
Testing particular URLs/products to test the site flow
Maven itself won't do that. But it can run (integration) tests doing that.
Sending mail regarding deployment status
That's not maven's responsibility (more a Continuous Integration engine task).
My global feeling is that you are thinking too much Ant oriented and maybe expecting too much from Maven. Maven is different, it doesn't really work the way you described, it doesn't work like Ant. My recommendation would be to either fully migrate to Maven and adopt its philosophy or to stick with your current Ant solution (and maybe consider using the Maven Ant Tasks or Ivy to leverage things such as dependency management, artifact deployment).
See also
How to convert from Ant to Maven (...)
Differences between Ant and Maven
Maven: The Definitive Guide

How can I merge multiple OSGi bundles with BND / Maven-BND-plugin?

I'm using some off-the-shelf OSGi bundles in my application and would like to repackage them together with additional packages that are not yet OSGi compatible into a new bundle.
Case in point is EclipseLink, which is available as several OSGi bundles, most of which are optional, depending on what you want to do. I want to pick those bundles that are relevant for me, add database drivers (for example the MySQl JDBC connector) and repackage them into a new bundle that is easier to deploy.
I'm using the maven-bundle-plugin from Apache Felix. I set up a new Maven project without source code, added the four eclipselink and the mysql connector as dependencies and tried the following:
use the <Embed-Dependency> and <Embed-Transitive> instructions to include all dependencies in one bundle. Problem: Optional dependencies from the eclipselink bundles (for example, javax.mail.internet) become required as the plugin rewrites the manifest. The original bundles contain "resolution=optional" in the manifest and thus work well without.
use the manifest goal of the plugin and a jar-with-dependencies assembly, but that gives me basically the same result, only with more work.
used the bundleall goal of the plugin, which is not quite what I want, because it creates separate bundles again. Even worse, because now these bundles don't have their dependencies inside.
I'm going to face similar issues with Struts 2. I'm not going to be obsessive about this, and just go with a whole bunch of separate third-party bundles, but if I can package them more neatly, I would really like to. I'm aware that a point of OSGi is modularity, so creating big bundles kind of defeats that, but I feel that if your modules are tightly coupled anyway, you might as well put them into a single bundle.
Of course, I could manually tweak the manifests, but I definitely don't want to.
As omerkudat says, this is probably not a good practice to encourage, but as you have your reasons, this is a way you could do a poor-man's merge.
Assuming you are handling the OSGi manifest yourself, you only really need to get all the classes from the bundles and jars into the target/classes directory before the package phase.
You can do this with either of the dependency plugin's unpack-dependencies or unpack goals. I'd use the unpack-dependencies if you want to process all the project dependencies (or those following a certain naming patter or in a certain groupId) and the unpack goal if you want to have fine control over the artifacts to be unpacked (at the expense of a verbose POM). I'll assume unpack in my example. Each unpack is output to the project's outputDirectory (i.e. target/classes).
Note this will overwrite duplicate artifacts from each package in the order they're downloaded, so the manifests will be clobbering each other. To ensure your artifacts are managed correctly, I would bind the unpack goal to an early phase so that your src/main/resources are copied on top of the unpacked contents and not overwritten. In the sample below this phase is generate-resources, so it will happen after your local compile. If you need to overwrite any of the classes, use an earlier phase to unpack the dependencies such as generate-sources
My sample below unpacks the contents of junit-3.8.1 and commons-io 1.4 (just the first two dependencies I had declarations for) into target/classes before the project's resources are copied there. Note that the versions are defined in my dependencies section. If you haven't got the bundles/jars declared as dependencies you'll need to declare the version in the artifactItem as well.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<overWrite>false</overWrite>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
</artifactItem>
<artifactItem>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<overWrite>false</overWrite>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
</artifactItem>
</artifactItems>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>