Plugin absent in the POM, but still being invoked by Maven - maven

I have a pom.xml file, and I have commented one dependency and one plugin. After this I refreshed and made reimport, but the plugin works anyway. I can't understand why, because it is absent in the pom.xml.
Actually I try to change output directory for the Surefire Plugin, but it is always target/surefire.
<?xml version="1.0" encoding="UTF-8"?>
<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>TEST</groupId>
<artifactId>TEST</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<!--<org.apache.maven.surefire.version>2.19.1</org.apache.maven.surefire.version>-->
</properties>
<!--<reporting>-->
<!--<plugins>-->
<!--<plugin>-->
<!--<groupId>org.apache.maven.plugins</groupId>-->
<!--<artifactId>maven-surefire-report-plugin</artifactId>-->
<!--<version>2.19.1</version>-->
<!--</plugin>-->
<!--</plugins>-->
<!--</reporting>-->
<dependencies>
<!--<dependency>-->
<!--<groupId>org.apache.maven.surefire</groupId>-->
<!--<artifactId>surefire</artifactId>-->
<!--<version>${org.apache.maven.surefire.version}</version>-->
<!--<type>pom</type>-->
<!--</dependency>-->
</dependencies>
</project>

There are several misconceptions with the question. Let's go through them.
Why is a plugin being invoked when I commented a dependency?
Because a <dependency> has no effect at all on the execution of plugins. This is used to declare what your project depends on in order to compile it and run it. It is separate from the actual build process of your project, which is launched by Maven and invokes several plugins to do some tasks, like performing the actual compilation or copying files, etc.
Why is a plugin being invoked when I commented it out?!
The explanation relies on the existence of build lifecycles. To put it simply, a lifecycle consists of several phases, which consists themselves of plugin goals. There are multiple lifecycles possible but the default one is the central one and typically governs the packaging and deployment of the project. The phases are, for example, compile which represents the phase in which the project's sources are being compiled, or package which represents the phase where the project is being packaged into a deliverable, or test which represents the unit-testing of your project.
And, also by default, there are several plugins already bound to phases of the default lifecycle (depending on the packaging). You will notice that there is:
test: surefire:test
which means that, in the test phase of the default lifecycle (for certain packaging), the goal surefire:test is going to be invoked (see also the documentation). This is what you're seeing here: maven-surefire-plugin, whose prefix is surefire and was used above, has a goal called test, whose purpose is to run the test classes of your project.
There's a second consideration. The explanation above refers to build plugins, declared in the <build><plugins><plugin> element of your POM. What you commented out was actually the <reporting> section, which contains the reporting plugins invoked when generating a website for your project.
The actual question
Actually I try to change output directory for surefire plugin
You can do so by configuring the reportsDirectory of the maven-surefire-plugin, which is by default target/surefire-reports. This would look like in your case:
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<build>
...
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<reportsDirectory>target/someDirectory</reportsDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>
Notice how this is placed inside <build> to configure the build plugins. And you can omit the <groupId>org.apache.maven.plugins</groupId>, it is the default.
Best practice is that all generated files during the build (like Surefire reports) are placed inside target, or more generally, the build directory (which can be obtained with the ${project.build.directory} property in a generic manner).

Related

versions-maven-plugin:update-property not updating pom.xml

