[JAVA] Java 9 and Jigsaw and why I don´t use it yet

I recently started a new framework project for text classification and wanted to move to Java 9 and the Jigsaw module system. Unfortunately I had to stop the usage of Jigsaw in Java 9 for several reasons and I want to share, what exactly is the problem.

General project structure

The structure of the framework should somehow use the “use and provide” mechanism from jigaw, so that I can use a core package, where the interface is defined and just plugin other modules, which offer the implementation for an API. The modules look like this:

 

Build system

The first thing after reading about the general idea of jigsaw was to decide if I use Maven or Gradle. I tried to create a simple archetype with Gradle first, because it was my preferred build system. After some time I gave up, because with Gradle it is way too complicated. It works somehow, but if you take a look at the build file, you see that you don´t want to deal with that. Here you can find a repo, where you can see a working example.

Anyway with maven it works much easier and my multi module maven project worked after some time. To get it working you can just use a standard multi project structure from maven:

IDE

Also IntelliJ supports jigsaw somehow, even if not everything is as easy as expected. For example if you use a class in your module and you have not required it already in the module-info, you don´t get a autofix suggestion to require it, but if you write the import statement IntelliJ will suggest you to add it as a requirement in the module-info.

Using Spring 5

This is where the pain starts. So lets say we want to use Spring Boot 2 (1.x is not using Spring 5) in the API. You might thing this should work out of the box, but it doesn´t. When you add the dependency in maven and start the application, you will get some weird errors. Basically this is because Spring uses the Reflection API on your classes and Java 9 does not allow it by default. So besides adding all the requirements for Spring to your module, you also have to add this:

Now what about using Spring in the provider module and configure the beans there and autowire it somehow in the API, because it implements the Interface? Well that was my first intuition, but it does not work so far. If you would add the Spring beans from the provider module to the API Spring context, you need to reference to the module class for using the @Import(ProviderSpringConfiguration.class). I tried it with @ComponentScan before, but it did not work.

The alternative was to use the Java ServiceLocator mechanism to load the implementation, with knowing only the interface:

 

Well this works, but now the service instance is created in the API module and even if it is basically managed by spring, we can not pass constructor arguments.

Writing tests

I wanted to add JUnit 5 to the project and the Spring Extension to have a spring context in the tests. Well the only thing I can say is, that it does not work. I don´t know exactly where the problem is, but the dependency is not resolved, the only solution was to add Junit5 as a library in IntlliJ itself. But with the maven surefire plugin it does not work.

Here you can find the code, jsut in case you want to make it working 🙂

Where are the benefits?

For the JVM itself it makes sense to have modules to make smaller JREs for embedded devices and so on. But even if you want to adopt the modules mechanism to your library, you will go through a lot of pain and in the end there is not really a good reason to do so. At the moment it does not really make sense to me, to move to jigsaw.

0.00 avg. rating (0% score) - 0 votes

Related Posts

Leave a reply


This website stores some user agent data. These data are used to provide a more personalized experience and to track your whereabouts around our website in compliance with the European General Data Protection Regulation. If you decide to opt-out of any future tracking, a cookie will be set up in your browser to remember this choice for one year. I Agree, Deny
612