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.
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.
I have a library that has several sub modules. I have set the version for the library in the parent POM.
<groupId>com.softtech</groupId>
<artifactId>BatchLibrary</artifactId>
<version>2.1</version>
<packaging>pom</packaging>
Also, I have created a Maven Bill Of Materials(BOM) project where this library is defined.
In first case, I set the version for entire library in BOM as below
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.softtech</groupId>
<artifactId>BatchLibrary</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
</dependencyManagement>
In second case, I set the version for library's each sub module individually like below
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.softtech</groupId>
<artifactId>BatchLibrary-core</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>com.softtech</groupId>
<artifactId>BatchLibrary-web</artifactId>
<version>2.1</version>
</dependency>
</dependencies>
</dependencyManagement>
I have added this BOM to my projects. When declaring library's sub module without version in my project. In first case mentioned above, I get an error
dependency.version is missing
In Second case, it works fine.
Is that is how BOM works? Do I have to define all the sub modules with version individually in my BOM or I can just define the parent POM of my library with version and it should work. If it should? Why It is not working in my case?
The BOM should list the version of all the artifacts. I snipped the following from the Importing Dependencies section of the Maven website's "Introduction to the Dependency Mechanism":
The root of the project is the BOM pom. It defines the versions of all the artifacts that will be created in the library. Other projects that wish to use the library should import this pom into the dependencyManagement section of their pom.
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.
I have a project with multiple Maven dependencies and want to minimize the size of my compiled JAR. Right now it seems that IntelliJ is compiling all of the external dependency source files into my JAR even though I only use a small subset of their functionalities.
I would like to include only the files that are directly used by my module.
You can declare a dependency as optional:
<dependencies>
<dependency>
<groupId>sample.dependency</groupId>
<artifactId>small-dependency</artifactId>
<version>1.0</version> <!-- Will be packaged in JAR -->
</dependency>
<dependency>
<groupId>sample.dependency</groupId>
<artifactId>really-big-dependency</artifactId>
<version>1.0</version>
<optional>true</optional>
</dependency>
</dependencies>
Another approach is to use the provided scope. The difference is provided is used if you know the dependency will be included in the classpath of the application that will run your JAR (e.g. a Web or Java EE container):
<dependencies>
<dependency>
<groupId>sample.dependency</groupId>
<artifactId>small-dependency</artifactId>
<version>1.0</version> <!-- Will be packaged in JAR -->
</dependency>
<dependency>
<groupId>sample.dependency</groupId>
<artifactId>really-big-dependency</artifactId>
<version>1.0</version>
<scope>provided</scope> <!-- Will not be packaged in JAR, needs to be provided in classpath at runtime -->
</dependency>
</dependencies>
Sources:
Maven - Optional Dependencies and Dependency Exclusions
Maven - Dependency Scope
i have made two maven projects : the first is a generic authentification module with spring security with this structure :
ear
|...warModule
| |...ejbModule
|...ejbModule
the second is a CRM have this structure
ear
|...warModule
|...ejbModule
|...ejbModule
now i want to integrate both so i can manage the CRM security with my authentification project (control url access ,permissions ...)is there a way to do that ?
One way is that, you declare first project as dependency in your second project POM file.
For detail you can check: Maven Dependency Mechanism
Sample code to add Dependencies:
<project>
...
<dependencies>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact 1</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>group-a</groupId>
<artifactId>artifact 2</artifactId>
<version>1.0</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>`
Second way and I would suggest to use Overlay approach to integrate multiple modules and another benefit to use overlay is can share common resources across multiple applications.
You have just to add a dependency declaration in one pom.xml file which point to the other artifact. For example lets say the downside lines are your CRM pom file:
<project>
<groupId>crm.group.id</groupId>
<artifactId>crm-artifact-id</artifactId>
<version>1.0</version>
<packaging>ear</packaging>
<dependencies>
<dependency>
<groupId>authentication.group.id</groupId>
<artifactId>authentication-artifact-id</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</project>
It is just a sample and should be updated following your projects/modules group/artifact IDs.