Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use dependencies of a project that's been marked as provided?

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?

like image 725
Luiggi Mendoza Avatar asked Apr 26 '16 20:04

Luiggi Mendoza


People also ask

What are provided dependencies?

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 ...

What is a dependency manager how can you use it in a project?

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.


1 Answers

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):

  • Use a common parent pom where you could declare the list of shared dependencies, that is, dependencies that will be used by all children projects, defined (and maintained) once.
  • Use the 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).
like image 119
A_Di-Matteo Avatar answered Oct 22 '22 06:10

A_Di-Matteo