Maven generate jar dependencies then war - java

I'm using m2e Maven Plugin for Eclipse. I'm having 5 eclipse projects. A web application project and then 4 projects as jars dependencies for my web application.
I would like to know how can I package jars before including them in the WAR using "mvn clean install" on war project.
Here's my 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>dispatcher</groupId>
<artifactId>dispatcher</artifactId>
<version>4.0</version>
<packaging>war</packaging>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>referentiel</groupId>
<artifactId>referentiel</artifactId>
<version>4.7</version>
</dependency>
<dependency>
<groupId>mailTemplates</groupId>
<artifactId>mailTemplates</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>qualityTool</groupId>
<artifactId>qualityTool</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>tools</groupId>
<artifactId>tools</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
...
..
.
</dependencies>
</project>
Thank you in advance.

The answer of #Jigar Joshi is good but i thing you need a view of structure which can help you to understand quickly what we mean.
I. Create a top level maven module (parent of war and jars)
You habe already the 5 moduls that you need. Now create a new Maven project as parent which must contain only a pom.xml file.
parent project pom
<project...>
<groupId>groupId</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Define parent pom </name>
<!-- modul -->
<project>
II. Put your jar projects first as modul and at the end the war project. If you have another dependencies in the jar projects you may also try to order them consequently.
parent project pom
<modules>
<module>referentiel</module> <!-- jar -->
<module>mailTemplates</module> <!-- jar -->
<module>qualityTool</module> <!-- jar -->
<module>tools</module> <!-- jar -->
<module>dispatcher</module> <!-- war-->
</modules>
III. in all other project put the parent reference into the poms
<parent>
<groupId>groupId</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
IV. Now you can go to inside the new created parent project and run from there
mvn clean install

Either create a top level maven module (parent of war and jars) and execute mvn clean install
---pom.xml
|
|dispatcher---pom.xml (war)
|qualityTool----pom.xml (jar)
|mailTemplates----pom.xml (jar)
|referentiel----pom.xml (jar)
|tools----pom.xml (jar)
or use --also-make command line option to make dependencies as well

Related

Spring boot multi module maven projects without repository

I have multiple spring boot projects, every project is independent and has its own CICD pipeline.
These projects need some common classes, I have created a separate project with common classes.
Parent
pom.xml (with packaging)
lib-project
pom.xml
project-1
pom.xml
project-2
pom.xml
I can build project easily from the parent directory, it builds all the projects
parent$ mvn clean package
it generates all the jar files and put them in their respective target folder of projects
My problem is I can't initiate this at the parent level, this has to be initiated from within each project from its own pipeline.
and
I cannot use any local or remote repository, to put the dependent jar in m2 using mvn clean install and then refer to it as dependency
I want to build it from the relavent project directory
parent/project-1$ mvn clean package
it shows following error:
Could not resolve dependencies for project com.test.multiple:project-1:jar:0.0.1-SNAPSHOT: Could not find artifact com.test.multiple:lib-project:jar:0.0.1-SNAPSHOT
My expectation stepwise on compilation of project-1
Check if there is a dependency for project-1
Go to ../lib-project
Compile and build it in target folder (or anywhere relative to our project)
Add this generated jar to "project-1" dependency
Compile and build the "project-1" jar file.
Parent Pom Configurations
<project ...>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.test.multiple</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>lib-project</module>
<module>project-1</module>
</modules>
</project>
** Lib project pom **
<project ...>
<parent>
<groupId>com.test.multiple</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.test.multiple</groupId>
<artifactId>lib-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>lib-project</name>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Project-1 pom
<project ...>
<parent>
<groupId>com.test.multiple</groupId>
<artifactId>parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.test.multiple</groupId>
<artifactId>project-1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>project-1</name>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.test.multiple</groupId>
<artifactId>lib-project</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I have multiple spring boot projects, every project is independent and has its own CICD pipeline.
These projects need some common classes, I have created a separate project with common classes.
Congratulations, your projects are not independent any more!
Given the definitions above, here are the dependencies:
lib-project depends on parent;
project-1 depends on parent;
project-1 depends on lib-project.
Please check Introduction to the POM and Guide to Working with Multiple Modules for the discussion on the dependencies in Maven projects.
I cannot use any local or remote repository, to put the dependent jar in m2 using mvn clean install and then refer to it as dependency
Given this limitation, and dependencies listed above, the POMs and source files of all the projects have to be present on the disk for build purposes. The build process has to start from the parent folder. The build process has to build all modules at once.
Also, please consider using mvn clean verify instead of mvn clean install to avoid populating the local repository with the artifacts you are building.
A maven project isn't designed to build its dependencies on demand. However, jenkins can be configured to build downstream projects when changes are pushed to an upstream dependency.
I have also worked around this by using the -pl option on a parent pom in the relevant jenkinsfile to build a subset of the child projects
Jenkinsfile
clone parent project
mvn clean package -pl core,deployable

