Reputation: 1774
I have following dependency hierarchy in a service:
Service A
-> Lib A
-> Lib B
-> Lib A
-> Lib C
-> Lib A
-> Lib D
-> Lib A
"->" means depends on.
There are lot of problems that pops up because of above structure. The one that requires most of the efforts is to keep the Lib A sync across all modules to avoid class conflicts and other issues.
I am using maven for dependency management but it doesn't solve the issue as I have to update all dependencies to avoid conflicts (semantic and functional)
Is there any better way to manage these dependencies?
Scenario 1: Adding new code to Lib A which is only going to be used by Lib B.
In this case, it wouldn't be sufficient to change Lib B. I will have to add Latest version of Lib A in service A so that maven picks up the correct version.
Scenario 2: Non Backward compatible changes in A.
This will cause problem if I just update Lib A in Service A because other libs (B, C and D) doesn't know about this new change and it might break (e.g Adding a new argument in an existing method method). I will have to update all of them.
Scenario 3: Changing an existing method in Lib A.
This will work fine. If I update this Lib A in service A, maven will pick up latest Lib A and all libs (B,C and D) will use latest version of Lib A.
Upvotes: 3
Views: 355
Reputation: 2475
Service A
-> Project Commons
-> Lib B_A (functional dependency, commons B no functional dependency with C and D)
-> Lib C_A (functional dependency, commons C no functional dependency with B and D)
-> Lib D_A (functional dependency, commons C no functional dependency with B and C)
-> Lib A (technical dependencies , commons in B C D)
-> pom_parent
-> Lib B
-> Lib A and Lib B_A
-> Lib C
-> Lib A and Lib C_A
-> Lib D
-> Lib A and Lib D_A
pom_parent (SNAPSHOT)
Upvotes: 0
Reputation: 9492
Think about Domain Driven Design and more specifically Bounded Context Pattern. It allows code duplication to certain degree. The flexibility will allow you to decouple "jar A" from the rest very easily.
What exactly is a Bounded Context?
Lets imagine that we have User. This User in one context can be UserAdmin or in another context it can be PowerUser or in another context can be just User.
Now lets imaging that we have 3 services addressing three different functions of a User based on hist type. Each Service represents a different Context of the term User. Now the point here is that instead of creating one almighty "User" in your case it will go in the almighty "libA" we will create 3 users based on the context and will give different functions of these 3 users. Eventually we will end up with 3 domain objects AdminUser for service 1 PowerUser for service 2 and just User for service 3. This three services will not have dependencies on each other, unless it fits us and even if they have it will be piece of cake to decouple them at any point.
If we start thinking of a service as Onion. On the first layer we would have persistence. On the second layer we will start unwrapping our domain model. On the next layer we will start building our services. Then our network representation and so on.
Thinking in terms of Bounded Context will allow you to create a unique Bounded context on per service basis and this will allow you to not have this interdependencies in between the different Jars . This is because your service will not necessarily share code with other services.
Upvotes: 0
Reputation: 43817
You might look into OSGi or Java 9 modules (not finished yet of course). I am not an expert but I believe these frameworks allow for a concept of modules/bundles where each module has its own class loader. This means if lib B and lib C were modules they could have different versions of lib A and everything would work smoothly. It does prevent lib B and lib C from communicating directly but given your dependency tree that should be desired.
--Update to match your update--
Scenario 1:
Update lib A version only in module B. Module C/D can remain unchanged.
Scenario 2:
You can update lib A in module B/C/D independently when each of those modules is ready to use the new version of lib A.
Scenario 3:
No issue.
Upvotes: 0
Reputation: 4948
Not sure if i understand the question right , are you mentioning of dependency conflict between libraries.
If you have same dependencies across libraries , one way of sorting it out could be to use exclusions , that way you can add one dependency and exclude the others (https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html)
Upvotes: 1