Migrating to Java 9 Modules
-
Upload
sander-mak-sandermak -
Category
Software
-
view
645 -
download
5
Transcript of Migrating to Java 9 Modules
Migrating to Java 9
Let's try it!
java -cp .. -jar myapp.jar
java -cp .. -jar myapp.jar
Java 8
Java 9
Missing platform modules
error: package javax.xml.bind does not exist
import javax.xml.bind.DatatypeConverter;
public class Main {
public static void main(String... args) { DatatypeConverter.parseBase64Binary("SGVsbG8gd29ybGQh"); } }
‣ Classpath compile-time “java.se” module is used
‣ This does not resolve: java.activationjava.corbajava.transactionjava.xml.bindjava.xml.wsjava.xml.ws.annotation
Missing platform modules
Add unresolved platform modulesjdeps demo/Main.class
Main.class -> java.base Main.class -> not found <unnamed> -> java.lang java.base <unnamed> -> javax.xml.bind not found
Find
javac --add-modules java.xml.bind demo/Main.java
Add unresolved platform modulesjdeps demo/Main.class
Main.class -> java.base Main.class -> not found <unnamed> -> java.lang java.base <unnamed> -> javax.xml.bind not found
Find
Fix
javac --add-modules java.xml.bind demo/Main.java
Add unresolved platform modules
java --add-modules java.xml.bind demo/Main.java
jdeps demo/Main.class
Main.class -> java.base Main.class -> not found <unnamed> -> java.lang java.base <unnamed> -> javax.xml.bind not found
Find
Fix
javac --add-modules java.xml.bind demo/Main.java
Add unresolved platform modules
java --add-modules java.xml.bind demo/Main.java
Let's try it!
public class Main {
public static void main(String... args) throws Exception { sun.security.x509.X500Name name = new sun.security.x509.X500Name("CN=user"); } }
Using encapsulated APIs
public class Main {
public static void main(String... args) throws Exception { sun.security.x509.X500Name name = new sun.security.x509.X500Name("CN=user"); } }
Using encapsulated APIs
Main.java:4: error: package sun.security.x509 does not exist
sun.security.x509.X500Name name = ^
jdeps -jdkinternals Main.class Main.class -> java.base Main -> sun.security.x509.X500Name JDK internal API (java.base)
JDK Internal API Suggested Replacement ---------------- --------------------- sun.security.x509.X500Name Use javax.security.auth.x500.X500Principal @since 1.4
Use jdeps to find problems
Using encapsulated APIs
Exception in thread "main" java.lang.IllegalAccessError: class Main (in unnamed module @0x4cdbe50f) cannot access class sun.security.x509.X500Name (in module java.base) because module java.base does not export sun.security.x509 to unnamed module @0x4cdbe50f at Main.main(Main.java:4)
Compile with 1.8, run with 9:
Using encapsulated APIs
java --add-exports java.base/sun.security.x509=ALL-UNNAMED Main
Exception in thread "main" java.lang.IllegalAccessError: class Main (in unnamed module @0x4cdbe50f) cannot access class sun.security.x509.X500Name (in module java.base) because module java.base does not export sun.security.x509 to unnamed module @0x4cdbe50f at Main.main(Main.java:4)
Compile with 1.8, run with 9:
Using encapsulated APIs
Exception in thread "main" java.lang.IllegalAccessError: class Main (in unnamed module @0x4cdbe50f) cannot access class sun.security.x509.X500Name (in module java.base) because module java.base does not export sun.security.x509 to unnamed module @0x4cdbe50f at Main.main(Main.java:4)
Compile with 1.8, run with 9:
java --permit-illegal-access Main
New 'kill-switch':
package com.javamodularity.demonstrator;
import org.apache.commons.lang3.StringUtils;
public class Demo {
public static void main(String args[]) { String output = StringUtils.leftPad("Leftpad FTW!", 20); System.out.println(output); } }
Classic classpath
package com.javamodularity.demonstrator;
import org.apache.commons.lang3.StringUtils;
public class Demo {
public static void main(String args[]) { String output = StringUtils.leftPad("Leftpad FTW!", 20); System.out.println(output); } }
Classic classpath
javac -cp lib/commons-lang3-3.4.jar -d out $(find src -name '*.java')
java -cp out:lib/commons-lang3-3.4.jar com.javamodularity.demonstrator.Demo
Compile
Run
Top down migrationcommons.lang3.3.4.jar
demonstrator.jar
classpath
java.base module path
Can’t reference the classpath from named modules!
Top down migration
demonstrator.jar
classpath
java.base module path
commons.lang
But this isn’t our code!
Automatic Modules‣ A plain JAR on the module path becomes an
Automatic Module
‣ Module name derived from JAR name ‣ Exports everything ‣ Reads all other modules
module demonstrator { requires commons.lang; }
Using Automatic Modules
javac --module-path lib --module-source-path src -d mods $(find src -name '*.java')
java --module-path mods:lib -m demonstrator/com.javamodularity.demonstrator.Demo
Compile
Run
Migrating the books app
1. Create a “monolith module” 2. Declare exports 3. Figure out “requires” 4. Move some libs to Automatic Modules
Step 2
commons.pool
spring.context
classpath
Application code
module path
spring.tx
hibernate.core hibernate.jpa
javax.inject
Automatic modules Named modules
commons.logging
spring.beans spring.aop
spring.core
hsqldb
spring.orm
…
commons.pool
spring.context
classpath
Application code
module path
spring.tx
hibernate.core
hibernate.jpa
javax.inject
Automatic modules Named modules
commons.logging
spring.beans spring.aop
spring.core
hsqldb
spring.orm
…
Open Modules‣ Reliable configuration like normal modules ‣ Requires for every dependency ‣ Opens all packages for deep reflection
‣ Easy compatibility with existing code and frameworks ‣ Allows reflection
Open Packages
Opens the package for deep reflection, but not compile time access
A package can be both open and exported
Migrating the books app
1. Split monolith module 2. Move requires/exports 3. (optional) Move config files
Step 3
commons.pool
spring.context
classpath
Application code
module path
spring.tx
hibernate.core
hibernate.jpa
javax.inject
Automatic modules Named modules
commons.logging
spring.beans spring.aop
spring.core
hsqldb
spring.orm
…
commons.pool
spring.context
classpath
module path
spring.tx
hibernate.core
hibernate.jpa
javax.inject
Automatic modules Named modules
commons.logging
spring.beans spring.aop
spring.core
hsqldb
spring.orm
…
main books.api
books.impl
bookstore
Migration steps - recap
‣ Migrate to Java 9 using classpath only‣ Create a module around your whole app
Migration steps - recap
‣ Migrate to Java 9 using classpath only‣ Create a module around your whole app‣ Modularize your application!