Better tools for adjusting to strong encapsulation

Martijn Verburg martijnverburg at
Wed Mar 22 16:05:04 UTC 2017

Hi Mark,

Thanks for putting in this mechanism.  I appreciate some folks would
like some fine tuning / control of this, but it gets a thumbs up from
many of our customers and developers at the LJC.  It's crucial that
they're given time to migrate to safer libs (or even better help those
libs become safer).

On 21 March 2017 at 14:48,  <mark.reinhold at> wrote:
> By now we've heard quite a bit of feedback, both publicly and privately,
> from developers who've migrated existing applications to JDK 9.  This can
> be a non-trivial task, involving the iterative construction of a set of
> command-line workarounds, since some popular libraries and frameworks use
> the core reflection API to access internal APIs of the JDK.  On JDK 9
> such components no longer work out-of-the-box because most internal APIs
> are now strongly encapsulated in order to improve the integrity of the
> platform.
> In order to make it easier to adjust to the strong encapsulation of
> internal APIs in JDK 9, in both the short term and over the long term,
> we've introduced a temporary "big kill switch", described below.  This
> switch will only be supported in JDK 9.  It's already available in the
> current Jigsaw EA builds [1], and will shortly be merged into JDK 9.
> Background
> ----------
> Diagnosing the failures of libraries and frameworks that access internal
> APIs of the JDK and then working around those failures is possible, but
> tedious.  The initial symptom is usually an `IllegalAccessException` or
> an `InaccessibleObjectException`.  The workaround is to use an
> `--add-opens` command-line option whose arguments are based upon the
> information shown in the exception message.  A large application that
> uses several reflective components may suffer many such failures, so this
> process may have to be repeated many times, resulting in a long list of
> command-line options that will typically be recorded in a launch script
> or an @-file.
> These options are tedious to construct but, additionally, there's a
> significant risk that once they're baked into a file they'll never be
> removed, even long after the problems that they work around have been
> resolved.  An application that needs some workarounds today might not
> benefit as well as it could from strong encapsulation in the long term,
> after all of the reflective components that it uses have been fixed to
> replace their use of JDK-internal APIs with proper exported APIs.
> To help the entire ecosystem migrate to the modular Java platform we want
> to motivate such fixes as strongly as we possibly can, especially in the
> near term.  We can do that by making it easier for you to get an existing
> application to work while also ensuring that the run-time system reports
> illegal reflective-access operations in a way that allows you to identify
> which libraries and frameworks on your class path require illegal access
> in order to work.  If a component's maintainers have already released a
> new, fixed version that no longer requires illegal access then you can
> consider upgrading to that version.  If, however, a component still needs
> to be fixed then we encourage you to contact its maintainers and ask them
> to stop using JDK-internal APIs [2].
> With all this in mind we've introduced a "big kill switch", described
> below, together with some new warning messages.  This switch will be
> supported in JDK 9, in order to enable application migration and motivate
> fixes to libraries and frameworks.  It will not be supported in JDK 10 or
> later releases, in order to motivate fixes to libraries and frameworks
> sooner rather than later.  If this switch were to be supported long-term
> then that would tend to reduce the pressure on maintainers to fix their
> components.
> New command-line option: `--permit-illegal-access`
> --------------------------------------------------
> If this option is present at run time then it will permit illegal access
> operations by code in any unnamed module (i.e., code on the class path)
> to members of types in any named module via the standard reflective APIs
> (`java.lang.reflect` and `java.lang.invoke`), including in particular
> those that would otherwise result in an `IllegalAccessException` or an
> `InaccessibleObjectException`.
>             +----------------------------------------------+
>             | This option will only be supported in JDK 9. |
>             |         It will be removed in JDK 10.        |
>             +----------------------------------------------+
> This option does not permit illegal access operations by code in named
> modules to members of types in other named modules; for that you must
> use the `--add-opens` or `--add-exports` options.  Those options can be
> combined with `--permit-illegal-access`.
> Warnings of illegal reflective-access operations
> ------------------------------------------------
> When an illegal reflective access operation succeeds due to the use of
> the `--permit-illegal-access` option, or the use of an `--add-opens` or
> `--add-exports` option, then a warning message of the following form is
> written to the error stream:
>     WARNING: Illegal access by $PERPETRATOR to $VICTIM (permitted by $OPTION)
> where:
>   - $PERPETRATOR is the fully-qualified name of the type containing
>     the code that invoked the reflective operation in question plus
>     the code source (i.e., JAR-file path), if available,
>   - $VICTIM is a string that describes the member being accessed,
>     including the fully-qualified name of the enclosing type, and
>   - $OPTION is the name of the command-line option that enabled this
>     access, when that can be determined, or the first one of those
>     options if more than one option had that effect.
> The run-time system attempts to suppress duplicate warnings for the same
> $PERPETRATOR and $VICTIM, but it's not always practical to do so.
> For deeper diagnosis you can request a stack trace on each such warning
> by setting the system property `sun.reflect.debugModuleAccessChecks` to
> the value `access`, though this detail might change.  (That property can
> also be helpful to diagnose mysterious failures due to illegal-access
> exceptions that are caught and suppressed.)
> In addition to displaying a warning on each illegal access operation, the
> run-time system also shows new initial warning messages at startup time.
> If `--permit-illegal-access` is used then a warning reports the imminent
> demise of that option in the next major release.  If either `--add-opens`
> or `--add-exports` are used then a warning reports a count of each type
> of option used (i.e., opens vs. exports).
> Here are some examples of these messages, from running Jython on a very
> recent Jigsaw build:
>   $ java --permit-illegal-access -jar jython-standalone-2.7.0.jar
>   WARNING: --permit-illegal-access will be removed in the next major release
>   WARNING: Illegal access by jnr.posix.JavaLibCHelper (file:/tmp/jython-standalone-2.7.0.jar) to method (permitted by --permit-illegal-access)
>   WARNING: Illegal access by jnr.posix.JavaLibCHelper (file:/tmp/jython-standalone-2.7.0.jar) to field (permitted by --permit-illegal-access)
>   WARNING: Illegal access by jnr.posix.JavaLibCHelper (file:/tmp/jython-standalone-2.7.0.jar) to field (permitted by --permit-illegal-access)
>   WARNING: Illegal access by org.python.core.PySystemState (file:/tmp/jython-standalone-2.7.0.jar) to method (permitted by --permit-illegal-access)
>   Jython 2.7.0 (default:9987c746f838, Apr 29 2015, 02:25:11)
>   [OpenJDK 64-Bit Server VM (Oracle Corporation)] on java9-internal
>   Type "help", "copyright", "credits" or "license" for more information.
>   >>> ^D
>   $
> [1]
> [2] This will usually but not always be possible, since there are still a
>     few critical internal APIs without exported replacements, per JEP 260
>     (

More information about the jigsaw-dev mailing list