Maven multimodule project tries to download inner dependency from repository - java

I have a classical multimodule project with cross dependency
parent pom:
<modules>
<module>mod1</module>
<module>mod2</module>
</modules>
...
<dependencyManagement>
<dependencies>
<dependency>
<groupId>grp</groupId>
<artifactId>mod1</artifactId>
<version>${project.version}</version>
</dependency>
...
mod2 pom:
<dependencies>
<dependency>
<groupId>grp</groupId>
<artifactId>mod1</artifactId>
</dependency>
...
It builds mvn clean install fine, however when CI runs sonar using mvn sonar:sonar ... the maven tries to download mod1 snapshot dependency from repo, which supposed to be part of the same reactor.
Downloading from nexus: http://...mod1/1.0.0-SNAPSHOT/maven-metadata.xml
And it most cases it could not find the snapshot as it was not deployed yet, but it just keeps going. However it slows down the build as I have several modules and each takes a while to make a roundtrip to repository.
Why?

I had a very similar problem: mvn install was working fine, mvn sonar:sonar wasn't.
In my case, it was a test dependency:
<dependency>
<groupId>grp</groupId>
<artifactId>mod2</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
It was solved by adding test-compile to the mvn command:
mvn test-compile sonar:sonar
I got the tip from this answer: https://stackoverflow.com/a/57226037/5269825
I guess maven needs something (like compile or compile-test) to know that the dependency is another submodule.

Related

how to replace SNAPSHOT version when releasing jar using maven release plugin

I first ran maven locally using:
mvn release:prepare -DreleaseVersion=1.1.2 -DautoVersionSubmodules=true -Dresume=false -Dtag=1.1.2 -DdevelopmentVersion=1.1.2-SNAPSHOT
but some third party dependencies like :
<properties>
<core.version>1.0.0-SNAPSHOT</core.version>
</properties>
<dependency>
<groupId>com.demo</groupId>
<artifactId>core</artifactId>
<version>${core.version}</version>
</dependency>
I want to replace 1.0.0-SNAPSHOT with 1.0.0,What should I do now?

How to handle 3rd party JARs and remote repository in Maven POM?

