I have the following scenario, simplified:
projectX ---> projectA ---> projectB
Where --->
means "depends on".
ProjectB is really simple. It doesn't declare any dependenci. In fact, the only relevant part is this:
<packaging>jar</packaging>
In pom.xml of projectA I have declared the dependency to projectB:
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>projectB</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
And in pom.xml of projectX I have:
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>projectA</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
The problem is that projectX needs to use components (classes and such) that are defined in projectB. If I change the scope in projectA to use compile
for projectB, everything will work, but then projectB will be included when generating the war in projectX, and I need to have this library out of the generated war because I'm providing projectB in other part of the project.
In the real scenario, I have several dependencies like projectB that affect projectA, so to reduce the size of the generated war, I would like to set them as provided, but then projectX cannot use the components defined in any of those libraries. Example of components: Spring, Hibernate, etc.
Question: Is there a way to achieve this in a clean way without re-declaring dependencies in lots of places?
Dependencies defined by compile and provided must be resolved against a repository and they are also visible for runtime execution; the difference strives that provided should not expose its dependencies to the final packaging as they are expected to be provided by the hosting environment (hence the name), such as an ...
A dependency in project management refers to a series of tasks that are interrelated. There are several different types of dependencies in project management: Finish-to-Start: Task B cannot start until task A has been completed. Start-to-Start: Task B cannot start until task A starts.
The problem is that projectX needs to use components (classes and such) that are defined in projectB.
Then ProjetB should be a dependency of ProjectX indeed, in provided
scope, again. Re-declaring the dependency would change how Maven would handle it as transitive dependency (that is, you can override its behavior by saying: I want this dependency in my project with this scope).
but then projectB will be included when generating the war in projectX, and I need to have this library out of the generated war
This will not happen by re-declaring it in provided
scope. Alternatively, you could change the scope of ProjectB in ProjectA to compile
and then configure the maven-war-plugin
to exclude them, using inclusions/exclusions.
Before doing so though, you should double-check why semantically (or requirements-wise) ProjectB was set as provided
in ProjectA and what would be its impact on other consumer projects.
Update
Both approaches above may suit your needs. Alternatively, as suggested in comments further options could be more sustainable and clear in the long run towards a better governance and maintenance (centralization):
dependencyManagement
section in ProjectX to change how Maven dependencies mediation would handle transitive dependencies on ProjectA, without changing ProjectA or ProjectB (similar to option 1 at the top of this answer, with the difference that it will only be applied whenever the dependency comes into scope and ignored otherwise). To centralize this management, again, would be better to do so in a common parent (option above).If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With