Can't run maven tests that include many projects

I have many java projects, each with its maven build. They all install fine.
In addition, I have many JUnit tests. These tests may depend on other projects, i.e. a test from Project A may import a class from Project B.
My projects are not structered good (all of the classes are just in src directory and not src/main/java). So when I run mvn clean test I get No sources to compile. If I structure it good by moving all of the main classes to src/main/java and all the tests to src/test/java I keep getting cannot find symbol (with a reference to an import of a class in a different project).
I tried defining <testSourceDirectory>, used many different plugins and profiles and also tried lowering my java configuration level to 1.7, all to no avail.
I even tried defining a TestProject that has a simple POM with many modules (either with only <modules>, or defining <dependencies> or both), but even in this - either I get No sources to compile, cannot find symbol or even package x.y does not exist (or it compiles but trying to include it in other projects does nothing).
Can I run a test that involves classes from other other projects? How?
Maybe you can have and use Test dependencies. I'll explain how i achieve that, hope it's usefull for your project.
I've got a project with many subprojects (named projectA, projectB, etc.) each one with its own Tests. Also one of the projects named 'core' with jar packaging that contains common classes. They look like the following structure:
Main
|- core (jar)
|- projectA (war)
|- projectB (war)
All tests on the diferent projects used common code that finally were placed on 'core' project test clases.
This is how we manage the dependencies on maven 3.1.1.
Only for reference Main is also a project with its own pom.xml
Main (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.myproject</groupId>
<artifactId>MyArtifact</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<properties>
</properties>
<repositories>
</repositories>
<modules>
<module>core</module>
<module>projectA</module>
<module>projectB</module>
</modules>
...
</project>
On core project pom.xml we put:
<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>
<artifactId>core</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>com.mycompany.myproject</groupId>
<artifactId>MyArtifact</artifactId>
<version>1.0</version>
</parent>
<build>
<pluginManagement>
<plugins>
<!-- Common test classes jar creation -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
...
And on the rest of the projects pom.xml we put the dependency with this jar:
<dependencies>
<!-- We put dependency with core.jar an test-core.jar -->
<dependency>
<groupId>com.mycompany.myproject</groupId>
<artifactId>core</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.mycompany.myproject</groupId>
<artifactId>core</artifactId>
<version>1.0</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
Eclipse warns about this maven dependency but it works fin when running Test from the command line with maven.
Hope this helps.

Maven error when pom.xml is packaged an ejb, but goes away when packaged as jar

When I package my pom.xml as an EJB I get an error that I do not understand. This error shows up if I touch the package in any way, to include Ctrl+S and Maven update. The error goes away if I change the packaging back to jar.
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>
<parent>
<groupId>com.myorg.buildparent</groupId>
<artifactId>BuildParent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.myorg.myEjbPackage</groupId>
<artifactId>MyEjbPackage</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>ejb</packaging>
</project>
By changing
<packaging>ejb</packaging>
to
<packaging>jar</packaging>
The error will go away.
Error string for reference:
'Building workspace' has encountered a problem.
Errors occurred during the build.
Errors running builder 'Maven Project Builder' on project 'MyEjbPackage'.
org.codehaus.plexus.archiver.ArchiverException
Even though I can remove the error, I still feel like it should be packaged as an ejb. Does this make sense to anyone? Does my EJB package need to be packaged as a EJB in the pom? I should admit that my skills with Maven are around that of a novice/low intermediate.
Try adding this configuration in your POM. The EJB plugin (which is bound to the lifecycle by default when you select ejb packaging type) doesn't use the same version of the archiver that the jar/war/ear plugins do.
There is a JIRA issue for updating the dependency versions, however it has not been worked yet.
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<version>${maven.ejb.plugin.version}</version>
<dependencies>
<!-- Use the same archiver as the other [j/w/e]-ar plugins -->
<!-- See http://jira.codehaus.org/browse/MEJB-52 -->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-archiver</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-archiver</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
Update
MEJB-52 is fixed in maven-ejb-plugin version 2.4 and later. Consider updating the plugin version to the latest before adding this configuration.

communicate between wars and jar inside ear

I'm new to creating ear and communicaton between wars and jar...
I was having two wars having completely independent functionality.
Now I've to create a Ear, where two application have to work on same functionality,
which is enclosed in a jar.But requirement is I must not include the jar in Pom.xml of both but make use of that jar, where all 3 are under single ear.is this is possible?
I've tested Ear with 2 independent wars and it's working fine now how to achieve above I'm not getting this.
I'm using Maven with Jboss7.1.1.
I went through links like MessageHandler in JAR/WAR/EAR , https://stackoverflow.com/questions/1796255/tell-me-a-clear-differnece-between-ear-war-and-jar but got no idea about above problem.
You can put multiple wars and jars into a ear and they can share the same classloader. This means that all the classes are accessible from all the jars/wars. i.e. it is as if all the classes / resouces are in one archive without the sub-packaging.
I am assuming this is what you mean by "communication between wars and jars".
EDIT: check Making an EAR with Maven for an example of the pom.xml for building an ear. In the example, there is one jar and one war but you could have any number of wars / jars.
Hi got the solution >> here it is.. this is a pom.xml of ear project
<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>0.0.1-SNAPSHOT</version>
<packaging>ear</packaging>
<dependencies>
<!--Dependency for jar-->
<dependency>
<groupId>com.jar</groupId>
<artifactId>com.jar</artifactId>
<version>1.0</version>
<type>war</type>
</dependency>
<!--Dependency for war1-->
<dependency>
<groupId>com.war2</groupId>
<artifactId>com.war2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>war</type>
</dependency>
<!--Dependency for war2-->
<dependency>
<groupId>com.war1</groupId>
<artifactId>com.war1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>war</type>
</dependency>
</dependencies>
<build>
<finalName>Project</finalName>
<plugins>
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.8</version>
<configuration>
<finalName>MyEarFile</finalName>
<version>5</version>
<modules>
<!--Webmodule for war1-->
<webModule>
<groupId>com.war1</groupId>
<artifactId>com.war1</artifactId>
<uri>war1.war</uri>
<bundleFileName>war1.war</bundleFileName>
</webModule>
<!--Webmodule for war2-->
<webModule>
<groupId>com.war2</groupId>
<artifactId>com.war2</artifactId>
<uri>war2.war</uri>
<bundleFileName>war2.war</bundleFileName>
</webModule>
</modules>
</configuration>
</plugin>
</plugins>
</build>
</project>
Note:: groupId and artifactId metioned here must match with groupId and artifactId mentioned in the project's pom.xml.
Also dependency of jar must be present in this i.e. ear's pom.xml and not in both app's pom.xml.
At time of maven install it automatically refers to jar's contents..

Question about maven

I read some useful posts here on SO about previous maven questions, I'm currently very interested in learning maven(cause I like it and because my boss requires me to). I'm currently reading [this][1] book and I'm working my way trough examples. Its a straightforward book but its has some errors inside(trivial ones), yet for a newbie like me can be hard to spot, once spotted it can be easily fixed. Is there any other book better to understand maven from top to bottom?
Second part of the question is relating an example in this book, maybe a simple explanations would resolve my doubts.
Here is the thing, I made a simple-weather project in java which retrieves the weather conditions from yahoo weather server, given the particular zip code it returns weather information.
Then I made an 'simple-webapp'(with maven as well as the one above I forgot to mention that), which is basicaly a web project which has some default servlet already there with maven and it does nothing.
And I have some parent-project I wanna merge those two projects into one, so I made a pom.xml which has 2 modules , 1 to retrieve info(java project) and other to display it on the web (web app).
I made everything work at the end, but here is the odd thing .. if I make webapp display any string "name" lets say then build it independently, it does exactly print that string. But when I put the webapp in the "parent-project" and change this string to "name1" and build it as sa partent-project sub module.. nothing changes ..
So I go back to the point, because simple-webapp is dependent on simple-weather I can't build it anymore on its own, so now if I wanna make some changes to the webapp.. modify the webapp outside the "parent-project" build it there then paste it back to the parent-project and then the changes will apply, why is that, why can't I directly change the servlet content/or add another one in the webapp as the part of the "parent-project"?
Thank you.. I know its a long and boring question, but I'm just trying to learn things and there is no better place to ask than here :D
EDIT - HERE ARE POM FILES FOR EACH PROJECT :
1. simple-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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.sonatype.mavenbook.multi</groupId>
<artifactId>simple-parent</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
<name>Multi Chapter Simple Parent Project</name>
<modules>
<module>simple-weather</module>
<module>simple-webapp</module>
</modules>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2. simple-weather 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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonatype.mavenbook.multi</groupId>
<artifactId>simple-parent</artifactId>
<version>1.0</version>
</parent>
<artifactId>simple-weather</artifactId>
<packaging>jar</packaging>
<name>Multi Chapter Simple Weather API</name>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
3. simple-webapp 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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.sonatype.mavenbook.multi</groupId>
<artifactId>simple-parent</artifactId>
<version>1.0</version>
</parent>
<artifactId>simple-webapp</artifactId>
<packaging>war</packaging>
<name>simple-webapp Maven Webapp</name>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.sonatype.mavenbook.multi</groupId>
<artifactId>simple-weather</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<build>
<finalName>simple-webapp</finalName>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
I am not sure to completely understand your question. However, let's explain some principles in Maven.
So you have such a structure:
parent
+ simple-weather
+ simple-webapp
On a Maven point of view, we have 3 projects here:
parent, which is a pom project (i.e. its packaging attribute is set to pom)
simple-weather, which is a jar project and has parent as parent.
simple-webapp, which is a war project, has parent as parent and simple-weather as dependency.
The parent projects uses two concepts in Maven:
The inheritance, which say that all of his children (simple-weather and simple-webapp) will inherit all of his properties (this concept is almost the same thing as the extends in Java).
The aggregation, which is defined by the definition of <modules>. Aggregation means that every command that will be run on the project will also be run on each module.
What happen if I build (using mvn clean install) on the parent directory?
Maven will "compile" the parent project and then install the pom.xml in the local repository.
Maven will compile the simple-weather project, but as it has a parent, Maven will look the parent pom.xml file into the local repository. Once the JAR is created, it is installed in the local repository.
Maven will finally compile the simple-webapp project. Maven will do the same thing for the parent pom.xml, but also for the simple-weather project.
The situtation explained in the 3rd point is important: If you want to build the simple-webapp project, Maven will always try to find all of his dependencies - including simple-weather - from the local (or distant) repository.
That's why if you build only the simple-webapp without building and installing simple-weather, Maven will not find the latter project, or will find an older version.
So to summarize, when you work on multi-modules project with Maven, try to always run the build and install commands from the root (or parent) directory.
I hope that this explanation is clear enough and help you to understand what happen in your case. Do not hesitate to ask more information...

Categories