Hi Meier I have used the following goal:
mvn versions:update-property
-Dproperty="emom.web.dependency.shr.version"
-Dincludes:org.safeway.com:emom-shr
-DgenerateBackupPoms=false
-DallowIncrementalVersios=true
-DallowSnapshots=true
clean package
My Job B pom.xml is:
<dependency>
<groupId>com.safeway.app</groupId>
<artifactId>emom-shr</artifactId>
<version>${emom.web.dependency.shr.version}</version>
</dependency>
Under the properties it has the version hard-coded:
<emom.web.dependency.shr.version>19.6.5-SNAPSHOT</emom.web.dependency.shr.version>
My Job A pom.xml:
<groupId>com.safeway.app</groupId>
<artifactId>emom-shr</artifactId>
<version>20.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
When I run the above goal, Maven is picking the latest version (i.e. 20.1.0) from Artifactory but when I check the pom.xml of Job B under properties it still says 19.6.5. I need a way to change the 19.6.5 or current version to latest version available. Am I doing something wrong? I'm not able to figure it out.
Here's an example of versions-maven-plugin:update-property working in practice. I've used the common Mockito library as an example that works for everyone as it's in Maven Central.
Starting with this POM (noting the mockito-version property):
<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>abc</groupId>
<artifactId>def</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<mockito-version>2.22.0</mockito-version>
</properties>
<dependencies>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
The simplest way to upgrade it to the latest release version is this:
mvn versions:update-property -Dproperty=mockito-version
Replace mockito-version with emom.web.dependency.shr.version in your case.
You can then start to use more of the goal options to adjust the options. For example, you might:
Permit snapshots, not just releases, with -DallowSnapshots=true.
Disallow major version updates (i.e. third element from the right) with -DallowMajorUpdates=false. Note that the logic around these version number sections seems a bit flaky in the plugin - or isn't how I expect.
Avoid creating backup POMs with -DgenerateBackupPoms=false. This is cleaner, but if you omit this option then you can use mvn versions:revert to get yourself back to where you started.
To apply this to your scenario, I think you need to:
Check you've not got typos in your actual command (like you have in the question and comments).
Get rid of options that don't appear in the options.
Probably, keep things simple by not trying to run this in conjunction with anything else (unless it's in automation), so get rid of the clean package at the end of the command.

How to embed external jars dependency in OSGI bundles?

I am trying to convert my project into an OSGI application. I have few doubts. Suppose ModuleA in my application is dependent on external jars jarA and jarB. Now to make ModeuleA run, I am embedding both the jars using embed-dependency property of maven-bundle-plugin.
Now suppose I have another module ModuleB which is also dependent on jarA. So this module also embeds the jarA. My project ends up having jarA being embedded 2 times which will unnecessarily bloat the size of project.
Is there any way to tell OSGI to load jarA only once and provide it to both the modules.
If converting these jars to OSGI bundles is the only solution, I have few more questions:
What is the easiest way to convert jar to a bundle. BND tool looks like a good solution but I am not able to find proper documentation about it.
jarA will also have some dependent jars. So do I need to convert all the dependent jars to bundles also. My project has more than 100 jars. How can I automate this process.
Thanks in advance :)
There are actually to solutions to this, both a little bit different from what you are doing right now:
Build one "third party dependencies" bundle, which will embed all of the non OSGi dependencies your project has.
Convert every non OSGi dependency to a OSGi bundle.
Option 1 is easier to handle so I think most projects do this. I, personally, prefer option 2. We have a Maven "pom.xml" template that we use to convert those dependencies.
The "pom.xml" looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<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>
<properties>
<library.groupId></library.groupId>
<library.artifactId></library.artifactId>
<library.version></library.version>
</properties>
<artifactId></artifactId>
<packaging>bundle</packaging>
<name></name>
<description>${library.groupId}:${library.artifactId}:${library.version}</description>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Import-Package>*;resolution:=optional</Import-Package>
<Export-Package>*</Export-Package>
<Embed-Dependency>*;scope=compile|runtime;inline=true</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>${library.groupId}</groupId>
<artifactId>${library.artifactId}</artifactId>
<version>${library.version}</version>
</dependency>
</dependencies>
</project>
This does:
Add the non OSGi library as dependency
Tell maven-bundle-plugin to embed this dependency (transitive)
Tell maven-bundle-plugin to export all of the dependencies packages
I left some things blank that you have to set like library.groupId, library.artifactId and library.version. And somethings we need to tweak the configuration of the maven-bundle-plugin. But this is our starting point. Somethings for example, you do not want to export all packages etc.
If you really have 100+ dependencies that you need to convert you might be better of using this template and just adding all of your 100 dependencies as dependency and build one big bundle with all of them inside.
You can find the documentation for the maven-bundle-plugin here:
https://felix.apache.org/documentation/subprojects/apache-felix-maven-bundle-plugin-bnd.html
At this point I also want to mention that there is a new bundle plugin that you might want to consider for this: bnd-maven-plugin.
See: https://github.com/bndtools/bnd/tree/master/maven/bnd-maven-plugin

build multiple modules multiple times in parent pom

