Maven inherit dependencies from a project into another - java

Given a Maven project A producing a jar:
<groupId>myprojects</groupId>
<artifactId>A</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>some.needed.group</groupId>
<artifactId>some.needed.artifact1</artifactId>
</dependency>
<dependency>
<groupId>some.needed.group</groupId>
<artifactId>some.needed.artifact2</artifactId>
</dependency>
</dependencies>
and a project B depending on A and producing an enterprise archive:
<groupId>myprojects</groupId>
<artifactId>B</artifactId>
<version>1.0</version>
<packaging>ear</packaging>
<dependencies>
<dependency>
<artifactId>A</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
how can I achieve to have the project B ear artifact to include not only the project B's jar artifact but also its dependent artifacts some.needed.artifact1 and some.needed.artifact2?
I edited and added this because it seems that the behaviour occurs only when running mvn from Bamboo:
The strange thing is that it is working when I'm running mvn locally from Eclipse but not when it's being ran by the Bamboo continuous integration server. On a local run I have the application.xml generated correctly with references to all the transitive dependencies the corresponding jar files copied to the lib folder. On Bamboo plan the generated application.xml does not include the references and the jar files are not in the lib folder.

First as a correction I think dependency should be on A, not on B , like this :
<dependencies>
<dependency>
<artifactId>A</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
And about the original question of having the dependent jars , i think they should be available in your EAR file , as you have dependency on A project and which in turn depends on some.needed.artifact1 and some.needed.artifact2(transitive dependencies) as the scope you provided is default so maven will take it as compile and all the jars will be bundled in your ear file.
Thanks

In project B which produces the ear, you can include a dependency to A like this
<modules>
<module>project A</module>
</modules>
<dependencies>
<dependency>
<groupId>some.needed.group</groupId>
<artifactId>A</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
In project A, define the parent project to be project B like the following
<parent>
<groupId>myprojects</groupId>
<artifactId>B</artifactId>
<version>1.0</version>
<name>project B</name>
</parent>
<name>project A</name>

Related

Exclude maven sub modules dependencies from top level module

I created a maven parent project with three modules :
data-layer-module
data-service-module (uses the data-layer-module)
web-module (uses the data-services-module)
Here is a snippet from the parent pom.xml :
<groupId>org.mygroup</groupId>
<artifactId>myArtifact</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>data-layer-module</module>
<module>data-service-module</module>
<module>web-module</module>
</modules>
The data-layer-module pom.xml contains no dependencies to the other modules (it contains only its external dependencies).
The data-service-module has a dependency in its pom.xml to the data-layer-module :
<dependencies>
<dependency>
<groupId>org.mygroup</groupId>
<artifactId>data-layer-module</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
And the web-module has a dependency to the data-service-module :
<dependency>
<groupId>org.mygroup</groupId>
<artifactId>data-service-module</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
Everything is fine but I don't want the web-module to have access to the data-layer-module. I need to enforce the three layer web-service-data model. Which is not the case with this configuration.
I obviously tried manually excluding it from the web-module pom.xml :
<dependency>
<groupId>org.mygroup</groupId>
<artifactId>data-service-layer</artifactId>
<version>1.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.mygroup</groupId>
<artifactId>data-layer-module</artifactId>
</exclusion>
</exclusions>
</dependency>
But this causes compilation error since the data-service-module can't find its data-layer-module dependency.
How could this configuration be done ?
If the web module is going to run in the same jvm as the data-service-layer, then a transient dependency to the data-layer-module is necessary - this is why the exclusion you added casuses the application to fail.
You could consider making a simple api, for example data-service-layer-api, which obviously does not depend on data-layer-module, and is implemented correctly by data-service-layer.
You can still use a multi-module maven project, but now you will have 2 artifacts - a web module, and a data-service, which must be deployed separated.
It's basically a tradeoff between strict dependency analysis and project complexity.

Java 8 to Java 9 migration optimal way for mavenised project

