Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java 9: Illegal reflective access by com.sun.xml.bind.v2.runtime.reflect.opt.Injector #1197

Closed
Tomas-Kraus opened this issue May 6, 2018 · 13 comments

Comments

@Tomas-Kraus
Copy link
Member

With Java 9 or 10, using

            <dependency>
                <groupId>org.glassfish.jaxb</groupId>
                <artifactId>jaxb-runtime</artifactId>
                <version>2.3.0</version>
            </dependency>

results in:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.sun.xml.bind.v2.runtime.reflect.opt.Injector 
(file: repository/org/glassfish/jaxb/jaxb-runtime/2.3.0/jaxb-runtime-2.3.0.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int)
WARNING: Please consider reporting this to the maintainers of com.sun.xml.bind.v2.runtime.reflect.opt.Injector
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
@Tomas-Kraus
Copy link
Member Author

@namannigam Commented
Tracker for a similar question on Stackoverflow => Q50237516

@Tomas-Kraus
Copy link
Member Author

@bravehorsie Commented
jaxb-ri runtime uses ClassLoader#defineClass / Unsafe#defineClass to do
some bytecode modification in runtime to optimize performance.
ClassLoader#defineClass is tried first which causes the warning.

This legacy optimization is removed completely in jaxb-ri master (after
2.3.0, not released yet).

To disable this optimization for 2.3.0, set system property
com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize.

Roman

On Wed, May 9, 2018 at 6:57 AM, Naman Nigam [email protected]
wrote:

Tracker for a similar question on Stackoverflow => Q50237516
https://stackoverflow.com/questions/50237516/proper-fix-for-java-10-complaining-about-illegal-reflection-access-by-jaxb-impl


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
javaee/jaxb-v2#1197 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AI8ZttSIFtRovJJhToXUxJrtfXDj2AGmks5twndJgaJpZM4Tz4Of
.

@Tomas-Kraus
Copy link
Member Author

@corneliuc Commented
Hi Roman,

When I try to run with Java 9 I have the following behavior:

java -XX:+IgnoreUnrecognizedVMOptions --add-modules java.activation -cp ":./otherJars/" com.package.Main "$@"

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.sun.xml.bind.v2.runtime.reflect.opt.Injector (file:/.../jaxb-impl.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int)
WARNING: Please consider reporting this to the maintainers of com.sun.xml.bind.v2.runtime.reflect.opt.Injector
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

And when I used noOptimize I still have some messages:

java -XX:+IgnoreUnrecognizedVMOptions -Dcom.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize=true --add-modules java.activation -cp ":./otherJars/" com.package.Main "$@"

May 18, 2018 12:18:52 PM com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector
INFO: The optimized code generation is disabled

Do you know how to escape these messages?

The current intent for Oracle is to remove the java.se.ee modules starting with a future release which apparently is Java 11,
this means we will not be able to use anymore JAXB(javax.xml.bind module).

How I can be procced further I need to change the library completely already now(find a replacement for JAXB) in order to be compatible with Java 11+ or use JAXB for Java 9 and 10 and look in the future
for Java 11 solution, keep in mind java 11 will be released soon(around the end of this year).
https://jaxenter.com/jdk-11-java-ee-modules-140674.html

Library used:
FastInfoset-1.2.13.jar
istack-commons-runtime-3.0.5.jar
stax-ex-1.7.8.jar
txw2-2.3.0.jar
jaxb-api-2.3.0.jar
jaxb-core-2.3.0.jar
jaxb-runtime-2.3.0.jar

Corneliu,

@Tomas-Kraus
Copy link
Member Author

@bravehorsie Commented
Hi Corneliu,

as I posted here:
https://stackoverflow.com/questions/50237516/proper-fix-for-java-10-complaining-about-illegal-reflection-access-by-jaxb-impl
Runtime code optimizaton is removed in master branch and will ship with
next release. Updating to new version will remove both messages. and
.noOptimize flag.
Next version will be usable with Java 11, which has excluded java.xml.bind
and java.xml.ws modules.

Roman

On Fri, May 18, 2018 at 12:02 PM, corneliuc [email protected]
wrote:

Hi Roman,

