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

Support for Java 11 #626

Closed
nirupamarachuri opened this issue Oct 8, 2018 · 9 comments
Closed

Support for Java 11 #626

nirupamarachuri opened this issue Oct 8, 2018 · 9 comments

Comments

@nirupamarachuri
Copy link

nirupamarachuri commented Oct 8, 2018

Is there any release planned for kryo-serializers and kryo-shaded that supports Java 11? If yes, when is it planned to release?

@free2bcreative
Copy link

I've been testing my project with java 11 and noticed the following warning:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.esotericsoftware.kryo.util.UnsafeUtil (...) to constructor java.nio.DirectByteBuffer(long,int,java.lang.Object)
WARNING: Please consider reporting this to the maintainers of com.esotericsoftware.kryo.util.UnsafeUtil
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

I don't know if this fits under "support for Java 11", because my project still works fine. I don't know when java will start denying illegal access, but I would hope kryo can avoid it early on - it's been a great library.

@NathanSweet
Copy link
Member

@nirupamarachuri Kryo works fine with Java 11. When reflection is disallowed (note it is allowed in Java 11 by default), many Kryo serializers will no longer work. Kryo itself should still work fine, but you would need to use serializers that don't rely on reflection. I don't personally have a need to use Java with reflection disabled, so I don't currently have plans to work on alternate serializers.

@free2bcreative It's just a warning. You can read more about it here:
https://groups.google.com/forum/#!topic/kryo-users/bcsag2KfbvA

@lucianoRM
Copy link

I am also interested in Java 11 support.
I see the following error when trying to serialize a java.io.FileInputStream:

Serialization trace:
cleanup (java.io.FileDescriptor)
fd (java.io.FileInputStream)
	at org.mule.tooling.client.tests.integration.tooling.client.KryoTestCase.serializeBufferedInputStream(KryoTestCase.java:32)
Caused by: java.lang.IllegalArgumentException: Unable to create serializer "com.esotericsoftware.kryo.serializers.FieldSerializer" for class: java.io.FileCleanable
	at org.mule.tooling.client.tests.integration.tooling.client.KryoTestCase.serializeBufferedInputStream(KryoTestCase.java:32)
Caused by: java.lang.reflect.InvocationTargetException
	at org.mule.tooling.client.tests.integration.tooling.client.KryoTestCase.serializeBufferedInputStream(KryoTestCase.java:32)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field jdk.internal.ref.PhantomCleanable jdk.internal.ref.PhantomCleanable.prev accessible: module java.base does not "opens jdk.internal.ref" to unnamed module @37f1104d
	at org.mule.tooling.client.tests.integration.tooling.client.KryoTestCase.serializeBufferedInputStream(KryoTestCase.java:32)

I debugged the code and the error is indeed because "jdk.internal.ref" is not opened in java.base module.
I tried using --add-opens and --illegal-access=permit flags but i still get this error. I think is because PhantomCleanable is a new class that was not included in Java 8 and as i could understand, with those flags you only get reflection access to pre-java 9 classes. (https://docs.oracle.com/javase/9/tools/java.htm#JSWOR624)

@NathanSweet Is this one example of one of the many Kryo serializers that will no longer work? Do you suggest any kind of workaround?

By the way, the code i'm running is the following:

FileInputStream bis =
        new FileInputStream(currentThread().getContextClassLoader().getResource("test-file").getPath());

    Kryo kryo = new Kryo();

    kryo.register(FileInputStream.class);

    try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
      try (Output output = new Output(byteArrayOutputStream)) {
        kryo.writeClassAndObject(output, bis);
      }
    }

@NathanSweet
Copy link
Member

@lucianoRM That is not about Java 11 at all. You register FileInputStream with the default serializer, which is FieldSerialier. You can't just point FieldSerializer at any class. See here:
https://github.com/EsotericSoftware/kryo/#fieldserializer

FieldSerializer works by serializing each non-transient field. It can serialize POJOs and many other classes without any configuration. All non-public fields are written and read by default, so it is important to evaluate each class that will be serialized.

@lucianoRM
Copy link

