28.3 Advanced CDS Features and Custom Class Loaders

CDS supports advanced features including custom class loaders, module-aware archives, and AOT integration for maximum performance.

Custom Class Loaders Support

// Custom Class Loader CDS Support
public class CustomClassLoaderCDS {

    public static void printCustomLoaderSupport() {
        System.out.println("=== CUSTOM CLASS LOADER SUPPORT ===");

        System.out.println("\n--- SUPPORTED LOADERS (JDK 11+) ---");

        System.out.println("\n1. Bootstrap Class Loader:");
        System.out.println("   • Loads JDK core classes (java.*)");
        System.out.println("   • Always supported");
        System.out.println("   • Default CDS archive");

        System.out.println("\n2. Platform Class Loader:");
        System.out.println("   • Loads JDK platform modules");
        System.out.println("   • java.sql, java.xml, etc.");
        System.out.println("   • Supported since JDK 11");

        System.out.println("\n3. System Class Loader:");
        System.out.println("   • Loads application classes");
        System.out.println("   • Classes from classpath");
        System.out.println("   • Supported since JDK 10");

        System.out.println("\n4. Custom Class Loaders:");
        System.out.println("   • User-defined loaders");
        System.out.println("   • Requires explicit setup");
        System.out.println("   • Supported since JDK 11");

        System.out.println("\n--- CLASS LOADER HIERARCHY ---");

        System.out.println("\n      ┌──────────────────────┐");
        System.out.println("      │ Bootstrap Loader     │");
        System.out.println("      │ (JDK core)          │");
        System.out.println("      └──────────┬───────────┘");
        System.out.println("                 │");
        System.out.println("      ┌──────────▼───────────┐");
        System.out.println("      │ Platform Loader      │");
        System.out.println("      │ (JDK modules)       │");
        System.out.println("      └──────────┬───────────┘");
        System.out.println("                 │");
        System.out.println("      ┌──────────▼───────────┐");
        System.out.println("      │ System Loader        │");
        System.out.println("      │ (Application)       │");
        System.out.println("      └──────────┬───────────┘");
        System.out.println("                 │");
        System.out.println("      ┌──────────▼───────────┐");
        System.out.println("      │ Custom Loader        │");
        System.out.println("      │ (Plugin system)     │");
        System.out.println("      └──────────────────────┘");

        System.out.println("\n--- REQUIREMENTS FOR CUSTOM LOADERS ---");

        System.out.println("\nLoader must:");
        System.out.println("  1. Be registered during dump");
        System.out.println("  2. Load classes deterministically");
        System.out.println("  3. Use same classpath at runtime");
        System.out.println("  4. Be created before archive loading");
    }

    public static void printCustomLoaderExample() {
        System.out.println("\n=== CUSTOM LOADER EXAMPLE ===");

        System.out.println("\n--- SIMPLE PLUGIN LOADER ---");

        System.out.println("\nPluginLoader.java:");
        System.out.println("  public class PluginLoader extends URLClassLoader {");
        System.out.println("      public PluginLoader(URL[] urls) {");
        System.out.println("          super(urls, ");
        System.out.println("                ClassLoader.getSystemClassLoader());");
        System.out.println("      }");
        System.out.println("      ");
        System.out.println("      public static PluginLoader create(String path) {");
        System.out.println("          try {");
        System.out.println("              URL url = new File(path).toURI().toURL();");
        System.out.println("              return new PluginLoader(new URL[]{url});");
        System.out.println("          } catch (Exception e) {");
        System.out.println("              throw new RuntimeException(e);");
        System.out.println("          }");
        System.out.println("      }");
        System.out.println("  }");

        System.out.println("\n--- CREATING ARCHIVE WITH CUSTOM LOADER ---");

        System.out.println("\nStep 1 - Class list with loader info:");
        System.out.println("  java -Xshare:off \\");
        System.out.println("       -XX:DumpLoadedClassList=classes.lst \\");
        System.out.println("       -cp app.jar:plugins/* \\");
        System.out.println("       com.example.Main");

        System.out.println("\nGenerated classes.lst includes loader info:");
        System.out.println("  # System loader");
        System.out.println("  com/example/Main");
        System.out.println("  com/example/Service");
        System.out.println("  ");
        System.out.println("  # Custom plugin loader");
        System.out.println("  @lambda-form-invoker");
        System.out.println("  com/example/plugins/Plugin1 source: plugins/plugin1.jar");
        System.out.println("  com/example/plugins/Plugin2 source: plugins/plugin2.jar");

        System.out.println("\nStep 2 - Create archive:");
        System.out.println("  java -Xshare:dump \\");
        System.out.println("       -XX:SharedClassListFile=classes.lst \\");
        System.out.println("       -XX:SharedArchiveFile=app.jsa \\");
        System.out.println("       -cp app.jar:plugins/*");

        System.out.println("\nStep 3 - Use archive:");
        System.out.println("  java -Xshare:on \\");
        System.out.println("       -XX:SharedArchiveFile=app.jsa \\");
        System.out.println("       -cp app.jar:plugins/* \\");
        System.out.println("       com.example.Main");
    }