When I try to run with Java 9 I have the following behavior:

java -XX:+IgnoreUnrecognizedVMOptions --add-modules java.activation -cp "
:./otherJars/" com.package.Main "$@"

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.sun.xml.bind.v2.runtime.reflect.opt.Injector
(file:/.../jaxb-impl.jar) to method java.lang.ClassLoader.
defineClass(java.lang.String,byte[],int,int)
WARNING: Please consider reporting this to the maintainers of
com.sun.xml.bind.v2.runtime.reflect.opt.Injector
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

And when I used noOptimize I still have some messages:

java -XX:+IgnoreUnrecognizedVMOptions -Dcom.sun.xml.bind.v2.
bytecode.ClassTailor.noOptimize=true --add-modules java.activation -cp "
:./otherJars/" com.package.Main "$@"

May 18, 2018 12:18:52 PM com.sun.xml.bind.v2.runtime.reflect.opt.AccessorInjector

INFO: The optimized code generation is disabled

Do you know how to escape these messages?

The current intent for Oracle is to remove the java.se.ee modules
starting with a future release which apparently is Java 11,
this means we will not be able to use anymore JAXB(javax.xml.bind module).

How I can be procced further I need to change the library completely
already now(find a replacement for JAXB) in order to be compatible with
Java 11+ or use JAXB for Java 9 and 10 and look in the future
for Java 11 solution, keep in mind java 11 will be released soon(around
the end of this year).
https://jaxenter.com/jdk-11-java-ee-modules-140674.html

Library used:
FastInfoset-1.2.13.jar
istack-commons-runtime-3.0.5.jar
stax-ex-1.7.8.jar
txw2-2.3.0.jar
jaxb-api-2.3.0.jar
jaxb-core-2.3.0.jar
jaxb-runtime-2.3.0.jar

Corneliu,


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
javaee/jaxb-v2#1197 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AI8Ztjdb1wdHQfCboWh5PZS4l39Ty_Unks5tzpxCgaJpZM4Tz4Of
.

@Tomas-Kraus
Copy link
Member Author

@abdulmuqsith Commented
When do we have the next release 2.4 available?

@Tomas-Kraus
Copy link
Member Author

@bravehorsie
Copy link
Contributor

Fixed in 2.3.1

codekaust added a commit to draeger-lab/ModelPolisher that referenced this issue Jul 2, 2019
@sify21
Copy link

sify21 commented Jan 21, 2021

Hi I'm using org.glassfish.jaxb:jaxb-runtime:3.0.0 jakarta.xml.bind:jakarta.xml.bind-api:3.0.0, and this warning comes back @bravehorsie @Tomas-Kraus

@bourgesl
Copy link

Hi,

I tested my jaxb application (compiled with JDK8) with JDK 16 (openjdk) and it fails with the exception:

ERROR [main] com.sun.xml.bind.v2.runtime.reflect.opt.Injector - null
    java.security.PrivilegedActionException: null
    Caused by: java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String,[B,int,int,java.lang.ClassLoader,java.security.ProtectionDomain)
    at java.base/java.lang.Class.getMethod(Class.java:2195)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:170)
    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:166)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:554)

I upgrade to the lastest JAXB 2.3 release (no 2.4 release yet) as I need wide java version compatibility (8 to 17).
I can not switch to JAXB RI 3.0 (JDK11+, no jdk8 support) as it implies a migration effort to jakarta.xml packages and re-generate all JAXB code to comply with this package renaming).

To fix the problem with JDK16, I must explicitely set one of the following system properties before calling JAXBContext.newInstance(...):

    System.setProperty("com.sun.xml.bind.v2.runtime.reflect.opt.OptimizedAccessorFactory.noOptimization", "true");
or
    System.setProperty("com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize", "true");

Which property is better to use ?
I figured out myself that 'OptimizedAccessorFactory.noOptimization' is good, but you promote using 'ClassTailor.noOptimize'. Could you explain the difference ?

Would it be possible to detect JDK16 in jaxb 2.3.x or 2.4 (JDK8 compatible) and disable such (unsupported) optimization ?

