To JAR Hell And Back

A Life Migration To Java 9

Public Service Announcements

Java Module System

Delaying Java since 2008!

JAR Hell is bad, mkay?

JARs have:

  • no name the JVM cares about

  • no explicit dependencies

  • no well-defined API

  • no concept of versions


Modules are like JARs but have:

  • proper names

  • explicit dependencies

  • a well-defined API

  • no concept of versions

Important goals:

  • reliable configuration

  • strong encapsulation

Module Descriptor

A file

module java.sql {
	requires transitive java.logging
	requires transitive java.xml
	uses java.sql.Driver
	exports java.sql
	exports javax.sql
	exports javax.transaction.xa

Reliable Configuration

module java.sql {
	requires transitive java.logging
	requires transitive java.xml

Module system enforces:

  • all required modules are present

  • no ambiguity

  • no static dependency cycles

  • no split packages

Strong Encapsulation

module java.sql {
	exports java.sql
	exports javax.sql
	exports javax.transaction.xa

Say you want to access java.sql.ResultSet.

Module system only grants access if:

  • ResultSet is public

  • java.sql is exported by java.sql

  • your module reads java.sql

Other Features

  • decoupling via services

  • finer grained dependencies and exports

  • open packages and modules (for reflection)

  • unnamed and automatic modules (for migration)

  • layers (for containers)

  • jlink to create runtime images

Of Modules And JARs

Modularized JDK and legacy JARs have to cooperate.

Two requirements:

  • for the module system to work,
    everything needs to be a module

  • for compatibility, the class path
    and regular JARs have to keep working

The Unnamed Module

The Unnamed Module
contains all JARs on the class path
(including modular JARs).

  • has no name (surprise!)

  • can read all modules

  • exports all packages

Inside the unnamed module
"the chaos of the class path" lives on.

Migration Challenges

What to look out for
when running on JDK 9

Break Stuff

Some internal changes break existing code!

Just by running on JDK 9
(even without modularizing the application).

Internal APIs

  • internal APIs are:

    • all in sun.*

    • most in com.sun.*
      (unless marked @jdk.Exported)

  • encapsulated at compile time

  • accessible at run time
    for some time

  • critical APIs may survive longer
    (e.g. sun.misc.Unsafe)

What to look for?

JDeps can report internal dependencies:

$ jdeps --jdk-internals
	-recursive --class-path 'libs/*'

> batik-codec.jar -> JDK removed internal API
>     JPEGImageWriter -> JPEGCodec
> guava-18.0.jar -> jdk.unsupported
>     Striped64 -> Unsafe
> scaffold-hunter-2.6.3.jar -> java.desktop
>     SteppedComboBox -> WindowsComboBoxUI

What else to look for?

  • look for reflection, especially

    • Class::forName

    • AccessibleObject::setAccessible

  • recursively check your dependencies!

What to do?

  1. fix your code

  2. contact library developers

  3. look for alternatives
    (in the JDK or other libraries)

  4. consider command line flags
    --add-exports, --add-opens, or

Split Packages

  • packages should have a unique origin

  • no module must read the same package
    from two modules

The implementation is even stricter:

  • no two modules must contain
    the same package (exported or not)

  • split packages on class path
    are inaccessible


  • some libraries split java.xml.*, e.g. xml-apis

  • some JBoss modules split, e.g.,

  • jsr305 splits javax.annotation

What to look for?

JDeps reports split packages:

$ jdeps -summary
	-recursive --class-path 'libs/*'

> split package: javax.annotation
>     [jrt:/,
>         libs/jsr305-3.0.2.jar]

What to do?

Your artifacts:

  1. rename one of the packages

  2. merge package into the same artifact

  3. merge the artifacts

  4. place both artifacts on the class path


  1. upgrade the JDK module with the artifact

  2. --patch-module with the artifact’s content

Java EE Modules

  • java.activation (javax.activation)

  • java.corba (CORBA packages)

  • java.transaction (javax.transaction)

  • java.xml.bind (javax.xml.bind.*)

  • (JAX-WS packages)

  • (javax.annotation)

These are

  • deprecated for removal

  • not resolved by default

What to look for?

JDeps shows dependencies on platform modules:

$ jdeps -summary sh-2.6.3.jar

> sh-2.6.3.jar -> java.base
> sh-2.6.3.jar -> java.datatransfer
> sh-2.6.3.jar -> java.desktop
> sh-2.6.3.jar -> java.logging
> sh-2.6.3.jar -> java.prefs
> sh-2.6.3.jar -> java.sql
> sh-2.6.3.jar -> java.xml

What to do?

  • pick a third-party implementation

  • add Java EE platform modules
    with --add-modules

Run-Time Images

  • new JDK/JRE layout

  • internal JARs are gone (e.g. rt.jar, tools.jar)

  • JARs are now JMODs

  • application class loader is no URLClassLoader
    (no way to append to its class path)

  • new URL schema for run-time image content

What to look for?

  • does the code rummage around
    in the JDK / JRE folder?

  • are URLs to JDK classes / resources handcrafted?

  • search for casts to URLClassLoader


  • Compact Profiles

  • Extension Mechanism

  • Endorsed Standards Override Mechanism

  • Boot Class Path Override

  • JRE version selection with -version:N

But wait, there’s more!

Yes, yes, there’s more:

Java 9 Migration Guide


And there are new version strings:

  • goodbye 1.9.0_31, hello 9.1.4
    (soon 18.3?)

General Advice I

The most relevant for most applications:

  • internal APIs

  • split packages

  • Java EE modules

General Advice II

  • get your code in shape
    (and prevent relapses)

  • check your dependencies and tools

  • if any are suspicious
    (automatically true for IDEs, build tools):

    • make sure they’re alive

    • get them up to date!

    • or look for alternatives

  • download Java 9 and try it!

Full Picture

If you want more details:

Java 9 Migration Guide


For the the full picture get my book:

The Java 9 Module System

About Nicolai Parlog

37% off with
code fccparlog

Want More?

⇜ Get my book!

You can hire me:

  • training (Java 8/9, JUnit 5)

  • consulting (Java 8/9)

Image Credits