I'm using a Maven dependency that requires setting up a remote repository. In the same project, I'm using a custom built JAR and trying to add it as a dependency as well. The problem is that I get errors saying that Maven cannot find my custom JAR in the remote repository.
In my POM I have multiple dependencies, including my custom built dependency and the dependency requiring the remote repository (confluent). I have tried putting my custom dependency first in the POM and that did not help. I tried removing the repository from the POM and I don't get the error about my custom built dependency, but I get an error for the remote one.
I'm running the code in a Maven Docker container. I've tried running the Docker container with a Bash shell and without the Maven commands, then manually ran the Maven commands inside the container, and manually checked the ~/.m2/repository and confirmed that my custom built JAR is in there.
Ran an interactive Maven container:
docker run -it --rm --name ProcessedObsGen -v "$(pwd)":/usr/src/mymaven \
-w /usr/src/mymaven maven:3.3-jdk-8 /bin/bash
Inside the Docker container:
mvn clean install:install-file \
-Dfile=/usr/src/mymaven/libs/daas-utilities-0.0.1-SNAPSHOT.jar \
-DgroupId=atlas -DartifactId=daas-utilities -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar
mvn exec:java -Dexec.mainClass="atlas.processed_obs_generator.App"
ls ~/.m2/repository
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>atlas</groupId>
<artifactId>processed-obs-generator</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>processed-obs-generator</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>
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>0.10.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.9.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>atlas.daas-utilities</groupId>
<artifactId>daas-utilities</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.confluent</groupId>
<artifactId>kafka-avro-serializer</artifactId>
<version>5.0.0</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>confluent</id>
<url>https://packages.confluent.io/maven/</url>
</repository>
</repositories>
</project>
I run the code as a Docker container with the command:
docker run -it --rm --name ProcessedObsGen -v "$(pwd)":/usr/src/mymaven \
-w /usr/src/mymaven maven:3.3-jdk-8 mvn clean install:install-file \
-Dfile=/usr/src/mymaven/libs/daas-utilities-0.0.1-SNAPSHOT.jar \
-DgroupId=atlas -DartifactId=daas-utilities -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar; \
mvn exec:java -Dexec.mainClass="atlas.processed_obs_generator.App"
I get the error:
Failed to execute goal on project processed-obs-generator: Could not resolve dependencies for project atlas:processed-obs-generator:jar:0.0.1-SNAPSHOT: Could not find artifact atlas.daas-utilities:daas-utilities:jar:0.0.1-SNAPSHOT in confluent (https://packages.confluent.io/maven/)
I've also tried downloading the confluent jar, putting it in the same location that I'm putting my custom jar, installing it the same way, and removing the remote repository from my pom. Then I get errors with the confluent classes I'm using saying ClassNotFoundException.
I was able to solve it.
I rebuilt my utilities jar with dependencies included. Please see Including dependencies in a jar with Maven.
I kept my pom pretty much the same, although I removed some dependencies not being used.
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>atlas</groupId>
<artifactId>daas-utilities</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.confluent</groupId>
<artifactId>kafka-avro-serializer</artifactId>
<version>5.0.0</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>confluent</id>
<url>https://packages.confluent.io/maven/</url>
</repository>
</repositories>
I placed my custom built jar in ${project.basedir}/libs.
I adjusted the maven commands in my docker run command to include my jar with dependencies. I also figured out that the mvn install:install-file ... is only installing the jar and is not (as I assumed) also installing your project. So, I added another mvn clean install command at the end before I executed it.
docker run -it --rm --name ProcessedObsGen -v "$(pwd)":/usr/src/mymaven -w /usr/src/mymaven maven:3.3-jdk-8 mvn clean install:install-file -Dfile=/usr/src/mymaven/libs/daas-utilities-0.0.1-SNAPSHOT-jar-with-dependencies.jar -DgroupId=atlas -DartifactId=daas-utilities -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar; mvn clean install; mvn exec:java -Dexec.mainClass="atlas.processed_obs_generator.App"
In your install-file commands you define -DgroupId=atlas while your POM reads:
...
<dependency>
<groupId>atlas.daas-utilities</groupId>
...

Dynamically add a new maven dependency?

I need to add a new maven dependency to my maven project when project is built by the continuous integration server, but the dependency should not be there when developers are building the project locally.
Is there a way to dynamically add the dependency through a maven plugin so that continuous integration plan can run a maven command and add the dependency by itself?
Using profiles is the best way for this kind of case
Here is the example to customize the dependencies inclusion
<profiles>
<profile>
<id>profile-dev</id>
<dependencies>
<dependency>
depednency A
</dependency>
</dependencies>
</profile>
<profile>
<id>profile-prod</id>
<dependencies>
<dependency>
dependency B
</dependency>
</dependencies>
</profile>
<profiles>
To run the build at dev box mvn install -P profile-dev
To run the build at production mvn install -P profile-prod

How to compile a maven project which reference to another local changed maven project?

I have 2 projects, A and B. B is a lib project and A reference to B.
When I add new function to B, it's ok to run mvn install on B, but it failed on mvn install on A due to can not find the symbol from new B.
I'm sure I did install correctly on project B, but why A still failed to compile and install?
This is A's pom.xml:
<dependency>
<groupId>A and B's group</groupId>
<artifactId>B</artifactId>
<scope>provided</scope>
</dependency>
any clue? Thanks
I would suggest to create a multi-module build like the following:
+-- root
+-- pom.xml
+-- module-A
+-- module-B
In the root pom you need to define the modules like this and define the packaging to pom.
<modules>
<module>module-A</module>
<module>module-B</module>
</modules>
Furthermore you can define a dependency of module-A to module -B simply by:
<project ..
<parent>
<groupId>project.parent</groupId>
<artifactId>parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>module-A</artifactId>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>module-B</artifactId>
<version>${project.version}</version>
</dependency>
..
</dependencies>
..
</project>
With this setup you can simply build all modules from the root folder just by:
mvn clean package
or you can import that structure into Eclipse (m2e installed?) or any other IDE like IntelliJ or Netbeans.
Try mvn clean install to do a totally fresh build of A, or mvn -U install to force Maven to look for updated snapshots. It sounds like your environment is still using the older JAR. It's hard to tell what your setup is from this description -- sounds like you're correctly installing B to your local repository, but I'm not sure if your IDE might be trying to be 'helpful' as well.
You can include the <version> element in the project's as well as dependency's declaration.
pass a version variable from Maven command line. Eg: ${build.version}
Module A's pom.xml:
<groupId>A & B's Group ID</groupId>
<artifactId>A</artifactId>
<version>${build.version}</version>
<dependencies>
<dependency>
<groupId>A & B's Group ID</groupId>
<artifactId>B</artifactId>
<version>${build.version}</version>
<type>war</type>
<scope>provided</scope>
</dependency>
...
So, whenever Project B is built and installed, the dependency will be available in the local maven repository for that particular version and will be picked by Project A

Mulit-module application maven

I've got multi module maven project, where main project depend on sub-module. Every dependency of sub-module is define by version like this: ${pom.version}. I use maven release plug-in. If I try to prepare release, I've got an error about missing version of sub-module.
Example:
main pom is on version 1.0, I try to release it. Maven build every sub-module to version 1.1, then try to build parent, and then crash. Because it can't find sub-module-1.1.
I don't know how to tell maven to build, and immediate install to local-repo every sub-module witch it build. I use maven2.
My pom:
<modelVersion>4.0.0</modelVersion>
<groupId>com.voncuver</groupId>
<artifactId>voncuver</artifactId>
<packaging>pom</packaging>
<version>1.1-SNAPSHOT</version>
<name>multimodule</name>
<modules>
<module>mod1</module>
<module>mod2</module>
</modules>
(...)
<dependencyManagement>
<dependencies>
<dependency>
<artifactId>mod1</artifactId>
<groupId>com.voncuver</groupId>
<version>${pom.version}</version>
</dependency>
<dependency>
<artifactId>mod2</artifactId>
<groupId>com.voncuver</groupId>
<version>${pom.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
(...)
You should probably post a bit more of your project structure, but typically a multimodule project looks like this:
project
mod1
mod2
mod3
pom.xml
The main pom.xml would have "pom" packaging type, and have a section in it to build everything else:
<packaging>pom</packaging>
<modules>
<module>mod1</module>
<module>mod2</module>
<module>mod3</module>
</modules>
Then, the surest way to make sure things build properly is to execute:
mvn clean install
Without the "install", it's highly possible that things might not be found in the maven reactor, especially depending on what version of maven you are using (and a few other factors).

Categories

Resources