Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Migrating to Java 9 Modules with ModiTect

Migrating to Java 9 Modules with ModiTect

The wait is over – Java 9 finally adds modularity to the platform. Well-defined module interfaces, small-sized runtime images containing just the modules an application needs, advantages are manyfold. How to migrate existing applications and their dependencies, though? Automatic modules help, but they don't work with modular runtime images as created by jlink.

In the first part of the session, we’ll introduce you to modular runtime images, introduced in Java 9. We'll then introduce you to ModiTect, a brand-new utility to add modularity to existing frameworks and libraries. We'll show you how ModiTect can be used to transform a classic application to a Java 9 modular runtime image by adding module configuration to existing JARs.

Gunnar Morling

March 14, 2018
Tweet

More Decks by Gunnar Morling

Other Decks in Programming

Transcript

  1. Migrating to Java 9 Modules Migrating to Java 9 Modules

    with ModiTect with ModiTect Gunnar Morling Gunnar Morling @gunnarmorling @gunnarmorling 1
  2. Agenda Agenda JPMS and the modular JDK Moving to Java

    9 Modules ModiTect Authoring module descriptors Creating modular runtime images #JavaLand #ModiTect @gunnarmorling 2
  3. Gunnar Morling Gunnar Morling Open source software engineer at Red

    Hat Debezium Hibernate Spec Lead for Bean Validation 2.0 Founder of MapStruct [email protected] @gunnarmorling http://in.relation.to/gunnar-morling/ #JavaLand #ModiTect @gunnarmorling 3
  4. JPMS and the Modular JDK JPMS and the Modular JDK

    JPMS = Modularized JDK and modules for your applications Strong encapsulation Clearly defined APIs Explicit relationships #JavaLand #ModiTect @gunnarmorling https://twitter.com/mreinhold/status/882644292036026368 4
  5. JPMS and the Modular JDK JPMS and the Modular JDK

    Why Do I Like It? Why Do I Like It? Clearly defined APIs are great for libraries Modular runtime images Validate (and fail) early #JavaLand #ModiTect @gunnarmorling 5
  6. Moving to Java 9 Modules Moving to Java 9 Modules

    3 Steps 3 Steps Consciously decide on module usage Build on Java 9 Move to automatic modules Move to named modules #JavaLand #ModiTect @gunnarmorling 7
  7. Moving to Java 9 Modules Moving to Java 9 Modules

    Step 1 - Build on Java 9 Step 1 - Build on Java 9 The class path still exists! Often works fine Be wary of Java EE dependences (JAXB, @Generated etc.) and jdk.unsupported Time for some clean-up Watch out for illegal access warnings Remove split packages Remove circular dependencies (services can help) #JavaLand #ModiTect @gunnarmorling 8
  8. Moving to Java 9 Modules Moving to Java 9 Modules

    Step 2 - Automatic Modules Step 2 - Automatic Modules Use non-modular JARs on module path Read all resolved modules and the classpath ("UNNAMED" module) Export all packages Define module name via Automatic-Module-Name manifest entry Unique "super package" is a good default choice Send patches for your dependencies :) #JavaLand #ModiTect @gunnarmorling 9
  9. Moving to Java 9 Modules Moving to Java 9 Modules

    Step 3 - Named Modules Step 3 - Named Modules Declare module-info descriptor Carefully decide on API dependences ("Do I really need java.desktop?") ModiTect helps with authoring module descriptors #JavaLand #ModiTect @gunnarmorling 10
  10. module com.example { requires java.sql; requires joda.time; requires com.google.guava; exports

    com.example.foo; exports com.example.foo.bar; exports com.example.foo.baz; uses com.acme.SomeService; provides com.acme.AnotherService with com.example.internal.MyServiceImpl; opens com.example.zap; } Moving to Java 9 Modules Moving to Java 9 Modules Anatomy of a Module Descriptor Anatomy of a Module Descriptor #JavaLand #ModiTect @gunnarmorling Derive from project dependencies? Support for patterns? 11
  11. Module Descriptors Module Descriptors Authoring with ModiTect Authoring with ModiTect

    Can create descriptors "out-of-bands" Works on Java 8 Can skip (optional) non-modularised dependences Can semi-automatically derive descriptors Based on project metadata Patterns for exports Adjust via rules as needed #JavaLand #ModiTect @gunnarmorling 13
  12. <plugin> <groupId>org.moditect</groupId> <artifactId>moditect­maven­plugin</artifactId> <executions> <execution> <id>add­module­info</id> <phase>package</phase> <configuration> <outputDirectory>${project.build.directory}/modules</outputDirectory> <module>

    <moduleInfo> <name>org.hibernate.validator</name> <requires> static jboss.logging.annotations; transitive java.validation; *; </requires> <exports> org.hibernate.validator.internal.util.logging to org.jboss.logging; !org.hibernate.validator.internal*; *; </exports> <uses> javax.validation.ConstraintValidator; javax.validation.valueextraction.ValueExtractor; </uses> </moduleInfo> </module> </configuration> <goals> <goal>add­module­info</goal> </goals> </execution> </executions> </plugin> 15
  13. Java 9 Modules Java 9 Modules Some Pitfalls Some Pitfalls

    Only one version of a given module Conflicting concealed packages Don't leak internal types in API Some APIs behave differently when called from named module, e.g. Package#getImplementationVersion() returns null ClassLoader#getResource() only works for opened packages #JavaLand #ModiTect @gunnarmorling 16
  14. Modular Runtime Images Modular Runtime Images Contain just your app

    and its dependencies JDK modules 3rd-party modules Optional launcher Created via jlink tool Require named modules Great for app deployment (e.g. desktops or Docker) #JavaLand #ModiTect @gunnarmorling my­jlink­image ├── bin │ ├── appletviewer │ ├── helloWorld │ ├── java │ └── keytool ├── conf ├── include ├── legal ├── lib │ ├── classlist │ ... │ ├── libjava.dylib │ ... │ ├── modules │ ... │ └── tzdb.dat └── release 18
  15. <plugin> <groupId>org.moditect</groupId> <artifactId>moditect­maven­plugin</artifactId> <executions> <execution> <id>create­runtime­image</id> <phase>package</phase> <goals> <goal>create­runtime­image</goal> </goals>

    <configuration> <modulePath> <path>${project.build.directory}/modules</path> </modulePath> <modules> <module>com.example</module> </modules> <launcher> <name>helloWorld</name> <module>com.example</module> </launcher> <compression>2</compression> <stripDebug>true</stripDebug> <outputDirectory>${project.build.directory}/jlink­image</outputDirectory> </configuration> </execution> </executions> </plugin> 20
  16. Modular Runtime Images and Docker Modular Runtime Images and Docker

    Instead of re-creating the whole image, leverage --upgrade-module-path Have a stable image layer with dependencies Have a very thin layer with the changing parts No more Uber JARs :) ModiTect helps to "cross-build" for other environments #JavaLand #ModiTect @gunnarmorling 21
  17. FROM centos:7 COPY maven/target/jlink­image /opt/vertx­helloworld/ COPY maven/helloWorld.sh /opt/vertx­helloworld/bin ADD entrypoint.sh

    /entrypoint.sh EXPOSE 8080 ENTRYPOINT ["/entrypoint.sh"] Docker base image with modular runtime image FROM moditect/vertx­helloworld­base COPY maven/moditect­integrationtest­vertx­1.0.0­SNAPSHOT.jar /opt/upgrade­modules/ Derived image only with the application module on the upgrade module path DIR=`dirname $0` $DIR/java ­XX:+UnlockExperimentalVMOptions \ ­XX:+UseCGroupMemoryLimitForHeap \ ­­upgrade­module­path=/opt/upgrade­modules \ ­m com.example $@ Entrypoint script for launching the runtime image with the upgraded module 23
  18. docker history moditect/vertx­helloworld IMAGE CREATED CREATED BY SIZE COMMENT 6c65bcd7502b

    12 seconds ago /bin/sh ­c #(nop) COPY file:80e4cc103663b29d… 6.66kB f9ef9b586ce3 About a minute ago /bin/sh ­c #(nop) ENTRYPOINT ["/entrypoint.… 0B e8fbd78c372b About a minute ago /bin/sh ­c #(nop) EXPOSE 8080 0B e0a2ecf61d91 About a minute ago /bin/sh ­c #(nop) ADD file:533538b625baa8b9e… 671B 54e48e3d809d About a minute ago /bin/sh ­c #(nop) COPY file:1cd6b0aa65642128… 788B f759b95b9eed About a minute ago /bin/sh ­c #(nop) COPY dir:9b8ade3775c4b0b0a… 52.1MB 2d194b392dd1 9 days ago /bin/sh ­c #(nop) CMD ["/bin/bash"] 0B <missing> 9 days ago /bin/sh ­c #(nop) LABEL name=CentOS Base Im… 0B <missing> 9 days ago /bin/sh ­c #(nop) ADD file:8d83f3e2c14f39e7f… 195MB Only derived image must be re-built and distributed after app changes 24
  19. ModiTect ModiTect Summary and Outlook Summary and Outlook Consider JPMS

    to modularise your application Assisted definition of module descriptors and runtime images Automation where possible, while keeping full control org.moditect:moditect-maven-plugin:1.0.0.Alpha2 on Maven Central Next steps Move descriptor generation to "generate-sources" phase Gradle plug-in #JavaLand #ModiTect @gunnarmorling 25
  20. Resources Resources Source code Docs Vert.x Example Contributions welcome! @gunnarmorling

    github.com/moditect/moditect/ github.com/moditect/moditect/wiki github.com/moditect/moditect/tree/ master/integrationtest/vert.x #JavaLand #ModiTect @gunnarmorling 26