I relate this to Java 11 because the same example works in Java 8 and the error described relates to module encapsulation. Maybe it was just a coincidence that it worked before updating to Java 11.

magro added a commit that referenced this issue Dec 28, 2018
Running tests with java 9+ required changes in test code.

Refs #626
magro added a commit that referenced this issue Dec 28, 2018
Running tests with java 9+ required changes in test code.

Refs #626
magro added a commit that referenced this issue Dec 28, 2018
Running tests with java 9+ required changes in test code.

Refs #626
magro added a commit that referenced this issue Dec 28, 2018
Running tests with java 9+ required changes in test code.

Refs #626
magro added a commit that referenced this issue Dec 28, 2018
Running tests with java 9+ required changes in test code.

Refs #626
magro added a commit that referenced this issue Dec 28, 2018
Running tests with java 9+ required changes in test code.

Refs #626
magro added a commit that referenced this issue Dec 28, 2018
Running tests with java 9+ required changes in test code.

Refs #626
@magro
Copy link
Collaborator

magro commented Dec 28, 2018

I just submitted PR #636 which adds running tests with jdk 9/11 to verify that kryo is working with these versions.
Is this sufficient to consider this issue to be resolved, or is anything else required?

Slightly related to the modules stuff is kryo's module name: as suggested here I'd say we should set the "Automatic-Module-Name" to "com.esotericsoftware.kryo" (and accordingly for reflectasm and minlog). WDYT?

magro added a commit that referenced this issue Dec 28, 2018
For the motivation see https://blog.joda.org/2017/05/java-se-9-jpms-automatic-modules.html

reflectasm and minlog are updated to versions that provide an
Automatic-Module-Name as well.

objenesis is not updated, because it only provides Automatic-Module-Name
with 3.0.1, which requires java 1.8 (since 3.0.0) and therefore would
require kryo to switch from 1.7 to 1.8.

Refs #626
@dustContributor
Copy link

dustContributor commented Dec 30, 2018

I was trying out Kryo in Java 11 and got that warning.

Just an idea but unless I'm mistaken, UnsafeUtil would be only be used if you use the Unsafe I/O classes, right? The issue is that for now, even if you don't use them, you get the warning anyway because the static initializer in Util triggers UnsafeUtil's class initialization.

https://github.com/EsotericSoftware/kryo/blob/master/src/com/esotericsoftware/kryo/util/Util.java#L41

I'm thinking you could give a way to "opt out" of this by having a system property to disable unsafe usage in Kryo, and skipping that Class.forName call so UnsafeUtil doesn't gets initialized and you stop getting that warning in Java 9+

Something like:

static {
  boolean found = false;
  String tryLoadUnsafe = System.getProperty("kryo.tryloadunsafe");
  if(!Objects.equals("false", tryLoadUnsafe)) {
    try {
      // By default if the property is missing or not 'false', try to load Unsafe.
      found = Class.forName("com.esotericsoftware.kryo.unsafe.UnsafeUtil", true, FieldSerializer.class.getClassLoader())
        .getField("unsafe").get(null) != null;
    } catch (Throwable ex) {
      ex.printStackTrace();
      if (TRACE) trace("kryo", "Unsafe is unavailable.");
    }
  } else {
    // Property was present and explicitly set to 'false', disable Unsafe usage.
    if (TRACE) trace("kryo", "Unsafe is disabled.");
  }
  unsafe = found;
}

@piyushbajaj0704
Copy link

I got the error during the run, "unable to make jdk.internal.ref.phantomcleanable() accessible: module java.base does not" on Java 11, when I switched to Java 9 in Intellij under Project structure, the error was gone and I was able to execute successfully.

@AbstractAlao
Copy link

Not sure if this has been fixed. I'm using spring state machine and got this message

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.esotericsoftware.kryo.util.UnsafeUtil (file:/C:/Users/aaats/.m2/repository/com/esotericsoftware/kryo-shaded/4.0.2/kryo-shaded-4.0.2.jar) to constructor java.nio.DirectByteBuffer(long,int,java.lang.Object)
WARNING: Please consider reporting this to the maintainers of com.esotericsoftware.kryo.util.UnsafeUtil
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

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

No branches or pull requests

8 participants