I am migrating my project from Java 8 to Java 9. My project is mavenised. Now for migrating to Java 9, I am planning on creating a separate module directory where all the required dependency of a module will go.
For doing this through maven the only way I know is to use the copy plugin of maven to copy all the required dependency in the module directory. So after running maven installs for a module, the dependent jars will be copied in repository folder(which is by default) and also copied to this module directory folder.
So there will be a copy of the jars and also hard coding in pom.xml for copying specific dependency in the module directory.
This approach doesn't seem to be clean, is there any way out were automatically maven can read my module-info.java file and copy the required dependency not in the classpath but in the specified directory
Here is 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>
<parent>
<groupId>com.aa.bb</groupId>
<artifactId>cc</artifactId>
<version>0.0.1</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>dd</artifactId>
<name>dd</name>
<groupId>com.aa.cc</groupId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>10</maven.compiler.source>
<maven.compiler.target>10</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.11</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<release>10</release>
<compilerArgs>
<arg>--module-path</arg>
<arg>./moduledir</arg>
</compilerArgs>
</configuration>
<dependencies>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>6.2</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
module-info.java
module com.some_module_name {
requires com.fasterxml.jackson.core;
requires com.fasterxml.jackson.databind;
requires org.apache.commons.codec;
requires spring.beans;
requires spring.context;
}
After adding module-info.java to an existing java 10 module and running maven i am getting issue like "package exist is used in module a and module b".
What i believe is while running maven it is looking for module dependency in the .m2/repository and there are loads of jar there as the m2./repository is common for my multiple modules.
So what i was planning to do is create a separate module directory for each module and place the required jar for that module in it which way it even works.
I assume you're making this effort to make sure Maven "does the right thing" regarding the module and class path, i.e. placing direct dependencies of your module on the former and all other dependencies on the latter. If that's so, there's nothing you need to do - from version 3.7 on, the Maven Compiler Plugin does it for you as soon as you add a module-info.java to your src/main/java directory.
You can verify that by running Maven in debug mode with mvn clean compile -X. When you carefully analyze the output, you will see which JARs end up on which path.

How to bundle/package latest version of custom library in maven web project without updating pom.xml?

I have a custom library - Dao.jar which contains the database persistence logic.
I push this jar to artifactory with new version each time there is a change in code as shown below :
mvn install:install-file -Dfile=C:\*****\target\Dao.jar -DgroupId=non-public.com.karthik -DartifactId=dao -Dversion=2.0 -Dpackaging=jar
I have another maven web project which has a dependency on this jar. This jar is also packaged/bundled in the maven webapp project/war.
<dependency>
<groupId>non-public.com.karthik</groupId>
<artifactId>dao</artifactId>
<version>2.0</version>
</dependency>
Currently, I am changing the version of dao dependency in the pom.xml & re-building the maven webapp project each time a new version of Dao.jar is available in the artifactory.
Is there any option to build the maven project with the latest version of Dao.jar without manually changing the dependency version in the pom.xml?
When Maven searches for a dependency, it first checks the local repository (~/.m2/repository). If it's not found, it tries other resources, such as remote repositories defined in the POM file or in the settings file (~/.m2/settings.xml).
By that logic, if you try to use a version of a local project that's not yet installed to the local repository, Maven will never be able to find it to use in another project.
To avoid changing version numbers all the time and manually building both projects. You could create a parent POM for both projects. The parent would then be able to recognize that one of the child projects depends on the other and build them in the correct order.
Based on Luciano's inputs, I have created a multi-module maven project/parent POM with 2 modules(dao & web)
Parent
<groupId>com.karthik</groupId>
<artifactId>test</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
..........
</dependencies>
</dependencyManagement>
<modules>
<module>web</module>
<module>dao</module>
</modules>
Child module # 1 - dao
<parent>
<groupId>com.karthik</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>dao</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>oracle</groupId>
<artifactId>ojdbc6</artifactId>
</dependency>
.........
</dependencies>
Child module # 2 - web(declared dao dependency in POM)
<parent>
<groupId>com.karthik</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>web</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>com.karthik</groupId>
<artifactId>dao</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
.........
</dependencies>
When I run mvn package command at root path of parent pom, both modules - web.war and dao.jar are built. This method ensures always the latest version of dao.jar is packaged in web.war.

