Get away from dependency hell in maven possible

18 views
Skip to first unread message

mike

unread,
Mar 24, 2022, 10:46:45 AMMar 24
to
Hi,

Today we have a framework that user make java code calls to a java API.

Project, a monolith,consists of multiple maven modules but also numerous in-house made java libraries.

The problem today is that each module depends on specific versions of libraries. So when using any of the in-house libraries we cannot just upgrade a dependency since the same must be done for other libraries used in the project.

So what we wish for is a separate deplorable java components that can be managed independently.

I have read about micro-services but they only use rest calls (AFAIK) but we need to make java calls between the different components.

Is it possible? Any hints?

br,

//mike

Eric Sosman

unread,
Mar 24, 2022, 1:16:19 PMMar 24
to
On 3/24/2022 10:46 AM, mike wrote:
> [...]
>
> So what we wish for is a separate deplorable java components that can be managed independently.

Perhaps I can help: My Java has often been called "deplorable."

:)


--
eso...@comcast-dot-net.invalid
Look on my code, ye Hackers, and guffaw!

e.d.pro...@gmail.com

unread,
Mar 24, 2022, 1:32:13 PMMar 24
to
For my work project I put all the code in one project. This project has a pom with dependency management specifying all dependencies and versions. Under that project it's broken up into modules. Each module has it's own pom which can specify type, either war type to be published with it's own url, jar type to be packaged as a dependency of a war module, or pom type which simply executes a pom step. Each of those modules has it's own pom which specifies it's own dependency, with no versions by default. Versions can inherit from the parent, and may be overridden if you need to make an exception.
If you're hosting different versions of in house dependency jar code, you can put those jars into the project in a folder structure, under the main or a separate module. You can use the pom with the maven-install-plugin to install those jars from there into your local maven repository, and reference them from other modules as regular maven dependencies.
While they share a common structure for version management, and can reference each other so common code gets built into one jar which may be copied into multiple wars, each war module may be deployed (deplored?) independently. Put these wars on the same domain and they should have no problem calling each other.

Arne Vajhøj

unread,
Mar 24, 2022, 2:19:35 PMMar 24
to
On 3/24/2022 10:46 AM, mike wrote:
You can only do what you can do.

You can switch to a model with multiple micro-services
that makes network calls to each other.

Or you can stay with a single application and Java
calls.

If you chose the latter then the way to support different versions
of libraries it to switch to a model where each module is loaded
by separate classloaders from separate classpaths.

There are a few options for that. You can go custom. There is
OSGi. Etc..

Arne

e.d.pro...@gmail.com

unread,
Mar 24, 2022, 2:24:19 PMMar 24
to
> You can only do what you can do.
>
> You can switch to a model with multiple micro-services
> that makes network calls to each other.
>
> Or you can stay with a single application and Java
> calls.
>
> If you chose the latter then the way to support different versions
> of libraries it to switch to a model where each module is loaded
> by separate classloaders from separate classpaths.
>
> There are a few options for that. You can go custom. There is
> OSGi. Etc..
>
> Arne

Deploy an app as multiple war files, each gets it's own classpath. They can share code from a common module which packages a copy of a jar into each war. If they need to share each other's code, it's http calls, which is normal in the front end code.

Arne Vajhøj

unread,
Mar 24, 2022, 2:49:21 PMMar 24
to
On 3/24/2022 2:24 PM, e.d.pro...@gmail.com wrote:
>> You can only do what you can do.
>>
>> You can switch to a model with multiple micro-services that makes
>> network calls to each other.
>>
>> Or you can stay with a single application and Java calls.
>>
>> If you chose the latter then the way to support different versions
>> of libraries it to switch to a model where each module is loaded by
>> separate classloaders from separate classpaths.
>>
>> There are a few options for that. You can go custom. There is OSGi.
>> Etc..
>
> Deploy an app as multiple war files, each gets it's own classpath.
> They can share code from a common module which packages a copy of a
> jar into each war. If they need to share each other's code, it's http
> calls, which is normal in the front end code.

A servlet engine also provide the different classloaders, but if
a switch from Java calls to HTTP calls is warranted then SpringBoot
micro-services is a bit more modern.

Arne

mike

unread,
Mar 25, 2022, 2:31:39 AMMar 25
to
Hi Eric,

Yes it should read "deployable". Sorry about the confusion :-)

//mike

mike

unread,
Mar 25, 2022, 3:06:22 AMMar 25
to
Thanks for all the hints!

Current project is maven modules. Then modules has dependencies to inner-source libraries that can in turn use open source libraries :-)

Users write test code like:

XX myXXResource = Resource.getXXResource();

myXXResource.connect();
myXXResource.upgrade();
//helpers to poll for a ready state on the resource before we can continue.

So end-users have their own repo (git) and creates a dependency to our framework and then write testcases using similar code as above.
The problem as I see it is that we deploy one large jar (monolith) but only a portion is really needed by each test repo.

And besides, as mentioned in the heading of this message, we have the same dependency in multiple places which makes it hard to upgrade.
OSGI seems interesting...

In an ideal world when test code is running in a user repo we should only load components that are actually used and not more.

I appreciate all your thoughts and ideas and experienced input for an open discussion.

//mike

Reply all
Reply to author
Forward
0 new messages