2

I am migrating a huge monolith application from java 1.7 to 12 and I want to do it the right way with as little hacks as possible. I keep, rightfully, running into errors such as this :

[ERROR] /home/idiot/projects/projects/blah/blah/src/blah/blah/blah/Blah.java:[8,18] package sun.nio.cs.ext is not visible

and

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project blah: Compilation failure
    [ERROR] /home/idiot/projects/blah/blah/src/blah/blah/blah/Bblah.java:[152,42] package com.sun.org.apache.xerces.internal.dom is not visible
    [ERROR]   (package com.sun.org.apache.xerces.internal.dom is declared in module java.xml, which does not export it)

and warnings such as this

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.python.google.common.base.internal.Finalizer (file:/home/idiot/.m2/repository/own/plugin/own-plugin-1.jar) to field java.lang.Thread.inheritableThreadLocals
WARNING: Please consider reporting this to the maintainers of org.python.google.common.base.internal.Finalizer
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Modularising this behemoth of a web app seems impossible, without even a proper tutorial to look up. Most of google and stack results are solutions applicable to pre java 11 environments. Most of google-fu recommends using the right package instead of the one which is now hidden/obsolete.

The challenge and my question is, how do I find out what a now obsolete API is replaced with ?

There are hundreds and thousands of files using reflections, com.sun.org, sun.misc packages, once the steps to find the replacement packages is figured, how to go about addressing this? Just manually go through thousands of files and update ?

happybuddha
  • 1,271
  • 2
  • 20
  • 40

1 Answers1

3

I know of no single source that lists all existing replacement packages (although it would be nice to have one). Instead, you need to search for a replacement for each individual one - if that's unsuccessful, I recommend creating a new question for each package / use case.

Note that there may very well not be an official replacement for each internal API. Quite the opposite, in general, most internals won't have a public alternative. Many don't need one, but there are always some edge cases that we come up against that are simply not supported by the JDK APIs. In that case (and as a band-aid for others until you find solutions), you can force compiler and runtime to export/open internal APIs with --add-exports and --add-opens, e.g.:

# your first compile error example
javac --add-exports jdk.charsets/sun.nio.cs.ext=ALL-UNNAMED ...
java --add-exports jdk.charsets/sun.nio.cs.ext=ALL-UNNAMED ...
# your second compiler error example
javac --add-exports java.xml/com.sun.org.apache.xerces.internal.dom=ALL-UNNAMED ...
java --add-exports java.xml/com.sun.org.apache.xerces.internal.dom=ALL-UNNAMED ...
# your run-time warning example
java --add-opens java.base/java-lang=ALL-UNNAMED

Here's how to add these in Maven to the compiler plugin and Surefire/Failsafe (same syntax):

<plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <!-- PLEASE ADD A COMMENT EXPLAINING WHICH CLASSES/DEPENDENCIES
                USE THIS INTERNAL API AND WHY! -->
        <compilerArgs>
            --add-exports jdk.charsets/sun.nio.cs.ext=ALL-UNNAMED
            --add-exports java.xml/com.sun.org.apache.xerces.internal.dom=ALL-UNNAMED       </compilerArgs>
    </configuration>
</plugin>
<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <!-- PLEASE ADD A COMMENT EXPLAINING WHICH CLASSES/DEPENDENCIES
                USE THIS INTERNAL API AND WHY! -->
        <argLine>
            --illegal-access=deny
            --add-exports jdk.charsets/sun.nio.cs.ext=ALL-UNNAMED
            --add-exports java.xml/com.sun.org.apache.xerces.internal.dom=ALL-UNNAMED
            --add-opens java.base/java-lang=ALL-UNNAMED
        </argLine>
    </configuration>
</plugin>

(Explanation of --illegal-access and why you should add it.)

Yes, these are "dirty workarounds", but they have an advantage over the pre-Java-9 way: Your dependency on internal APIs is now explicit and the inconvience of adding command line flags everywhere gives you an incentive to stop doing it.

There are hundreds and thousands of files using reflections, com.sun.org, sun.misc packages, once the steps to find the replacement packages is figured, how to go about addressing this? Just manually go through thousands of files and update ?

Yep. It's almost as if using them were a bad idea in the first place.

Nicolai Parlog
  • 47,972
  • 24
  • 125
  • 255