Example example_unnamed-module-reflection-illegal-access

Part of the full Java 9 Jigsaw modules example suite.

Authors

Migrated for Java Modules support documentation of Apache MavenTM in the course of the Maven Support & Care program by Gerd Aschemann (and other team members) as forked repository. Please add discussions, requirements, bugfixes, etc. to the fork instead of the original.

What is this example about?

Modules in this example

  • The unnamed module (i.e. the classpath) and "normal" modules modb and modc.

  • modb is accesses from the unnamed module.

  • modc is not really relevant but only needed to allow a class in modb to be exported-to only to modc.

Module Dependency Graph, created with DepVis

Example’s Module Dependency Graph

Example shows …​

The usage of the Java command line option --illegal-access, aka the "kill switch". See Java9 Maillinglist for details.

Four classes on the classpath, i.e. in the unnamed module, access other classes with reflective access.

  • cpmain/pkgcpmain.MainCallingJavaBaseJDKInternal.java does reflective access to a class from module java.base, package jdk.internal (a package which is new in Java9). An explicit --add-opens is hence needed.

  • cpmain/pkgcpmain.MainCallingJavaBaseSunNet.java does reflective access to a class from module java.base, package sun.net (a package which has existed before, in Java8). The kill-switch --illegal-access=permit will hence work.

  • cpmain/pkgcpmain.MainCallingJavaDesktop.java does reflective access to a class from module java.desktop, package sun.awt (a package which has existed before, in Java8). The kill-switch --illegal-access=permit will hence work.

  • cpmain/pkgcpmain.MainCallingJavaBaseModB.java does reflective access to a class from module modb (a package which has not existed before Java9). An explicit --add-opens is hence needed.

Note that the kill switch only works for classes which had been available before Java9, i.e. were part of Java8. See also explanation here.

See all 20 different variants of how to use the --illegal-access=…​ command line option or the --add-opens option in the run script run.sh.

Output

This example uses golden master testing to ensure output consistency. The expected output is compared with actual output using verify.sh.

Expected Output

Caught exception: class java.lang.reflect.InaccessibleObjectException
Caught exception: class java.lang.reflect.InaccessibleObjectException
Caught exception: class java.lang.reflect.InaccessibleObjectException
Caught exception: class java.lang.reflect.InaccessibleObjectException
jdk.internal.math.DoubleConsts
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.net.PortConfig
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.net.PortConfig
WARNING - content dropped due to output normalization
sun.net.PortConfig
Caught exception: class java.lang.reflect.InaccessibleObjectException
sun.net.PortConfig
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.awt.OSInfo
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.awt.OSInfo
WARNING - content dropped due to output normalization
sun.awt.OSInfo
Caught exception: class java.lang.reflect.InaccessibleObjectException
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.awt.OSInfo
pkgb.BFromModule, id=ID_MainCallingModB_14
Caught exception: class java.lang.reflect.InaccessibleObjectException
pkgb.BFromModule, id=ID_MainCallingModB_14
Caught exception: class java.lang.reflect.InaccessibleObjectException
pkgb.BFromModule, id=ID_MainCallingModB_14
Caught exception: class java.lang.reflect.InaccessibleObjectException
pkgb.BFromModule, id=ID_MainCallingModB_14
Caught exception: class java.lang.reflect.InaccessibleObjectException
pkgb.BFromModule, id=ID_MainCallingModB_14
pkgbinternal.BFromModuleButInternal, id=ID_MainCallingModB_26
pkgbexportedqualified.BFromModuleButExportedQualified, id=ID_MainCallingModB_38

Actual Output