    public static void printLoaderConstraints() {
        System.out.println("\n=== CUSTOM LOADER CONSTRAINTS ===");

        System.out.println("\n--- DETERMINISTIC LOADING ---");

        System.out.println("\n✓ Works (deterministic):");
        System.out.println("  public Class<?> loadClass(String name) {");
        System.out.println("      if (name.startsWith(\"com.plugin.\")) {");
        System.out.println("          return findClass(name);  // Always same path");
        System.out.println("      }");
        System.out.println("      return super.loadClass(name);");
        System.out.println("  }");

        System.out.println("\n✗ Doesn't work (non-deterministic):");
        System.out.println("  public Class<?> loadClass(String name) {");
        System.out.println("      if (Math.random() > 0.5) {  // Random!");
        System.out.println("          return loadFromCache(name);");
        System.out.println("      }");
        System.out.println("      return loadFromDisk(name);");
        System.out.println("  }");

        System.out.println("\n--- CLASSPATH STABILITY ---");

        System.out.println("\nArchive creation:");
        System.out.println("  -cp app.jar:plugins/v1.jar:plugins/v2.jar");

        System.out.println("\n✓ Runtime (same order):");
        System.out.println("  -cp app.jar:plugins/v1.jar:plugins/v2.jar");

        System.out.println("\n✗ Runtime (different order):");
        System.out.println("  -cp app.jar:plugins/v2.jar:plugins/v1.jar");
        System.out.println("  → CDS will be disabled");

        System.out.println("\n--- LOADER LIFECYCLE ---");

        System.out.println("\nLoader must exist before archive mapping:");
        System.out.println("  public static void main(String[] args) {");
        System.out.println("      // 1. Create custom loader FIRST");
        System.out.println("      PluginLoader loader = PluginLoader.create(\"plugins\");");
        System.out.println("      ");
        System.out.println("      // 2. JVM maps CDS archive");
        System.out.println("      // 3. Classes from archive reference loader");
        System.out.println("      ");
        System.out.println("      // 4. Use classes");
        System.out.println("      Class<?> plugin = loader.loadClass(\"Plugin\");");
        System.out.println("  }");
    }
}

Module-Aware CDS

// Module-Aware CDS
public class ModuleCDS {

