Different result by different profile activate method? - maven

I have been using maven for about two years, but I don't think I understand profiles in maven exactly, especially when I encounter the following problem.
I have a maven project with three modules, secweb-parent, secweb-service and secweb-web, secweb-sevice depends on spring-webmvc, and secweb-web depends on secweb-service.
The problem is :
1) When I use 'mvn clean install -Dinclude', it works well, and spring-mvc.jar will be found in secweb-web.war
2) When I use 'mvn clean install -Pinclude-jar', it doesn't work, and spring-mvc.jar can't be found in secweb-web.war
Anybody know why ? And is there something I must pay attention to when I use profiles ?
(I know I can define scope of dependency, this project here just to demo different result of different profile activate method)
pom.xml for secweb-parent
<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>
<project.version>1.0.0</project.version>
</properties>
<groupId>com.mediatek.dt</groupId>
<artifactId>secweb-parent</artifactId>
<version>${project.version}</version>
<packaging>pom</packaging>
<modules>
<module>../secweb-web</module>
<module>../secweb-service</module>
</modules>
</project>
pom.xml for secweb-service
<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>
<parent>
<groupId>com.mediatek.dt</groupId>
<artifactId>secweb-parent</artifactId>
<version>${project.version}</version>
<relativePath>../secweb-parent</relativePath>
</parent>
<artifactId>secweb-service</artifactId>
<profiles>
<profile>
<id>include-jar</id>
<activation>
<property>
<name>include</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
pom.xml for secweb-web
<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>
<parent>
<groupId>com.mediatek.dt</groupId>
<artifactId>secweb-parent</artifactId>
<version>${project.version}</version>
<relativePath>../secweb-parent</relativePath>
</parent>
<artifactId>secweb-web</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.mediatek.dt</groupId>
<artifactId>secweb-service</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

You mat check the active profile by using the Maven Help Plugin as the following example
change directory to the parent
e.g. cd /my/project/secweb-parent
Then execute the following command twice for comparing
mvn help:help:active-profiles
mvn help:help:active-profiles -Pinclude-jar
Anyhow the significant point is the version, you have defined as 1.0.0. I would prefer to use the 1.0.0-SNAPSHOT instead.
You may see further information about the SNAPSHOT, here.
Why would you use this? SNAPSHOT versions are used for projects under active development. If your project depends on a software component that is under active development, you can depend on a SNAPSHOT release, and Maven will periodically attempt to download the latest snapshot from a repository when you run a build. Similarly, if the next release of your system is going to have a version "1.4", your project would have a version "1.4-SNAPSHOT" until it was formally released.
As a default setting, Maven will not check for SNAPSHOT releases on remote repositories. To depend on SNAPSHOT releases, users must explicitly enable the ability to download snapshots using a repository or pluginRepository element in the POM.
There is also a useful question and answer about the snapshot at our stackoverflow, here as well.
I hope this may help.

Related

Download Maven artifact with version range

I need download specific Maven artifact using version range e.g.:
GroupId:org.apache.logging.log4j
ArtifactId=log4j-api
Version=[2.17.1,)
Right now I need it in one CI job.
How can I do it?
I was hoping to find an easier solution, but at least this works:
Create pom.xml file
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cz.vondr</groupId>
<artifactId>maven-dependency-download</artifactId>
<version>1.0.0</version>
<properties>
<dep.group>org.apache.commons</dep.group>
<dep.artifact>commons-lang3</dep.artifact>
<dep.version>3.12.0</dep.version>
<dep.type>jar</dep.type>
<dep.classifier></dep.classifier>
</properties>
<dependencies>
<dependency>
<groupId>${dep.group}</groupId>
<artifactId>${dep.artifact}</artifactId>
<version>${dep.version}</version>
<type>${dep.type}</type>
<classifier>${dep.classifier}</classifier>
</dependency>
</dependencies>
</project>
And then use it to download artifact using command:
mvn dependency:copy-dependencies "-DoutputDirectory=./downloaded-dependencies" -Ddep.group="org.apache.logging.log4j" -Ddep.artifact="log4j-api" -Ddep.version="[2.17.1,)"
Additional information
Basic description is here:
http://vondrnotes.blogspot.com/2022/09/download-maven-artifact-with-version.html
Working example is here:
https://github.com/bugs84/download-maven-dependency-with-version-range

including test-jar in the runtime scope

i got a war-project and in the test-jar of it, we have aside of the jUnit testcases also the mocks to the neighbor systems (for instance, the roles and users management system).
and we have a maven profile called mocking that adds the test-jar dependency to the war-project, at runtime, so that the mocks are available for the developer, but do not end up by error in production.
<profile>
<id>mocking</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>runtime</scope>
</dependency>
...
not very clean, i know, but we did not want to have just another artifact for only a hand full of mock clases, and it worked so far well with Maven 3.3.9.
now we need a feature of Maven 3.5.0, so i updated to the latest Maven 3.6.2 and get following error:
The project com.my-project:web:0.0.1-SNAPSHOT has 1 error:
'dependencies.dependency.[com.my-project:web:0.0.1-SNAPSHOT]' for com.my-project:web:0.0.1-SNAPSHOT is referencing itself.
which is kind of borderline case.
imho, and since the dependency is of scope runtime, it should be allowed.
is this a bug?
can anyone figure out a better way to achieve this?
many thanks
Michael
UPDATE 20191125:
Without full pom files or at least an example which looks very like your original projects it's hard to guess....
Here a small pom-file to reproduce the problem:
<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>my.project</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>test</name>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
with that file, and nothing else, mvn compile works fine with v3.3.9 but breaks with v3.6.2
If you use the normal setup for creating a test-jar this implies the test-jar is created as supplemental artifact to your usual artifacts which needed to be distinguished from each other which has to be achieved by using the <classifier>tests</classifier>.

