Jigsaw – Java 9

As previously mentioned here, Java 9 is coming soon, and with it comes an interesting approach called Jigsaw. It was first announced to release with Java 7, but was delayed to Java 8 and will now release with Java 9. What is Jigsaw, you think, and is it as horrific as it sounds like? Well, probably not, but it has the potential to improve the development-process of Java-Applications and Libraries a lot.

Why would I need it?

Ok let us assume, you have a big project where you develop a browser-based enterprise application. Let us say, you create two top-level-packages in this example: front-end and back-end. You want to interact between front-end and back-end only over a fixed set of well-defined interfaces, you created only for that purpose. All other classes should not be visible outside of their base package.
Currently, there is no real way to achieve that.
I mean, you could put all your classes directly in the two top-level-packages, without any sub-packages and set their visibility to package. But be honest, that would be a mess if you have thousands of classes in there without sub-packages. But as soon, as you introduce some sub-packages, you are forced to set the visibility of the interacting classes to ‘public’.

A different approach is, to create sub-projects for the main functionalities (frontend, backend). But these two are just on the top level and I am pretty sure, you want to structure your project a little bit more. So you are very likely to end up with many small sub-projects, you only need for structure. You will define your dependencies on project-level via jar-files (one for each sub-project) and the process of structuring is outsourced to the build-process.

A third approach are microservices. They force you to encapsulate your functionality. You can only communicate between them via inter-process-communication. But you need much more effort, to maintain & develop a bunch of microservices instead of one big application. And the problem of structuring your code within one microservice remains.
And there are some more workarounds we currently use to archive, what Jigsaw will introduce to us: A fully modular system with one more visibility layer.

What is Jigsaw about?

There are four main goals, as stated by the developers:

  1. Offer easy scalability (especially to small devices)
  2. Improve security
  3. Optimize the construction-process and the maintainability of libraries and big applications
  4. Improve the performance of applications

These goals are archived, by finally introducing a modular system to Java. Because of that, the new JDK coming with Java 9 will be divided into modules. These modules are strongly encapsulated and help to provide clear dependencies for every project or library.
The scalability to small devices is reached by providing only the specified dependencies instead of the entire Java SE when you deploy your application.
Security could be improved, because the modules are strongly encapsulated and the relations between the modules should be clearer which helps finding possible security breaches. Also, the end user of your library can only use the selected packages of your library, which can help to prevent unauthorized access to the internal implementation of your library. More on this later.
The Construction Process and maintainability should be made far easier because of the clear dependencies. You also do not see all the public classes for each library, you will only see those which were made visible to you.
The improve in performance is inclined with the scalability to small devices. As said, you can apply a whole-program-optimization technique to your complete setup (including your application, your dependencies and the platform you want to deploy your application on).

How does it work?

Normally, every public class of your library or application-project is visible to everyone. Now you can select which classes or interfaces are visible to the end user and which classes are not. You only have to put a module-declaration (module-info.java) in your project. There you can specify which modules you want to import in the requirements-section, and which classes and interfaces you want to provide to the user in the exports-section. Every class which is not mentioned in this exports-section will NOT be visible from outside the module, even if the class and its attributes/methods are public. They can also not be accessed through ReflectionAPI. You can specify, who you want to export your classes to. You normally export them to everyone, but you could also export some of your classes only to one specific library (example for this: see below). If you do not specify your requirements and exports in the module-info.java (for example in older projects and libraries) or do not create a module-info.java, your old project requires everything and exports every single class inside it. If one of your dependency depends on other modules, your module will depend on them too. This is called “implied readability”.
What is also new, is the module-path. It is far more robust then the class path, because it is meant to look up modules, not specific types which can be anywhere in any package on the class-path. With the module-path, it is obvious at compile-time, if a module is missing or if two modules have the same name. You cannot detect these problems in the class-path before runtime.

You could also add multiple versions of a library without them conflicting. But this works only, if they are named in the correct way and are old, non-modular jar-files. This is, because each jar will be loaded into the module-path as a new module and its classes are not loaded into the same class-path. So you could use someLib-1.2.0.jar in one of your modules, while you would use someLib-2.1.0.jar in another module and these two versions of the same library would not conflict. That is no solution to the problem with different versions. Currently, there is no real standardized versioning for jigsaw-modules, but we hope, that the developers will deliver this very important feature later.

What would it look like?

Imagine this as your file-structure:

Java9Jigsaw/
│  de.oio.java9lib
│   ├── de
│   │   └── oio
│   │       └── java9lib
│   │           ├── export
│   │           │   └── SomeAPIInterface.java
│   │           │   
│   │           └── internal
│   │               └── SomeImplementation.java
│   └── module-info.java
│
│ de.oio.java9app
│   ├── de
│   │   └── oio
│   │       └── java9app 
│   │           └── Main.java
│   └── module-info.java

This would be the implementation for the library. You see, that there is a public attribute and a public method.

public class InternalImpl implements SomeAPIInterface {

	public int someValue = 5;

	@Override
	public void doStuff() {
		// do important stuff
	}
}

Then the module-info file for the lib would look like:

module de.oio.java9lib {	
	exports de.oio.java9lib.export;	
}

And the module-info file for the application:

module de.oio.java9app {	
	requires de.oio.java9lib;
}

Now let’s see, what we can do in the Main.class:

import (...)

public class Main {
	public static void main(String... args) {
		/* working as expected */
		SomeAPIInterface interf;

		/* not working */
		InternalImpl impl = new InternalImpl();

		/* also not working */
		int value = impl.someValue;
	}
}

The class SomeAPIInterface is inside the de.oio.java9lib.export-package which is exported by the java9lib-module. But the InternalImpl-class is not part of that package, so line 9 would not compile. The same goes for line 12 (which would not compile anyway because of the error in line 9). You are simply not allowed to access the InternalImpl-class, or some field in it, despite the fact that the class and the field are both public.

How about OSGi?

OSGi is slightly more complex then Jigsaw, and it does not modularize the JDK, but it is commonly used by many developers. Some key differences between the two are, that Jigsaw will support modularity at compile time and supports all native libraries. But Jigsaw does not aim to replace OSGi. For example, Jigsaw does not provide dynamic services or the live-cycle-model.
By the way, it is possible to run Jigsaw AND OSGi, like in this proof of concept.

I could go into much more detail about the controversy about OSGi vs. Jigsaw, but that would go beyond the scope of this article.

Short URL for this post: http://wp.me/p4nxik-2Hy
This entry was posted in Did you know?, Java Basics, Java modularization and tagged , , , . Bookmark the permalink.

One Response to Jigsaw – Java 9

  1. Pingback: Java 9 Top Features | techscouting through the java news

Leave a Reply