Build War with multi module project - java

I have a multi module maven project with three different modules Module-Data, Module-Domain, Module-Web. All three projects are spring boot projects, however Module-Web is the web component of the project that handles everything web oriented which I want to build a war file for. I have a parent project with the following pom file which contains no code.
<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.somename</groupId>
<artifactId>My-Project</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>module-data</module>
<module>module-domain</module>
<module>modele-web</module>
</modules>
Module-Domain depends on Module-Data and Module-Web depends on both Module-Data and Module-Domain. The problem I'm having is that when I try to build the project using maven it fails when building the Module-Domain with the following erros:
package com.somename.data.model does not exist // class file with this error
Module-Domain class files that imports from the Module-Data project fails with this error. I suspect this is because maven is not adding the Module-Data jar to the Module-Domain when building although its referenced in its pom file. How can I solve this problem and generate a war file with all dependencies?
Module-Domain pom.xml:
<dependency>
<groupId>com.somename.data</groupId>
<artifactId>module-data</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
Module-Web pom.xml
<dependency>
<groupId>com.somename.data</groupId>
<artifactId>module-data</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.somename.domain</groupId>
<artifactId>module-domain</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>

This is a simple straight-forward approach that you are using. Should not cause a problem.
Module-Domain pom.xml:
<parent>
<groupId>com.somename</groupId>
<artifactId>My-Project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.somename.data</groupId>
<artifactId>module-data</artifactId>
<version>0.0.1-SNAPSHOT</version> <!-- Make sure this version is correct -->
</dependency>
</dependencies>
Module-Web pom.xml:
<parent>
<groupId>com.somename</groupId>
<artifactId>My-Project</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>com.somename.domain</groupId>
<artifactId>module-domain</artifactId> <!-- pulls "module-data" as well : transitive dependency -->
<version>0.0.1-SNAPSHOT</version> <!-- Make sure this version is correct -->
</dependency>
</dependencies>
Do maven clean compile on the parent project that would build all the modules.
If you still see any compilation issues, you would need fix the source code.

Related

gradle doesn't resolve placeholder from parent properties in dependency version that is inside library that I specified in build.gradle

I have one interesting question about resolving dependencies versions by gradle. Here is my situation. I deployed my libraries to nexus. In this process I used the flatten-maven-plugin and resolveCiFriendliesOnly flattenMode. As result I have parent pom file and child pom files in nexus.
parent pom file from source:
<groupId>ru.example</groupId>
<artifactId>example-parent</artifactId>
<version>${revision}${changelist}</version>
<packaging>pom</packaging>
<properties>
<revision>0.0.1</revision>
<changelist>-SNAPSHOT</changelist>
<version.base>${revision}${changelist}</version.base>
<example-child.version>${version.base}</example-child.version>
<example-child-dependency.version>${version.base}</example-child-dependency.version>
</properties>
child pom file from source
<parent>
<groupId>ru.example</groupId>
<artifactId>example-parent</artifactId>
<version>${revision}${changelist}</version>
<relativePath>..</relativePath>
</parent>
<artifactId>example-child</artifactId>
<version>${example-child.version}</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>ru.example</groupId>
<artifactId>example-child-dependency</artifactId>
<version>${example-child-dependency.version}</version>
</dependency>
</dependencies>
parent pom file from nexus
<groupId>ru.example</groupId>
<artifactId>example-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<version.base>0.0.1-SNAPSHOT</version.base>
<revision>0.0.1</revision>
<changelist>-SNAPSHOT</changelist>
<example-child.version>${version.base}</example-child.version>
<example-child-dependency.version>${version.base}</example-child-dependency.version>
<properties>
child pom file from nexus
<parent>
<groupId>ru.example</groupId>
<artifactId>example-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<groupId>ru.example</groupId>
<artifactId>example-child</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>ru.example</groupId>
<artifactId>example-child-dependency</artifactId>
<version>${example-child-dependency.version}</version>
</dependency>
</dependencies>
After that I try to build java application with gradle. In build.gradle file of this application I have such line:
dependencies {
implementation("ru.example:example-child:0.0.1-SNAPSHOT")
}
And build fails with error:
> Task :java_application:compileJava
Resolving global dependency management for project 'java_application'
Errors occurred while build effective model from /u01/jenkins_slave/.gradle/caches/modules-
2/files-2.1/ru.example/example-child/0.0.1-
SNAPSHOT/809129e53f76bfb7b6a141e9aeb8ffb1a692e76c/example-child-0.0.1-SNAPSHOT.pom:
'dependencies.dependency.version' for ru.example:example-child-dependency:jar must be a
valid version but is '${example-child-dependency.version}'. in ru.example:example-
child:0.0.1-SNAPSHOT
Why gradle doesn't resolve placeholder of child project dependency?
gradle appearently does not evaluate ${example-child-dependency.version} and you might have to build with mvn in order to produce consumable/static *.pom for gradle. I mean, most likely mvn would evaluate *.pom, while gradle doesn't.
And that might rather be:
<artifactId>example-child-dependency</artifactId>
<version>${version.base}</version>