    public static void printModuleCDS() {
        System.out.println("=== MODULE-AWARE CDS ===");

        System.out.println("\n--- MODULES IN CDS ---");

        System.out.println("\nDefault archive includes:");
        System.out.println("  • java.base module (always)");
        System.out.println("  • Core JDK classes");
        System.out.println("  • ~1,300 classes");

        System.out.println("\nAdditional modules:");
        System.out.println("  • java.sql");
        System.out.println("  • java.xml");
        System.out.println("  • java.logging");
        System.out.println("  • java.management");
        System.out.println("  • Your application modules");

        System.out.println("\n--- INCLUDING APPLICATION MODULES ---");

        System.out.println("\nModule structure:");
        System.out.println("  myapp/");
        System.out.println("  ├── module-info.java");
        System.out.println("  ├── com/example/Main.java");
        System.out.println("  └── com/example/Service.java");

        System.out.println("\nmodule-info.java:");
        System.out.println("  module com.example.myapp {");
        System.out.println("      requires java.base;");
        System.out.println("      requires java.sql;");
        System.out.println("      exports com.example;");
        System.out.println("  }");

        System.out.println("\n--- CREATING MODULE ARCHIVE ---");

        System.out.println("\nStep 1 - Generate class list:");
        System.out.println("  java -Xshare:off \\");
        System.out.println("       -XX:DumpLoadedClassList=classes.lst \\");
        System.out.println("       --module-path mods \\");
        System.out.println("       -m com.example.myapp/com.example.Main");

        System.out.println("\nStep 2 - Create archive:");
        System.out.println("  java -Xshare:dump \\");
        System.out.println("       -XX:SharedClassListFile=classes.lst \\");
        System.out.println("       -XX:SharedArchiveFile=myapp.jsa \\");
        System.out.println("       --module-path mods \\");
        System.out.println("       -m com.example.myapp/com.example.Main");

        System.out.println("\nStep 3 - Use archive:");
        System.out.println("  java -Xshare:on \\");
        System.out.println("       -XX:SharedArchiveFile=myapp.jsa \\");
        System.out.println("       --module-path mods \\");
        System.out.println("       -m com.example.myapp/com.example.Main");

        System.out.println("\n--- DYNAMIC MODULE CDS ---");

        System.out.println("\nSimpler with dynamic CDS:");
        System.out.println("  java -XX:ArchiveClassesAtExit=myapp.jsa \\");
        System.out.println("       --module-path mods \\");
        System.out.println("       -m com.example.myapp/com.example.Main");

        System.out.println("\n--- MODULE LAYERS ---");

        System.out.println("\nLayer 1 - JDK modules:");
        System.out.println("  Default classes.jsa");
        System.out.println("  Contains: java.base, java.sql, java.xml");

        System.out.println("\nLayer 2 - Application modules:");
        System.out.println("  myapp.jsa (layered on default)");
        System.out.println("  Contains: com.example.myapp");

        System.out.println("\nUsage:");
        System.out.println("  java -XX:SharedArchiveFile=default.jsa:myapp.jsa \\");
        System.out.println("       --module-path mods \\");
        System.out.println("       -m com.example.myapp/com.example.Main");
    }
}

CDS with AOT Compilation

// CDS and AOT Integration
public class CDSWithAOT {

