Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using different versions of dependencies in separated Java platform modules

I expected it's possible to use i.e. Guava-19 in myModuleA and guava-20 in myModuleB, since jigsaw modules have their own classpath.

Let's say myModuleA uses Iterators.emptyIterator(); - which is removed in guava-20 and myModuleB uses the new static method FluentIterable.of(); - which wasn't available in guava-19. Unfortunately, my test is negative. At compile-time, it looks fine. In contrast to runtime the result is a NoSuchMethodError. Means that, the class which was the first on the classloader decides which one fails.

The encapsulation with the underlying coupling? I found a reason for myself. It couldn't be supported because of transitive dependencies would have the same problem as before. If a guava class which has version conflicts occurred in the signature in ModuleA and ModuleB depends on it. Which class should be used?

But why all over the internet we can read "jigsaw - the module system stops the classpath hell"? We have now multiple smaller "similar-to-classpaths" with the same problems. It's more an uncertainty than a question.

like image 218
Daniel Avatar asked Jul 24 '17 14:07

Daniel


People also ask

How do I use Java 9 modules?

To set up a module, we need to put a special file at the root of our packages named module-info. java. This file is known as the module descriptor and contains all of the data needed to build and use our new module. We start the module declaration with the module keyword, and we follow that with the name of the module.

How do Java modules work?

A Java module is a packaging mechanism that enables you to package a Java application or Java API as a separate Java module. A Java module is packaged as a modular JAR file. A Java module can specify which of the Java packages it contains that should be visible to other Java modules which uses this module.

Which are valid keywords in a Java module descriptor module-info Java?

The keywords exports , module , open , opens , provides , requires , uses , with , as well as to and transitive , which we introduce later, are restricted keywords. They're keywords only in module declarations and may be used as identifiers anywhere else in your code.

What is module in Java with example?

A module is a collection of code, data, and resources. It is a set of related packages and types (classes, abstract classes, interfaces, and more) with code, data files, and some static resources. For example, the module descriptor module-info. java is one of the resources in a Java 9 module.


2 Answers

Version Conflicts

First a correction: You say that modules have their own class path, which is not correct. The application's class path remains as it is. Parallel to it the module path was introduced but it essentially works in the same way. Particularly, all application classes are loaded by the same class loader (by default at least).

That there is only a single class loader for all application classes also explains why there can't be two versions of the same class: The entire class loading infrastructure is built on the assumption that a fully qualified class name suffices to identify a class with a class loader.

This also opens the path to the solution for multiple versions. Like before you can achieve that by using different class loaders. The module system native way to do that would be to create additional layers (each layer has its own loader).

Module Hell?

So does the module system replace class path hell with module hell? Well, multiple versions of the same library are still not possible without creating new class loaders, so this fundamental problem remains.

On the other hand, now you at least get an error at compile or launch due to split packages. This prevents the program from subtly misbehaving, which is not that bad, either.

like image 53
Nicolai Parlog Avatar answered Oct 05 '22 22:10

Nicolai Parlog


Theoretically it is possible to use different versions of the same library within your application. The concept that enables this: layering!

When you study Jigsaw under the hood you find a whole section dedicated to this topic.

The idea is basically that you can further group modules using these layers. Layers are constructed at runtime; and they have their own classloader. Meaning: it should be absolutely possible to use modules in different versions within one application - they just need to go into different layers. And as shown - this kind of "multiple version support" is actively discussed by the people working on java/jigsaw. It is not an obscure feature - it is meant to support different module versions under one hood.

The only disclaimer at this point: unfortunately there are no "complete" source code examples out there (of which I know), thus I can only link to that Oracle presentation.

In other words: there is some sort of solution to this versioning problem on the horizon - but it will take more time until to make experiences in real world code with this new idea. And to be precise: you can have different layers that are isolated by different class loaders. There is no support that would allow you that "the same object" uses modV1 and modV2 at the same time. You can only have two objects, one using modV1 and the other modV2.

( German readers might want to have a look here - that publication contain another introduction to the topic of layers ).

like image 38
GhostCat Avatar answered Oct 05 '22 22:10

GhostCat