Include jars in pom.xml

So here is the scenario.
I have a maven project for which I am using some(7) jars for unit testing. All these jars are present on maven remote/local(.m2) repository. and I have to add them individually as dependency.
I want to create a pom (parent) which contain these jars as dependency so that if I include this pom(parent) as dependency, all 7 dependencies are automatically resolved.
I tried this code but i think there are some issues with packaging type. (pom packaging didn't work either).
<?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>some.package</groupId>
<artifactId>full-PACK</artifactId>
<version>1.1</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.21.0</version>
<scope>test</scope>
</dependency>
<!-- 6 more similar dependencies -->
</dependencies>
</project>
I want this pom to just act as pointer, and this should resolve dependencies in their respective packages not in package of this pom. I don't want to create a fat jar for this pom.
Is there a way in which I can use this pom as kind of pointer so that it just tells project to import those 7 jars?
I have not tested it, but following the Maven logic, this should work:
Create a project with packaging pom that references the 7 jars as compile dependencies:
<?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>some.package</groupId>
<artifactId>full-PACK</artifactId>
<version>1.1</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.21.0</version>
<scope>compile</scope>
</dependency>
<!-- 6 more similar dependencies -->
</dependencies>
</project>
Now declare a test dependency on this pom in your project like
<dependency>
<groupId>some.package</groupId>
<artifactId>full-PACK</artifactId>
<version>1.1</version>
<type>pom</type>
<scope>test</scope>
</dependency>
Your approach failed because test dependencies are not transitive. Have a look at the table on
https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html

How to inherit dependencies from other libraries in maven?

I created a custom my-commons library with maven. The commons pom contains eg the following dependency:
<?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">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/>
</parent>
<groupId>de.mydomain</groupId>
<artifactId>my-commons</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<!-- workaround for http://jira.codehaus.org/browse/MASSEMBLY-603-->
<maven.build.timestamp>${maven.build.timestamp}</maven.build.timestamp>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
I installed the custom library into my local repository.
In a different project, I reuse the library. It resolves correctly, so it exists in the repo:
<project ...>
<groupId>de.mydomain</groupId>
<artifactId>my-core</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>my.domain</groupId>
<artifactId>my-commons</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
Now in this project I'd like to use a class org.springframework.web.bind.annotation.ResponseBody.
Problem: the class is not in classpath. So maven complains [ERROR] cannot find symbol.
But why?? I'd expect the dependency being inherited!
Sidenote: I'm using Intellij IDEA if that matters. The same problem applies to all "inherited" libraries. The spring-web lib is just an example.
Please check if .m2 folder contains the jar you want to use or not. You can use mvn install command in commons project to generate the jar. Also you need to add commons project in your project pom that you are running.
You need to create the artifact for your commons project, through its pom.xml.
Like in my below example i created a separate project where i am using the AWS and some other dependency and then final jar, which i am using in other project :-
My AWS-client pom.xml looks like below :-
<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.kaamkaj</groupId>
<artifactId>aws-clients</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>aws-clients</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<aws.sdk.version>1.11.104</aws.sdk.version>
</properties>
<dependencies>
<!--AWS dependency-->
<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-dynamodb -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-dynamodb</artifactId>
<version>${aws.sdk.version}</version>
</dependency>
<dependency>
<groupId>com.mercadopago</groupId>
<artifactId>sdk</artifactId>
<version>0.3.4</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>mercadopago</id>
<url>https://github.com/mercadopago/sdk-java/raw/master/releases</url>
</repository>
</repositories>
</project>
Also, run mvn clean install on the commons pom, in your case.
And then in all other project where i need to include the aws-client , i use the artifact-id of above project, like below :-
<dependency>
<groupId>com.kaamkaj</groupId>
<artifactId>aws-clients</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
Let me know if you have any questions:
Found it: removing the <maven.build.timestamp>... <property> solved the problem. I don't know why it prevented the inheritance to work properly, especially as I didn't get any errors.

How to update the dependency version in the parent pom when building in Jenkins

I have a project with the following 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>
<parent>
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>2.5.1-RELEASE</version>
</parent>
<groupId>com.bb.cc.dd</groupId>
<artifactId>Proj1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>bla bla bla</name>
<description>abcfgd</description>
<!-- Configuration of repositories for dependency resolution -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>aa.bb.cc.dd</groupId>
<artifactId>dependencyProj</artifactId>
<version>2.0.0</version>
<type>war</type>
</dependency>
</dependencies>
</dependencyManagement>
</project>
What I am trying to achieve :
When I start a build in Jenkins for Proj1,I should have an option to start a build for dependencyProj and if that succeeds insert the new version(2.0.1) in the pom of the Proj1 and complete the build for Proj 1.So the updated pom (release version) should look like this (before the maven plugin updates it for the development iteration) :
<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>...</groupId>
<artifactId>...</artifactId>
<version>2.5.1-RELEASE</version>
</parent>
<groupId>com.bb.cc.dd</groupId>
<artifactId>Proj1</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
<name>bla bla bla</name>
<description>abcfgd</description>
<!-- Configuration of repositories for dependency resolution -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>aa.bb.cc.dd</groupId>
<artifactId>dependencyProj</artifactId>
<version>2.0.1</version>
<type>war</type>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Note : I tried the "Trigger build" option from the main project and the Post Build Step "Build other projects" from dependency project but none of them update the versions when cheking in to git.Just to add i used the maven release plugin here.
Is it possible to configure jenkins to update the version of the dependent projects in the pom?

Error parsing lifecycle processing instructions when using spring-boot-starter-parent 1.4.3 with maven (works well on 1.4.2)

The following pom.xml does not work for 1.4.3.RELEASE of spring-boot-starter-parent, and it says "Error parsing lifecycle processing instructions". But once I change the version to 1.4.2, the issue is automatically resolved.
So my question is, is the 1.4.3 version incompatible with the pom schema definition?
<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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
</parent>
<packaging>war</packaging>
<artifactId>SpringCloudConfig</artifactId>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
Deleting the entire .m2 folder or the specific jar files might help, in case there are corrupted jar files in your maven local repository. I solved the problem by removing the C:\Users\yourUserName\ .m2 folder. And then switch back to Eclipse Mars.(I was using Eclipse Neon when the problem occurs). Eclipse Mars is compatible with both the 1.4.2 and 1.4.3 version.
There is no need to delete entire repo. This is caused by corruption of some spring related jars. Just delete following folder from local m2 repo and update Maven project
.m2\repository\org\springframework
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.springframework.boot
spring-boot-starter-parent
1.4.3.RELEASE
test
test
0.0.1-SNAPSHOT
test
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>

Categories