    public static void printCDSAOTIntegration() {
        System.out.println("=== CDS WITH AOT COMPILATION ===");

        System.out.println("\n--- WHAT IS AOT? ---");

        System.out.println("\nAhead-of-Time Compilation:");
        System.out.println("  • Compile Java bytecode to native code");
        System.out.println("  • Before application runs");
        System.out.println("  • Skip JIT warmup");
        System.out.println("  • Instant peak performance");

        System.out.println("\n--- CDS + AOT BENEFITS ---");

        System.out.println("\nCDS provides:");
        System.out.println("  ✓ Fast class loading");
        System.out.println("  ✓ Shared metadata");
        System.out.println("  ✓ Reduced memory footprint");

        System.out.println("\nAOT provides:");
        System.out.println("  ✓ No JIT compilation delay");
        System.out.println("  ✓ Immediate peak performance");
        System.out.println("  ✓ Predictable execution");

        System.out.println("\nCombined:");
        System.out.println("  ✓ Fastest possible startup");
        System.out.println("  ✓ Instant peak performance");
        System.out.println("  ✓ Minimal memory usage");
        System.out.println("  ✓ Perfect for short-lived processes");

        System.out.println("\n--- USING GRAALVM NATIVE IMAGE ---");

        System.out.println("\nGraalVM Native Image:");
        System.out.println("  • Compile entire app to native executable");
        System.out.println("  • Includes AOT and CDS-like features");
        System.out.println("  • Startup: <50ms");
        System.out.println("  • Memory: <50MB RSS");

        System.out.println("\nBuild native image:");
        System.out.println("  native-image \\");
        System.out.println("    -cp app.jar:lib/* \\");
        System.out.println("    --no-fallback \\");
        System.out.println("    -H:+ReportExceptionStackTraces \\");
        System.out.println("    com.example.Main");

        System.out.println("\nResult:");
        System.out.println("  • Standalone executable");
        System.out.println("  • No JVM required");
        System.out.println("  • CDS metadata embedded");
        System.out.println("  • All code AOT compiled");

        System.out.println("\n--- PROJECT LEYDEN (FUTURE) ---");

        System.out.println("\nOpenJDK Project Leyden goals:");
        System.out.println("  • Tight CDS + AOT integration");
        System.out.println("  • Profile-guided optimizations");
        System.out.println("  • Cached JIT compilations");
        System.out.println("  • Sub-50ms startup");

        System.out.println("\nPlanned features:");
        System.out.println("  • Pre-compiled method cache");
        System.out.println("  • Closed-world optimizations");
        System.out.println("  • Eliminated runtime overhead");
        System.out.println("  • Expected: JDK 23-25");
    }
}

Advanced Configuration

// Advanced CDS Configuration
public class AdvancedCDSConfig {

    public static void printAdvancedOptions() {
        System.out.println("=== ADVANCED CDS OPTIONS ===");

        System.out.println("\n--- ARCHIVE SIZE TUNING ---");

        System.out.println("\nDefault sizes:");
        System.out.println("  -XX:SharedBaseAddress=0x800000000");
        System.out.println("  -XX:SharedReadOnlySize=16M");
        System.out.println("  -XX:SharedReadWriteSize=16M");
        System.out.println("  -XX:SharedMiscDataSize=4M");

        System.out.println("\nFor large applications:");
        System.out.println("  java -Xshare:dump \\");
        System.out.println("       -XX:SharedReadOnlySize=32M \\");
        System.out.println("       -XX:SharedReadWriteSize=32M \\");
        System.out.println("       -XX:SharedMiscDataSize=8M \\");
        System.out.println("       -XX:SharedClassListFile=classes.lst \\");
        System.out.println("       -XX:SharedArchiveFile=app.jsa \\");
        System.out.println("       -cp app.jar:lib/*");

        System.out.println("\n--- COMPRESSED OOP SETTINGS ---");

        System.out.println("\nWith compressed oops (default, heap <32GB):");
        System.out.println("  java -XX:+UseCompressedOops \\");
        System.out.println("       -XX:SharedArchiveFile=app-coop.jsa \\");
        System.out.println("       -jar app.jar");

        System.out.println("\nWithout compressed oops (heap >32GB):");
        System.out.println("  java -XX:-UseCompressedOops \\");
        System.out.println("       -XX:SharedArchiveFile=app-nocoop.jsa \\");
        System.out.println("       -jar app.jar");

        System.out.println("\nNote: Archive must match oop setting!");

        System.out.println("\n--- VERIFICATION LEVELS ---");

        System.out.println("\nNo verification (fastest):");
        System.out.println("  java -Xverify:none \\");
        System.out.println("       -XX:SharedArchiveFile=app.jsa \\");
        System.out.println("       -jar app.jar");
        System.out.println("  ⚠ Use only for trusted code");

        System.out.println("\nRemote verification (default):");
        System.out.println("  java -Xverify:remote \\");
        System.out.println("       -XX:SharedArchiveFile=app.jsa \\");
        System.out.println("       -jar app.jar");
        System.out.println("  Balance of speed and safety");

        System.out.println("\n--- STRING DEDUPLICATION ---");

        System.out.println("\nEnable string dedup with CDS:");
        System.out.println("  java -XX:+UseStringDeduplication \\");
        System.out.println("       -XX:SharedArchiveFile=app.jsa \\");
        System.out.println("       -jar app.jar");

        System.out.println("\nBenefits:");
        System.out.println("  • Shared string table");
        System.out.println("  • Reduced duplicate strings");
        System.out.println("  • Lower memory usage");

        System.out.println("\n--- DIAGNOSTIC LOGGING ---");

        System.out.println("\nComprehensive CDS logging:");
        System.out.println("  java -Xlog:cds=debug \\");
        System.out.println("       -Xlog:cds+map=trace \\");
        System.out.println("       -Xlog:cds+resolve=debug \\");
        System.out.println("       -XX:SharedArchiveFile=app.jsa \\");
        System.out.println("       -jar app.jar");

        System.out.println("\nLogging options:");
        System.out.println("  cds              General CDS info");
        System.out.println("  cds+map          Memory mapping");
        System.out.println("  cds+resolve      Class resolution");
        System.out.println("  cds+load         Class loading");
        System.out.println("  cds+heap         Heap archiving");
    }