how to add project jar into eclipseworkspace\.metadata\.plugins\serverfolder\projectfolder\web-inf\lib

i am using Eclipse IDE. i have a maven projects as lmexadapter-core-api, lmexadapter-core-impl, lmex-moodle-api, lmexserver-mobile-api, lmexadapter-moodle-api, lmexadapter-moodle-impl. i have dependency in pom as below :
<parent>
<artifactId>lmexadapter-moodle</artifactId>
<groupId>com.platysgroup.lmex.adapter</groupId>
<version>1.0</version>
</parent>
<groupId>com.platysgroup.lmex.adapter</groupId>
<artifactId>lmexadapter-moodle-web</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>Maven Webapp Archetype</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>com.platysgroup.lmex.adapter.core</groupId>
<artifactId>lmexadapter-core-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.platysgroup.lmex.adapter.core</groupId>
<artifactId>lmexadapter-core-impl</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>com.platysgroup.lmex.server.mobile</groupId>
<artifactId>lmexserver-mobile-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.platysgroup.lmex.adapter.moodle</groupId>
<artifactId>lmexadapter-moodle-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.platysgroup.lmex.adapter.moodle</groupId>
<artifactId>lmexadapter-moodle-impl</artifactId>
<version>${project.version}</version>
</dependency>
i am using tomcat as my application server. i get all the jar except lmexadapter-moodle-api, lmexadapter-moodle-impl in my D:\EclipseWorskpace\ew-pg\lmexadapter.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\lmexadapter-moodle-web\WEB-INF\lib. because of this application is unable to locate class of lmexadapter-moodle-impl. what should i have to define so it will take both jar in a specified path as above.
please help me.
Thank you
Assuming current version of Eclipse and Maven plugin, is this something that can be solved by adding Maven dependencies to "project deployment assembly"?
If you have your project configured as Dynamic Web Project and Tomcat as server in Eclipse, this is under Project->Deployment Assembly->Add->java build path entries -> Maven dependencies.

Maven: Re-use a POM file in every project

My goal is pretty simple actually but since there are multiple (and seemingly complex ways to do this) I wonder what I need to do... So I have certain runtime libraries (ADF libraries in particular) that are needed to be added to every project. This parent pom file will just have JAR dependencies in it. How can I use this pom file from a child pom file?
I don't think that using inheritance is a good solution here. Even if every project uses ADF artifacts, you don't want all poms to get these dependencies so declaring them in a corporate parent pom is not really an option.
So, instead, my recommendation would be to create a project with pom packaging to group the ADF dependencies together:
<project>
<groupId>com.mycompany</groupId>
<artifactId>adf-deps</artifactId>
<version>1.0</version>
<packaging>pom</packaging>
<dependencies>
<dependency>
<groupId>some.groupId</groupId>
<artifactId>adf-artifact-1</artifactId>
<version>${jdev.version}</version>
</dependency>
...
<dependency>
<groupId>some.groupId</groupId>
<artifactId>adf-artifact-n</artifactId>
<version>${jdev.version}</version>
</dependency>
</dependencies>
<properties>
<jdev.version>10.1.3</jdev.version>
</properties>
</project>
Then, install/deploy this project and declare it as dependency in any project that needs the ADF artifacts:
<project>
...
<dependencies>
...
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>adf-deps</artifactId>
<version>1.0</version>
<type>pom</type>
</dependency>
</dependencies>
</project>
If the child POM file is actually a child (i.e. declares its parent), then it will inherit the dependencies and there is nothing left for you to do.

Categories

Resources