Closed nirupamarachuri closed 5 years ago
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.
@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
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);
}
}
@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.
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.
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?
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.
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;
}
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.
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
Is there any release planned for kryo-serializers and kryo-shaded that supports Java 11? If yes, when is it planned to release?