    public static void printTroubleshooting() {
        System.out.println("\n=== TROUBLESHOOTING CDS ===");

        System.out.println("\n--- COMMON ISSUES ---");

        System.out.println("\n1. Archive not used silently:");
        System.out.println("   Problem: -Xshare:auto falls back without warning");
        System.out.println("   Solution: Use -Xshare:on to force error");
        System.out.println("   Debug: -Xlog:cds shows reason");

        System.out.println("\n2. Classpath mismatch:");
        System.out.println("   Error: 'Unable to use shared archive'");
        System.out.println("   Cause: Runtime classpath differs from dump");
        System.out.println("   Solution: Ensure exact same -cp");

        System.out.println("\n3. JVM option mismatch:");
        System.out.println("   Error: 'The shared archive file's option setting'");
        System.out.println("   Cause: Different -XX flags between dump and run");
        System.out.println("   Solution: Match flags or regenerate");

        System.out.println("\n4. Compressed oops mismatch:");
        System.out.println("   Error: 'The shared archive file cannot be used'");
        System.out.println("   Cause: Archive created with different oop setting");
        System.out.println("   Solution: Regenerate with matching setting");

        System.out.println("\n5. Version mismatch:");
        System.out.println("   Error: 'Cannot use shared archive'");
        System.out.println("   Cause: JDK version changed");
        System.out.println("   Solution: Regenerate for new JDK");

        System.out.println("\n--- VERIFICATION ---");

        System.out.println("\nConfirm CDS is active:");
        System.out.println("  java -Xlog:cds -version 2>&1 | grep 'Opened'");
        System.out.println("  ");
        System.out.println("  Expected output:");
        System.out.println("  [info][cds] Opened archive /path/to/app.jsa");

        System.out.println("\nCheck class loading:");
        System.out.println("  java -Xlog:cds+load -jar app.jar 2>&1 | grep 'loaded'");
        System.out.println("  ");
        System.out.println("  Shows classes loaded from archive");
    }
}

Best Practices

  • Test custom loaders thoroughly: Ensure deterministic behavior.
  • Use module-aware archives: Leverage JPMS for better organization.
  • Consider AOT for serverless: CDS + Native Image for fastest startup.
  • Layer archives strategically: Share common layers across services.
  • Monitor archive effectiveness: Use diagnostic logging.
  • Handle mismatches gracefully: Provide fallback or clear errors.
  • Document loader requirements: Custom loaders need careful setup.
  • Tune archive sizes: Adjust for large applications.
  • Keep compressed oop setting consistent: Match between dump and runtime.
  • Plan for future enhancements: Project Leyden will improve CDS + AOT integration.