Caught exception: class java.lang.reflect.InaccessibleObjectException
Caught exception: class java.lang.reflect.InaccessibleObjectException
Caught exception: class java.lang.reflect.InaccessibleObjectException
Caught exception: class java.lang.reflect.InaccessibleObjectException
jdk.internal.math.DoubleConsts
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.net.PortConfig
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.net.PortConfig
WARNING - content dropped due to output normalization
sun.net.PortConfig
Caught exception: class java.lang.reflect.InaccessibleObjectException
sun.net.PortConfig
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.awt.OSInfo
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.awt.OSInfo
WARNING - content dropped due to output normalization
sun.awt.OSInfo
Caught exception: class java.lang.reflect.InaccessibleObjectException
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.awt.OSInfo
pkgb.BFromModule, id=ID_MainCallingModB_14
Caught exception: class java.lang.reflect.InaccessibleObjectException
pkgb.BFromModule, id=ID_MainCallingModB_14
Caught exception: class java.lang.reflect.InaccessibleObjectException
pkgb.BFromModule, id=ID_MainCallingModB_14
Caught exception: class java.lang.reflect.InaccessibleObjectException
pkgb.BFromModule, id=ID_MainCallingModB_14
Caught exception: class java.lang.reflect.InaccessibleObjectException
pkgb.BFromModule, id=ID_MainCallingModB_14
pkgbinternal.BFromModuleButInternal, id=ID_MainCallingModB_26
pkgbexportedqualified.BFromModuleButExportedQualified, id=ID_MainCallingModB_38

Maven 4 Output

Caught exception: class java.lang.reflect.InaccessibleObjectException
Caught exception: class java.lang.reflect.InaccessibleObjectException
Caught exception: class java.lang.reflect.InaccessibleObjectException
Caught exception: class java.lang.reflect.InaccessibleObjectException
jdk.internal.math.DoubleConsts
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.net.PortConfig
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.net.PortConfig
WARNING - content dropped due to output normalization
sun.net.PortConfig
Caught exception: class java.lang.reflect.InaccessibleObjectException
sun.net.PortConfig
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.awt.OSInfo
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.awt.OSInfo
WARNING - content dropped due to output normalization
sun.awt.OSInfo
Caught exception: class java.lang.reflect.InaccessibleObjectException
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
WARNING - content dropped due to output normalization
sun.awt.OSInfo
pkgb.BFromModule, id=ID_MainCallingModB_14
Caught exception: class java.lang.reflect.InaccessibleObjectException
pkgb.BFromModule, id=ID_MainCallingModB_14
Caught exception: class java.lang.reflect.InaccessibleObjectException
pkgb.BFromModule, id=ID_MainCallingModB_14
Caught exception: class java.lang.reflect.InaccessibleObjectException
pkgb.BFromModule, id=ID_MainCallingModB_14
Caught exception: class java.lang.reflect.InaccessibleObjectException
pkgb.BFromModule, id=ID_MainCallingModB_14
pkgbinternal.BFromModuleButInternal, id=ID_MainCallingModB_26
pkgbexportedqualified.BFromModuleButExportedQualified, id=ID_MainCallingModB_38

Maven 4 Migration

This example required a special migration approach due to the presence of classpath code (unnamed module) that depends on explicit modules.

Standard Migration

The explicit modules (modb, modc) were migrated using the standard Module Source Hierarchy approach with direct paths to the original source directories.

Special Handling: Classpath Code Dependent on Modules

Problem

Maven 4’s Module Source Hierarchy requires module descriptors (module-info.java) for all source entries. This example contains cpmain, which is classpath code (unnamed module) without module-info.java.

Additionally, cpmain needs to access classes from modb during compilation, requiring the modules to be compiled first.

Solution

Hybrid compilation approach in m4/compile.sh:

  1. Maven compiles explicit modules (modb, modc) first

  2. Package modules as JARs in mlib/

  3. Manual javac compilation of cpmain with classpath pointing to mlib/*

    The compilation order is critical: modules must be compiled and packaged before cpmain.

  4. Runtime uses 20 test variants with various --illegal-access and --add-opens flags to demonstrate JDK encapsulation behavior

This hybrid approach is necessary because:

  • Maven 4’s Module Source Hierarchy cannot compile code without module-info.java

  • Classpath code (unnamed module) must be compiled separately from explicit modules

  • Compilation order matters: cpmain depends on modb during compilation

  • The classpath/module-path split must be maintained at both compile-time and runtime

  • The example demonstrates illegal reflective access behavior with various JVM flags