There are several applications that need to be built and packaged from a number of modules.
In parent pom, i'm using the profile to invoke builds for different apps.
root
parent/
pom.xml
moduleA/
pom.xml
moduleB/
pom.xml
moduleC/
pom.xml
For example, app "profile-1" would need a subset of existing modules to be built and put together as a tar ball.
The tar would contain several jars and different config files pulled from the target/ of the sub modules.
I'm using a shell script invoked using exec-maven-plugin to put together the tar.
The problem I'm facing is that, in one application, i need to build the same module multiple times but with different maven parameters.
What is the best way to do this?
<profiles>
<profile>
<id>profile-1</id>
<modules>
<module>../moduleA</module>
<module>../moduleB</module>
<!-- <module>../moduleC</module> -->
</modules>
<properties>
<global.version>0.0.1-SNAPSHOT</global.version>
</properties>
<build>
<!-- use maven exec plugin to run a shell script which generates the tar ball picking jars and config files from different modules target dirs -->
<plugins>
</plugins>
</build>
<profile>
</profiles>
A sample sub module pom
<groupId>com.test</groupId>
<artifactId>moduleC</artifactId>
<packaging>bundle</packaging>
<version>${global.version}</version>
<name>test :: ${project.artifactId} :: ${name} </name>
<parent>
<groupId>com.test</groupId>
<artifactId>parent</artifactId>
<version>${global.version}</version>
<relativePath>../parent</relativePath>
</parent>
Things i tried:
1) Can i separate into multiple profiles and invoke them as -Pprofile-1,profile-2?
It did not work for me but i would be doing something wrong.
2) Have another shell script that has mvn command line to build the moduleC in different ways.
- Even though i pass in the "-Dglobal_version", the moduleC run from mvn command line does not seem to find the parent in the repository.
I tried doing a "-N" build to put the parent pom in the repository before building the application but did not help.
Best way is:
mvn clean install --projects moduleA, moduleB
mvn clean install --projects moduleB, moduleC
You can't run multiple builds with maven (see this stackoverflow question)

Maven plugin dependency cannot use parent pom property

I'm hitting a weird edge use case with Maven & curious why it's behaving the way it does.
I'm defining a property in my parent project like so:
<properties>
<some.property.version>1.0.0.0</some.property.version>
</properties>
Now, in a module, I set a version of a dependency for a plugin like so:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>bob</artifactId>
<version>1.0.0.0</version>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>example</artifactId>
<version>${some.property.version}</artifactId>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
This causes Maven to spit out an error:
[ERROR] 'build.plugins.plugin[org.apache.maven.plugins:bob].dependencies.dependency.version' for org.example:example:jar must be a valid version but is '${some.property.version}'. # line 350, column 16
What's bizarre to me is if I move the property being defined down into the module itself, Maven compiles just fine. Is this a bug? Or are there restrictions of visibility to parent pom properties in a plugin for a module?
An insanely fast response from the Apache Maven's distribution list! The parent pom had been refactored, and the module was pointing to the stale parent's artifactId. Kudos to Robert!
Hi,
This makes me wonder if the "right" parent is used, so please double
check the groupId, artifactId and version. If both parent and module
are part of the same multi-module, be sure that the relativePath is
correct (defaults to ../pom.xml) You could also use "mvn
org.apache.maven.plugins:maven-help-plugin:2.2:effective-pom" to
verify that the property is really there with the expected value. If
this is all as expected, then it seems to be a bug.
thanks, Robert

Generating the .war file from maven dependency project

Here I have two projects those are project(1) and project(2).
I am going to generate a .war file for the project(1) but it depends on project(2).
I built the project(2) as a .jar file and added it to the project(1)'s build path but while runnig mvn install it results in compilation errors like:
package com.disha.db.dao.orm.gen does not exist` the package is in the project(2).
Can any one please help to me.
You have to delegate dependency management to Maven and that's actually where it comes in hand, otherwise you can move on packaging and resolving inter-projects dependencies by hand and let the Maven alternative be dropped.
You should make sure you have provided the correct Project Object Module description for your projects (pom.xm) along with tha packaging type.
Then since you want the project(2) to be availble for project(1) at compilation time, you have to declare, project(2) as a dependency of project(1).
project(2) pom.xml (I will refer to it as project-2 since 'project(2)' does not match a valid id pattern.):
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>project2.group.id</groupId>
<artifactId>project-2</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
</project>
Now the project(1) will refer to the project-2 artifact as a dependency with scope compile:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>project1.group.id</groupId>
<artifactId>project-1</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>project2.group.id</groupId>
<artifactId>project-2</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
Note: Update the group and artifact IDs with ones you are using.

Resources