My project has the following structure with multiple jars and wars:
root (pom)
+--core (jar)
+--webapp (jar)
+--childgroup (pom)
+--actual-web-application (war)
+--some-library (jar)
+--othergroup (pom)
+--another-web-application (war)
Where actual-web-application depends on webapp which depends on core. Ideally, I would like to specify the Java EE dependency only in the webapp module and let the actual-web-application inherit it. But because it's a provided dependency, this doesn't work and I have to manually add dependencies for provided stuff like Java EE, jax-rs etc. in every web application.
Is there any way, with dependencyManagement for example, to let actual-web-application inherit the javaee-api from the webapp?
What I've tried, in webapp's pom.xml:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
</dependencies>
</dependencyManagement>
And in actual-web-application's pom.xml:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<scope>provided</scope>
</dependency>
However, it complies about the version so it seems like it's still not carrying over the dependency from webapp's pom.xml.
Put <scope>provided</scope> into dependencyManagement also
Provided dependencies are inherited just as any other dependency would be.
parent pom.xml:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
child pom.xml:
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
</dependency>
</dependencies>
And the child's dependency tree:
--- maven-dependency-plugin:2.8:tree (default-cli) # child ---
com.iei.web:child:war:1.0-SNAPSHOT
\- javax:javaee-api:jar:7.0:provided
\- com.sun.mail:javax.mail:jar:1.5.0:provided
\- javax.activation:activation:jar:1.1:provided
If you are trying to avoid explicitly defining dependencies in the child at all, then you would of course have to move it out of dependencyManagement in the parent and make it a direct dependency, assuming you want every child module to inherit it.
Dependency Management
Related
I am building a project that runs on top of Wildfly 14.0.1-Final.
I wanted to try the BOM feature of maven, so I thought: "I will add the wildfly 14 BOM to the dependency management of my parent POM, and then I will only need to define the groupId and artifactId of each artifact, without caring about version number/scope".
So, in my parent POM, I did add:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.wildfly.bom</groupId>
<artifactId>wildfly</artifactId>
<version>14.0.1.Final</version>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
and to my children POM, I did add a reference to the CDI API:
<dependencies>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
</dependency>
</dependencies>
Yet maven protests that it does not have the version for cdi-api.
The error is:
ERROR] [ERROR] Some problems were encountered while processing the POMs:
[ERROR] 'dependencies.dependency.version' for javax.enterprise:cdi-api:jar is missing. # line 29, column 15
#
I have also tried with the wildfly-javaee8 BOM artifact.
What am I missing/missunderstanding?
#JamesR.Perkins comment made me realize that I did not have setup the import scope for the POM. Also, the correct artifact is org.wildfly.bom:wildfly-javaee8
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.wildfly.bom</groupId>
<artifactId>wildfly-javaee8</artifactId>
<version>14.0.1.Final</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
James was right in that I need to define the scope as provided when I needed to use the dependency, otherwise it cdi-api.jar would end packaged in the ear and this could cause problems.
<dependencies>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
When you add a dependency to the section of your parent POM, it sets a default version for that dependency, but it does not automatically add it to the dependencies section of your children POMs.
In your case, you need to add the for cdi-api to the section of your children POMs, not just in the section of your parent POM.
This should like this:
<dependencies>
<dependency>
<groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId>
<version>14.0.1.Final</version> <!-- version should match the version of wildfly BOM you are using -->
</dependency>
</dependencies>
Also, you can use wildfly-javaee8 BOM artifact instead of wildfly artifact that you are using, it covers all the dependencies you will need for your wildfly application development.
You can also check your wildfly documentation for more information on how to use BOM feature in wildfly.
According to the maven docs Dependency management
is a mechanism for centralizing dependency information.
and from this question here SO Question, many people suggested to use Dependency managmement instead of dependencies when we have a common jar file for all children.
as in dependency management , dependencies are propogated only when children request for it but incase of dependencies the dependecies are propogated even when not required.
but wouldn't it be a better approch when the jar file is common to all children ,i.e when all the children inherit the same jar file
for example (rewritten example taken from maven docs)
child a
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
</dependency>
<dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
</dependency>
</dependencies>
child b
<dependencies>
<dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-b</artifactId>
</dependency>
</dependencies>
parent of both a and b
<dependencyManagement>
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</dependencyManagement>
but wouldn't this yeild the same result ??
parent of both a and b
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact-a</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
child a
<dependencies>
<dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
</dependency>
</dependencies>
child b
<dependencies>
<dependency>
<groupId>group-c</groupId>
<artifactId>artifact-b</artifactId>
</dependency>
</dependencies>
or did i misunderstand them??
and which one should i use and in what conditions ??
Dependency management section in the parent pom is managing versions and only versions of these libraries, when you are using them in the child projects.
Dependency section on the contrary ENFORCES all child modules to have these dependencies, regardless child modules need them or not.
If you are sure ALL your child modules will use group-a:module-a:version, then feel free to declare it in parent dependencies section.
If you have at least one child module in the project, where such enforced dependency is unnecessary, then dependencyManagement better suites your need.
I am trying to exclude javax.persistence from javaee-api maven dependency
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<exclusions>
<exclusion>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
</exclusion>
</exclusions>
</dependency>
But even after adding the exclusion I still have the javax.persistence package in the javaee-api-7.0.jar
A dependency exclusion excludes a jar from the resolution of the artifact.
It means that the dependency (jar) will not be transitively pulled during the build.
In your case, it means this dependency:
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
will not be included in the resolution of the dependency :
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
and so will not be included in the artifact that you build.
But it doesn't mean that classes with a package that starts with javax.persistence will be removed from the jar.
The javax:javaee-api:7.0 jar will be indeed be provided with its original content.
Besides, your exclusion makes no sense.
org.eclipse.persistence:javax.persistence is not a dependency provided by javax:javaee-api.
javax:javaee-api is the Java EE API while org.eclipse.persistence:javax.persistence refers to a repackaging of the specific javax.persistence API of java EE + some extensions provided by EclipseLink.
I've got a multi-module maven project, with a structure like:
projectA-parent
- module-1
- module-2
And I have another project where I want to bring in all the modules in projectA-parent as runtime dependencies (it's a Spring application, and each module in projectA-parent contains Spring services that I want to be able to autowire).
What I'd like to do is something like
<dependency>
<groupId>projectA-group</groupId>
<artifactId>projectA-parent</artifactId>
<scope>runtime</scope>
</dependency>
so that if I add another module to projectA-parent it is automatically brought in as a runtime dependency (i.e., I don't want to have to add each new module as a dependency in my Spring application as I add them). Is such a thing possible?
You will have to use
<dependencies>
<dependency>
<groupId>projectA-parent-groupId</groupId>
<artifactId>projectA-parent-artifactId</artifactId>
<type>pom</type>
</dependency>
</dependencies>
This will transitively add all dependencies declared in com.my:commons-deps to your current POM.
Using
<dependencyManagement>
<dependencies>
<dependency>
<groupId>...</groupId>
<artifactId>...</artifactId>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
works as a simple 'include' of artifacts versions in your dependency management. Thus, it won't add any dependency in your project.
UPDATE:
Another aprroach would be to use a BOM (Bill of Materials). Check this link for the usage of BOM. It is hidden somewhere at the bottom.
You can create a BOM that lists all your modules as dependencies and then you can include the BOM into your pom.xml like this:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>your_bom_group_id</groupId>
<artifactId>your_bom_artifact_id</artifactId>
<version>you_bom_version</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
I guess I'd just add another module that referred to the other modules in your project, e.g.:
projectA-parent
- module-1
- module-2
- module-deps
with module-deps as a jar or pom that depends on module-1 and module-2.
You'll have to update module-deps as you add more modules, but at least it's only in one place.
I'm working in an application server environment in which I'm using a bom to gather the dependency information like so:
<dependency>
<groupId>org.jboss.bom.eap</groupId>
<artifactId>jboss-javaee-6.0-with-security</artifactId>
<version>${jboss.bom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
However, this particular bom specifies a dependency as "compile" that I wish to have scoped for all of my projects as "provided". However, when I attempt to override the scope in the same pom from which I'm importing the dependency like so:
<dependency>
<groupId>org.picketlink</groupId>
<artifactId>picketlink-federation</artifactId>
<scope>provided</scope>
</dependency>
Maven complains that it cannot find the version, or if I use the version property specified in the bom, the property cannot be found.
I'm fairly certain this is an issue with the import + override in the same pom, because I can override the scope in child projects just fine. Is there a way to both import and override the scope in a single pom?
*all code snippets above come from the same section.
It is certainly doable:
<dependencyManagement>
...
<dependency>
<groupId>org.jboss.bom.eap</groupId>
<artifactId>jboss-javaee-6.0-with-security</artifactId>
<version>${jboss.bom.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
...
</dependencyManagement>
<dependencies>
...
<dependency>
<groupId>org.picketlink</groupId>
<artifactId>picketlink-federation</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
Just remember that you need to redefine your scopes in the <dependencies>and not in the <dependencyManagement> section.
Your scope override will of course propagate to any child POMs, if you use inheritance.