how to automatically update maven dependencies in a multi-level project?

At my workplace, different groups works on providing different services.
My team consumes these services. Currently, whenever a new version of Service is rolled out, we manually change the pom.xml to the latest version of dependency and then make a build. I am wondering if there is an automatic way of pulling latest release into build.
Here is an example to explain:
pom.xml
<?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">
<groupId>com.company.product</groupId>
<artifactId>User-Application</artifactId>
<version>1.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<Service1-version>1.0.2</Service-1>
<Service2-version>1.1.2</Service-2>
<Service3-version>2.0.2</Service-3>
</properties>
<dependencies>
<dependency>
<groupId>com.company.product</groupId>
<artifactId>Service1</artifactId>
<version>${Service1-version}</version>
</dependency>
<dependency>
<groupId>com.company.product</groupId>
<artifactId>Service2</artifactId>
<version>${Service2-version}</version>
</dependency>
<dependency>
<groupId>com.company.product</groupId>
<artifactId>Service3</artifactId>
<version>${Service3-version}</version>
</dependency>
.....
....
</project>
When new release of each service is made, we manually change the pom.xml to get the latest dependency. How can this be managed automatically?
The versions-maven-plugin should be able to do this with the task versions:update-properties. See an example here.

Netbeans Maven annotations not supported in source 1.3, use source 5

When building my projects using Maven from Netbeans 6.7, I get these error messages:
Error annotations are not supported in -source 1.3 (use -source 5 or higher to enable annotations)
I've already seen on this thread that I need to add a maven-compiler-plugin configuration to my POM.xml, but I don't want to do this to every project. Can I set this in one central location that will affect all my maven projects? In settings.xml somehow?
I've already configured Netbeans to use Maven 3.0.3 and my JAVA_HOME is pointing to JDK 1.5.
Even if it is quiet simple using Netbeans to configure this in each project :
right click on your project,
select «properties»,
select «sources» in the project properties window,
choose the «source/binary/format» to 1.3
click OK will update your pom correctly.
A better approach will be to use (inheritance in poms) .
Configure the plugin in a parent pom.xml :
<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.mycompany</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>parent-pom</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.3</source>
<target>1.3</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Then after, your modules can inherit this behaviour this way :
<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>
<parent>
<groupId>com.mycompany</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>mavenproject1</artifactId>
<packaging>jar</packaging>
<name>mavenproject1</name>

Maven site on multi module project could not resolve dependency

I want to split my continous integration job (Hudson) into two steps. (Because the runtime with build and reporting together takes too long.)
In the first job, I build my multi module maven project with "mvn package" successfully.
Then I copy my workspace to another location and try to build the project again only with the goal "site" and/or findbugs/checkstyle/pmd to create reports.
But this doesn't work! Maven can't resolve a dependency of my submodules.
(But all JARs are available in its target folders.)
Example:
My structure looks like this:
Parent
A
B
C
D
Project C has as dependency project B.
When I build everything with "mvn site", it generates for project A and B all reports. But halted at project C with error message "Could not resolve dependencies for project B."
But project B is already builded with "mvn package". I.e. I can find the JAR file of project B in its target folder.
Is there any way to resolve the dependency from submodule B without a "mvn install"?
(I don't wanna do this on my ci server. I fear it could be dangerous for other jobs with the same code base.)
Update 08/20/12:
POM of root folder:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>Foo</name>
<groupId>foo</groupId>
<artifactId>bar</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<modules>
<module>parent</module>
</modules>
</project>
Parent POM:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>Foo</name>
<groupId>foo</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<modules>
<module>../bar-a</module>
<module>../bar-b</module>
<module>../bar-c</module>
<module>../bar-d</module>
</modules>
[...]
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>2.5.1</version>
[...]
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>2.7.1</version>
[...]
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.9.1</version>
[...]
</plugin>
</plugins>
</reporting>
</project>
POM of B:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>foo</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<relativePath>../parent</relativePath>
</parent>
<name>Bar B</name>
<artifactId>bar-b</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
[...]
</project>
POM of C:
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>foo</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
<relativePath>../parent</relativePath>
</parent>
<name>Bar C</name>
<artifactId>bar-c</artifactId>
<packaging>jar</packaging>
[...]
<dependencies>
<dependency>
<groupId>foo</groupId>
<artifactId>bar-b</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
[...]
</project>
I was facing quite the same "long time" issue.
The only way (I think) to solve it with your way of working is indeed mvn install, as you suggested it.
But the problem is indeed the way you try to have different behaviours with copying your workspace.
You should instead considering that CI will build and test as often as you want (each commit or every hour), but make reporting just one time (each midnight for example). You would be able to have faster continous builds, and correct documentation and reporting by night.
This is the way we work, and it is quite sufficient. We use jenkins for that, but you could trigger it with every CI soft I think) !
#hourly : mvn clean package (or install) --> from 1 to 5 minutes to run all test on all modules
#daily : mvn clean install site --> from 15 to 35 minutes to run all test on all modules + doc + reports + PDF reports
You can also use profiles to trigger different behaviours, but this is too much sophisticated for such a basic use.

Resources