Here are my concrete maven (explicit) dependencies to use JAXB 2.3.3 in my project:

        <!-- JAXB 2.3.3 (jdk 8+) -->
        <dependency>
            <groupId>jakarta.xml.bind</groupId>
            <artifactId>jakarta.xml.bind-api</artifactId>
            <version>2.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.3</version>
        </dependency>

        <!-- JAXB dependencies -->
        <dependency>
            <groupId>jakarta.activation</groupId>
            <artifactId>jakarta.activation-api</artifactId>
            <version>1.2.2</version>
        </dependency>
        <dependency>
            <groupId>com.sun.activation</groupId>
            <artifactId>jakarta.activation</artifactId>
            <version>1.2.2</version>
        </dependency>

        <dependency>
            <groupId>com.sun.istack</groupId>
            <artifactId>istack-commons-runtime</artifactId>
            <version>3.0.11</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.fastinfoset</groupId>
            <artifactId>FastInfoset</artifactId>
            <version>1.2.18</version>
        </dependency>
        <dependency>
            <groupId>org.jvnet.staxex</groupId>
            <artifactId>stax-ex</artifactId>
            <version>1.8.3</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>txw2</artifactId>
            <version>2.3.3</version>
        </dependency>

@lukasj
Copy link
Member

lukasj commented Mar 31, 2021

Does passing -Djdk.util.jar.enableMultiRelease=force to JVM make any difference?

@bourgesl
Copy link

In my case, the application is build on JDK8 (to be sure it works on java 8) as a single fat jar or exploded classpath. As I am not using modules yet, I have no idea.

Moreover, it is a desktop application so I can not ask users to define magic flags on the command line, but I can set few needed system properties in my code:

    /** JAXB implementation 2.3.x provided in project libraries */
    private static final String JAXB_CONTEXT_FACTORY_IMPLEMENTATION = "com.sun.xml.bind.v2.ContextFactory";

    static {
        // Define the system property to define which JAXB implementation to use:
        System.setProperty("javax.xml.bind.JAXBContextFactory", JAXB_CONTEXT_FACTORY_IMPLEMENTATION);
        System.setProperty(JAXBContext.JAXB_CONTEXT_FACTORY, JAXB_CONTEXT_FACTORY_IMPLEMENTATION);

        if (org.apache.commons.lang.SystemUtils.JAVA_VERSION_FLOAT >= 16.0f) {
            // JDK16 support fix:
            /*
                ERROR [main] com.sun.xml.bind.v2.runtime.reflect.opt.Injector - null
                java.security.PrivilegedActionException: null
                Caused by: java.lang.NoSuchMethodException: sun.misc.Unsafe.defineClass(java.lang.String,[B,int,int,java.lang.ClassLoader,java.security.ProtectionDomain)
                    at java.base/java.lang.Class.getMethod(Class.java:2195)
                    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:170)
                    at com.sun.xml.bind.v2.runtime.reflect.opt.Injector$3.run(Injector.java:166)
                    at java.base/java.security.AccessController.doPrivileged(AccessController.java:554)
            */
            final String key = "com.sun.xml.bind.v2.bytecode.ClassTailor.noOptimize";
            System.setProperty(key, "true");
            logger.info("Fix JDK-16+ support: version = {} (set {} = true)", 
                    org.apache.commons.lang.SystemUtils.JAVA_VERSION_FLOAT, key);
        }
        logger.info("JAXB ContextFactory: {}", System.getProperty(JAXBContext.JAXB_CONTEXT_FACTORY));
    }

@lukasj
Copy link
Member

lukasj commented Mar 31, 2021

In my case, the application is build on JDK8 (to be sure it works on java 8) as a single fat jar or exploded classpath. As I am not using modules yet, I have no idea.

So this the cause of your troubles and reason I won't be able to reproduce the issue on my end. Your app needs to have META-INF/versions folder and be marked as Multi-Release: true in manifest if you want it to work properly on JDKs 8-17 at the same time. Take a look what multirelease jar files are about: https://openjdk.java.net/jeps/238

@bourgesl
Copy link

Thanks.
My fat jar already had META-INF/versions folder but 'Multi-Release: true' was missing in the MANIFEST.MF !
I will get rid of my JDK16 fix as it works now like a charm !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants