Some notes on Java 9

Jigsaw

The part of Java 9 that deals with a new phenomenon called modules falls under the sobriquet, Jigsaw.

Because it's imminent (September, 2017), I followed Trisha Gee's presentation on Java 9. There are implications to this for work I'm doing presently. In particular, the disappearance of classpath. Trish bemoans this a little. Some technologies I use, such as NiFi and Cassandra, make use of classpath. So this interests me.

Project structure

Projects don't merely "pour over" into Java 9 from older versions. There's work to do. For one thing, module definition can no longer be willy-nilly.

Structure modules as separate IntelliJ submodules (or Eclipse projects/subprojects) with one package and module-info.java. E.g.: project sense-nine. I wonder what Eclipse is doing about this. Eclipse doesn't handle the concept of submodules or subprojects at all. Maybe this will have to change. Anyway, what me care?

sense-nine
 ├─ .idea
 ├─ com.mechanitis.demo.sense.client
 │   ├─ src
 │   │   ├─ com
 │   │   │   └ mechanitis
 │   │   │      └ demo
 │   │   │         └ sense
 │   │   │            └ client
 │   │   │               └ Java source files...
 │   │   └─ module-info.java
 │   └─ test
 │       └ com
 │          └ mechanitis
 │             └ demo
 │                └ sense
 │                   └ client
 │                      └ Java test files...
 └─ com.mechanitis.demo.sense.flow
     ├─ src
     │   ├─ com
     │   │   └ mechanitis
     │   │      └ demo
     │   │         └ sense
     │   │            └ flow
     │   │               └ Java source files...
     │   │                  └ impl
     │   │                     └ Java source files (classes will be publicly invisible, see below)...
     │   └─ module-info.java
     └─ testcommechanitisdemosenseflow
                        └ Java test files...
  etc.

Note that Gradle can't handle this (as of Trish's presentation), but Maven can. Still, I'm not sure how eager I am right now to create such projects in IntelliJ since they do defy traditional Maven (and ancient, traditional Java) structure. I would have welcomed it back in my Eclipse days.

The module-info.java file

module-info.java:
module com.mechanitis.demo.sense.flow
{
}

When the Java 9 compiler runs, it's no longer depending on the classpath, but on the modules you define. Now, you'll see, for instance, in the list of imports red ink for a class whose module hasn't been defined (in modules-info.java), let's say, import java.util.logging.Logger, so you Alt-click (in IntelliJ) the missing import and choose, for example, Add 'requires java.logging' statement to module-info.java, offered by the IDE. You then see in that file:

module-info.java:
module com.mechanitis.demo.sense.flow
{
  requires java.logging;
 // requires java.base; —you don't have to specify this; it's assumed!
}

So, moving a project's source to Java 9 is fraught with tedious duties. This said, those duties make you revisit your project structure (which can be tragically wrong if you publish it for consumption by other Java applications) and dependencies.

Now, there's a thing called, requires java.base, that you do not have to specify explicitly because it's just assumed. This is packages like java.util.

If you drill down through (in modules-info.java) a requirement, IntelliJ IDEA shows you the supplying JAR in External Libraries in the Project pane.

Exporting

If you want your module to export its classes for use by other modules or code, you explicitly list that in module-info.java. If you don't, it isn't exported and consuming code cannot see or use it:

module-info.java:
module com.mechanitis.demo.sense.flow
{
  requires java.logging;
  exports com.mechanitis.demo.sense.flow;
  // exports com.mechanitis.demo.sense.flow.impl; —don't export this!
}

This means that everything in the package, com.mechanitis.demo.sense.flow, will be exported from the module and available to consuming applications. To continue the example, if you want to avoid surfacing the code (and access to) of some package in your application, then you simply omit exporting it. That could be a subpackage in our example, such as we added separately a little higher up in our illustration, com.mechanitis.demo.sense.flow.impl.

There are also opens statements for module-info.java. It would appear that you can open your module to other non-base packages. Learn and use jdeps. Trish did not cover these and I can wait to figure out what they are and do. In the other reading I've done, mention has been absent.

Other interesting points...