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

Refactoring your code to Java 9 modules

Refactoring your code to Java 9 modules

JPoint Moscow

363cf27411356afc37199a73bb58bcfe?s=128

Rabea Gransberger

April 06, 2018
Tweet

Transcript

  1. Refactoring your code to Java 9 modules Rabea Gransberger (MEKO-S

    GmbH) @rgransberger
  2. Рабеа Грансбергер Rabea Gransberger • Computer Science Diploma 2008 •

    Java Developer, Project Lead at MEKOS, Germany • Organization Team JUG Bremen, JCrete, JAlba 06.04.2018 2 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger) By Karte: NordNordWest, Lizenz: Creative Commons by-sa-3.0 de, CC BY-SA 3.0 de, https://commons.wikimedia.org/w/index.php?curid=35392837
  3. 06.04.2018 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)

    3 102: Process API Updates 110: HTTP 2 Client 143: Improve Contended Locking 158: Unified JVM Logging 165: Compiler Control 193: Variable Handles 197: Segmented Code Cache 199: Smart Java Compilation, Phase Two 200: The Modular JDK 201: Modular Source Code 211: Elide Deprecation Warnings on Import Statements 212: Resolve Lint and Doclint Warnings 213: Milling Project Coin 214: Remove GC Combinations Deprecated in JDK 8 215: Tiered Attribution for javac 216: Process Import Statements Correctly 217: Annotations Pipeline 2.0 219: Datagram Transport Layer Security (DTLS) 220: Modular Run-Time Images 221: Simplified Doclet API 222: jshell: The Java Shell (Read-Eval-Print Loop) 223: New Version-String Scheme 224: HTML5 Javadoc 225: Javadoc Search 226: UTF-8 Property Files 227: Unicode 7.0 228: Add More Diagnostic Commands 229: Create PKCS12 Keystores by Default 231: Remove Launch-Time JRE Version Selection 232: Improve Secure Application Performance 233: Generate Run-Time Compiler Tests Automatically 235: Test Class-File Attributes Generated by javac 236: Parser API for Nashorn 237: Linux/AArch64 Port 238: Multi-Release JAR Files 240: Remove the JVM TI hprof Agent 241: Remove the jhat Tool 243: Java-Level JVM Compiler Interface 244: TLS Application-Layer Protocol Negotiation Extension 245: Validate JVM Command-Line Flag Arguments 246: Leverage CPU Instructions for GHASH and RSA 247: Compile for Older Platform Versions 248: Make G1 the Default Garbage Collector 249: OCSP Stapling for TLS 250: Store Interned Strings in CDS Archives 251: Multi-Resolution Images 252: Use CLDR Locale Data by Default 253: Prepare JavaFX UI Controls & CSS APIs for Modularization 254: Compact Strings 255: Merge Selected Xerces 2.11.0 Updates into JAXP 256: BeanInfo Annotations 257: Update JavaFX/Media to Newer Version of GStreamer 258: HarfBuzz Font-Layout Engine 259: Stack-Walking API 260: Encapsulate Most Internal APIs 261: Module System 262: TIFF Image I/O 263: HiDPI Graphics on Windows and Linux 264: Platform Logging API and Service 265: Marlin Graphics Renderer 265: Marlin Graphics Renderer 266: More Concurrency Updates 267: Unicode 8.0 268: XML Catalogs 269: Convenience Factory Methods for Collections 270: Reserved Stack Areas for Critical Sections 271: Unified GC Logging 272: Platform-Specific Desktop Features 273: DRBG-Based SecureRandom Implementations 274: Enhanced Method Handles 275: Modular Java Application Packaging 276: Dynamic Linking of Language-Defined Object Models 277: Enhanced Deprecation 278: Additional Tests for Humongous Objects in G1 279: Improve Test-Failure Troubleshooting 280: Indify String Concatenation 281: HotSpot C++ Unit-Test Framework 282: jlink: The Java Linker 283: Enable GTK 3 on Linux 284: New HotSpot Build System 285: Spin-Wait Hints 287: SHA-3 Hash Algorithms 288: Disable SHA-1 Certificates 289: Deprecate the Applet API 290: Filter Incoming Serialization Data 292: Implement Selected ECMAScript 6 Features in Nashorn 294: Linux/s390x Port 295: Ahead-of-Time Compilation 297: Unified arm32/arm64 Port 298: Remove Demos and Samples 261: Module System 282: jlink: The Java Linker
  4. 06.04.2018 4 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger)
  5. 06.04.2018 5 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger) Carola Lilienthal: It's all about the domain, honey!
  6. 06.04.2018 6 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger)
  7. 06.04.2018 7 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger) https://c2.staticflickr.com/4/3206 /2348940045_40482b7109_b.jpg
  8. Software Design customer.service invoice.service picture.service camera.service 06.04.2018 8 JPoint Moscow

    / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  9. Modules customer.service invoice.service picture.service camera.service 06.04.2018 9 JPoint Moscow /

    Java 9 Refactoring (Rabea Gransberger @rgransberger)
  10. Modules • Low coupling • "There is a limit to

    how many things a person can think about a once."* • => Chunking • High cohesion • "Incoherent fragments are hard to understands as an undifferentiated soup."* Chunking Example: 06042018 (8 digits, chunking limit 7) *Domain Driven Design, Eric Evans 06.04.2018 10 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  11. Modules • Low coupling • "There is a limit to

    how many things a person can think about a once."* • => Chunking • High cohesion • "Incoherent fragments are hard to understands as an undifferentiated soup."* Chunking Example: 06 04 2018 (3 groups, chunking limit 7) *Domain Driven Design, Eric Evans 06.04.2018 11 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  12. Java 8 Code • In Packages • In JARs •

    Classloader ignores JARs: No Dependency Graph • Linear Scan • More than one version of a class? 06.04.2018 12 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  13. OTIS • 155.159 LOC • 42.528 Classes • 3884 Packages

    • 285 Plugins (aka Modules) 06.04.2018 13 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  14. At the Vet 06.04.2018 14 JPoint Moscow / Java 9

    Refactoring (Rabea Gransberger @rgransberger) Java 8 JavaFX Sample Application
  15. 06.04.2018 15 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger)
  16. Entities 06.04.2018 16 JPoint Moscow / Java 9 Refactoring (Rabea

    Gransberger @rgransberger) Customer Pet Visit Invoice
  17. 06.04.2018 17 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger)
  18. External Dependencies • Commons Lang 3: ToStringBuilder 06.04.2018 18 JPoint

    Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  19. My friend … 06.04.2018 19 JPoint Moscow / Java 9

    Refactoring (Rabea Gransberger @rgransberger)
  20. 06.04.2018 20 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger) Work Items Cars Brand Repair Car Repair
  21. Vet Entities 06.04.2018 21 JPoint Moscow / Java 9 Refactoring

    (Rabea Gransberger @rgransberger) Customer Pet Visit Invoice
  22. Car Repair Entities 06.04.2018 22 JPoint Moscow / Java 9

    Refactoring (Rabea Gransberger @rgransberger) Customer Pet Visit Invoice Car
  23. Identifiy Modules • Parts without cyclic dependencies • Reminder: JARs

    can have cycles • Tools • Structure 101 • Sonargraph • UML • jQAssistant • DTangler (https://github.com/jimbethancourt/dtangler) • Degraph 06.04.2018 23 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger) customer.service invoice.service
  24. Domain Driven Design 06.04.2018 24 JPoint Moscow / Java 9

    Refactoring (Rabea Gransberger @rgransberger) If we had applied DDD for the example… … it would be easy to split code along: • Bounded Contexts • and maybe Aggregates • DDD Modules not same as Bounded Contexts • think packages / namespaces • Part III tells you more about refactoring to DDD See also: http://dddcommunity.org
  25. 06.04.2018 25 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger) DTangler
  26. DTangler 06.04.2018 26 JPoint Moscow / Java 9 Refactoring (Rabea

    Gransberger @rgransberger)
  27. Degraph 06.04.2018 27 JPoint Moscow / Java 9 Refactoring (Rabea

    Gransberger @rgransberger)
  28. 06.04.2018 28 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger)
  29. 06.04.2018 29 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger)
  30. 06.04.2018 30 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger)
  31. Domain Layers 06.04.2018 31 JPoint Moscow / Java 9 Refactoring

    (Rabea Gransberger @rgransberger) Customer Pet Visit Invoice
  32. Technical Layers 06.04.2018 32 JPoint Moscow / Java 9 Refactoring

    (Rabea Gransberger @rgransberger) Customer Pet Visit Invoice DB Model UI
  33. 1. Refactoring: Technical Layers 06.04.2018 33 JPoint Moscow / Java

    9 Refactoring (Rabea Gransberger @rgransberger) customer customer. model customer. db customer. ui
  34. Technical Layers 06.04.2018 34 JPoint Moscow / Java 9 Refactoring

    (Rabea Gransberger @rgransberger) Customer Pet Visit Invoice DB Model UI
  35. 2. Analysis 06.04.2018 35 JPoint Moscow / Java 9 Refactoring

    (Rabea Gransberger @rgransberger)
  36. 06.04.2018 36 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger)
  37. Java 9 06.04.2018 JPoint Moscow / Java 9 Refactoring (Rabea

    Gransberger @rgransberger) 37
  38. Java 9 Platform Module System (JPMS) JSR 376: 25. Nov

    2014 => Released 21.09.2017 • Reliable configuration: Replace Classpath (-Hell) • Strong encapsulation: public != Public • Scalable Java SE Platform (JEP 200: Modular JDK) • Greater platform integrity: illegal-access for internal API • Improved performance: No linear scans 06.04.2018 38 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  39. Java 9 Module Definition src\module-info.java module <reverse.dns.name>{ requires <Module>; exports

    <package>; uses <Service>; provides <Service> with <Impl>; } 06.04.2018 39 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  40. Module 06.04.2018 40 JPoint Moscow / Java 9 Refactoring (Rabea

    Gransberger @rgransberger) model ui db util requires module model { exports db; } module ui { requires model; exports table; } table CustomerTable Customer getCustomer()
  41. 06.04.2018 41 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger) model ui db util table requires module model { exports db; } module ui { requires model; exports table; } Module
  42. 06.04.2018 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)

    42 Customer Pet Visit Invoice Car
  43. New Modules 06.04.2018 43 JPoint Moscow / Java 9 Refactoring

    (Rabea Gransberger @rgransberger) model customer.model visit.model invoice.model ui customer.ui visit.ui invoice.ui pet pet.model pet.db pet.ui vet ui
  44. 2. Refactoring: Create Modules 06.04.2018 44 JPoint Moscow / Java

    9 Refactoring (Rabea Gransberger @rgransberger) • Warning: No Split-Packages allowed model customer ui customer
  45. Demo 06.04.2018 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger) 45
  46. External Dependencies Example: Commons Lang 3 (commons-lang3-3.7.jar) • Check for

    Automatic-Module-Name in JAR • META-INF/MANIFEST.MF • Automatic-Module-Name: org.apache.commons.lang3 • => requires org.apache.commons.lang3; • Otherwise use file name as module name • requires commons-lang3; 06.04.2018 46 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  47. 06.04.2018 47 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger)
  48. CustomerView private Node createTabPane() { TabPane tabPane = new TabPane();

    tabPane.getTabs().add(createTab("Pets", createPetNode())); tabPane.getTabs().add(createTab("Invoices", createInvoiceNode())); return tabPane; } private Node createPetNode() { List<Pet> pets = new PetDao().fetchPetsForCustomer(customer.getId()); PetTable table = new PetTable(pets, false) { protected void onDoubleClick(Pet pet) { replace(new PetView(customer, pet)); } }; return table; } 06.04.2018 48 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  49. 3. Refactoring: Resolve Dependencies 06.04.2018 49 JPoint Moscow / Java

    9 Refactoring (Rabea Gransberger @rgransberger) ui CustomerView TabService List<Tab> createTabs() pet PetTabService List<Tab> createTabs() PetTable module ui { exports service; uses CustomerViewTabService; } module pet { requires ui; provides CustomerViewTabService with PetCustomerViewTabService; } Service Loader
  50. Demo 06.04.2018 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger) 50
  51. 4. Refactoring: Car Repair Shop • de.rgra.car replaces de.rgra.pet •

    de.rgra.vet.ui transformed to de.rgra.app • New Service: ApplicationConfigurationProvider • New: de.rgra.vet.app and de.rgra.car.app • Implements ApplicationConfigurationProvider 06.04.2018 51 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  52. Demo 06.04.2018 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger) 52
  53. 06.04.2018 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)

    53
  54. Jigsaw Dependency Visualizer 06.04.2018 54 JPoint Moscow / Java 9

    Refactoring (Rabea Gransberger @rgransberger)
  55. Deployment 06.04.2018 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger) 55
  56. Compile • Every module to its own folder/jar %JAVA_9%\javac --module-path

    mods --module-source-path "./*/src" -d classes -Xlint:exports @sources.txt %JAVA_9%\jar --create --file mlib/vet/de.rgra.model.jar -C mods/vet/de.rgra.model_05 . 06.04.2018 56 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  57. Compile • dir /s /B *.java | find "." >

    sources.txt • %JAVA_9%\javac -p mods --module-source-path "./*/src" -d classes @sources.txt • xcopy /s/Y "de.rgra.model_05/resources" "classes/de.rgra.model_05" • %JAVA_9%\jar --create --file mlib/vet/de.rgra.model.jar -C classes/de.rgra.model_05 . 06.04.2018 57 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  58. Run • %JAVA_9%\java -p mods/vet -m de.rgra.vet.app_05/de.rgra.vet.VetAppConfiguration 06.04.2018 58 JPoint

    Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  59. JLink • Java binaries and modules in one package %JAVA_9%/jlink

    --module-path %JAVA_9%\jmods;mlib;mlib/vet --add-modules de.rgra.vet.app_05 --output vetapp --launcher vet=de.rgra.vet.app_05/de.rgra.vet.VetAppConfiguration run vetapp/bin/vet.bat 06.04.2018 59 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  60. Maven + Gradle Build with Maven >= 3.5 und Gradle

    >= 4.2 https://github.com/rgra/java9-module-refactoring/tree/master/de.rgra.vet_05 06.04.2018 60 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  61. Summary 06.04.2018 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger) 61
  62. 06.04.2018 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)

    62
  63. JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger) 06.04.2018

    63
  64. Refactoring Steps • Package Structure: <domain>.<product>.<deployable> .<businesslayer> .<technicallayer>.<subpackage> • Domain

    Driven Design / Design Patterns 1. Analyse dependencies 2. Identifiy / Create Modules 3. Move Code to new modules 4. Resolve Dependencies with Interfaces / Services a) Duplicate code if you can't find a quick solution 5. Go to 1. 06.04.2018 64 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  65. 06.04.2018 65 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger

    @rgransberger) https://i.ytimg.com/vi/RijScDMVQzQ/maxresdefault.jpg "The only thing a big bang rewrite guarantees is a Big Bang!" (M. Fowler)
  66. OTIS - Experience • New module created only on business

    need • new customer • new service provider • From monolith to 283 plugins in 5 years • Module boundaries • Refactoring usually easy by using new interfaces 06.04.2018 66 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  67. Tipp • Don't: Split up monolith completely into modules •

    A lot of work • Hard to test • No benefit in use • Better: Identifiy modules when needed Like in our example to replace pet with card • "The only thing a big bang rewrite guarantees is a Big Bang!" (M. Fowler) 06.04.2018 67 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  68. Advantages: Modules vs. Monolith 06.04.2018 68 JPoint Moscow / Java

    9 Refactoring (Rabea Gransberger @rgransberger)
  69. Advantages: Modular Monolith vs. Monolith • Architecture reflected in modules

    with clear boundaries • Chunking • Hide public classes • Replace single modules • Module Path more robust than Classpath • Tool Support: Which Dependencies are missing? • Smaller deployable units • Better (Startup-) Performance 06.04.2018 69 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  70. Related Talks tomorrow • 12:15 From monolith to microservices (Nikolay

    Archakov) • 14:00 Designing for modularity with Java modules (Sander Mak) • 15:45 A​ ​craftsman’s​ ​guide​ ​to​ ​a​ ​clean architecture (Marcus Biel) 06.04.2018 70 JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger)
  71. Slides & Code: https://rgra.github.io Twitter: @rgransberger (DM open) 06.04.2018 71

    JPoint Moscow / Java 9 Refactoring (Rabea Gransberger @rgransberger) June 2018 September 2017