ehcache / ehcache3

Ehcache 3.x line
http://www.ehcache.org
Apache License 2.0
2k stars 579 forks source link

Java 11 support #2671

Open hos-p opened 5 years ago

hos-p commented 5 years ago

According to jdeps ehcache relies on classes which are removed from jdk 11. Is there any plan for java 11 support?

ehcache-3.7.1.jar -> JDK removed internal API ehcache-3.7.1.jar -> jdk.unsupported org.ehcache.impl.internal.concurrent.ConcurrentHashMap -> sun.misc.Unsafe JDK internal API (jdk.unsupported) org.ehcache.impl.internal.concurrent.ConcurrentHashMap$CounterCell -> sun.misc.Contended JDK internal API (JDK removed internal API) org.ehcache.impl.internal.concurrent.ConcurrentHashMap$TreeBin -> sun.misc.Unsafe JDK internal API (jdk.unsupported) org.ehcache.impl.internal.concurrent.ThreadLocalRandomUtil -> sun.misc.Unsafe JDK internal API (jdk.unsupported) org.ehcache.sizeof.impl.UnsafeSizeOf -> sun.misc.Unsafe JDK internal API (jdk.unsupported)

Warning: JDK internal APIs are unsupported and private to JDK implementation that are subject to be removed or changed incompatibly and could break your application. Please modify your code to eliminate dependence on any JDK internal APIs. For the most recent update on JDK internal API replacements, please check: https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool

JDK Internal API Suggested Replacement


sun.misc.Contended Removed. See http://openjdk.java.net/jeps/260 sun.misc.Unsafe See http://openjdk.java.net/jeps/260

chrisdennis commented 5 years ago

Contended is an annotation and so it isn't a hard requirement. We do have an explicit dependency on Unsafe at the moment, which would be problematic for anyone using Ehcache 3 in a modular environment. Long term the best solution for this would be MR-JAR with a Java 8 version of the heap store that uses Unsafe and a Java 9+ version that uses Var Handles. That's not hard to write... but I had been holding off on getting better tooling support for building, testing and maintaining Multi-Release JARs.

ptahchiev commented 5 years ago

So I tried the following configuration:

and I got the following exception:

Caused by: org.ehcache.spi.serialization.SerializerException: java.io.NotSerializableException: org.hibernate.metamodel.model.convert.internal.JpaAttributeConverterImpl
    at org.ehcache.impl.serialization.PlainJavaSerializer.serialize(PlainJavaSerializer.java:51)
    at org.ehcache.impl.copy.SerializingCopier.copy(SerializingCopier.java:60)
    at org.ehcache.impl.copy.ReadWriteCopier.copyForWrite(ReadWriteCopier.java:42)
    at org.ehcache.impl.internal.store.heap.holders.CopiedOnHeapKey.<init>(CopiedOnHeapKey.java:33)
    at org.ehcache.impl.internal.store.heap.KeyCopyBackend.makeKey(KeyCopyBackend.java:188)
    at org.ehcache.impl.internal.store.heap.KeyCopyBackend.compute(KeyCopyBackend.java:154)
    at org.ehcache.impl.internal.store.heap.OnHeapStore.put(OnHeapStore.java:337)
    ... 176 more
Caused by: java.io.NotSerializableException: org.hibernate.metamodel.model.convert.internal.JpaAttributeConverterImpl
    at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1185)
    at java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1553)
    at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1510)
    at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1433)
    at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1179)
    at java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1553)
    at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1510)
    at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1433)
    at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1179)
    at java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1553)
    at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1510)
    at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1433)
    at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1179)
    at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:349)
    at java.base/java.util.HashMap.internalWriteEntries(HashMap.java:1840)
    at java.base/java.util.HashMap.writeObject(HashMap.java:1411)
    at java.base/jdk.internal.reflect.GeneratedMethodAccessor441.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at java.base/java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1130)
    at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1497)
    at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1433)
    at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1179)
    at java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1553)
    at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1510)
    at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1433)
    at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1179)
    at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:349)
    at org.ehcache.impl.serialization.PlainJavaSerializer.serialize(PlainJavaSerializer.java:49)

when executing against this spring-data method:

    @Query("SELECT an FROM #{#entityName} an JOIN an.name n WHERE KEY(n) in (:locales) ORDER BY n.value")
    @QueryHints({ @QueryHint(name = "org.hibernate.cacheable", value = "true") })
    List<T> findAllOrderByNameWithLocales(@Param("locales") Locale... locales);
chrisdennis commented 5 years ago

I'm fairly certain this isn't a Java 11 issue (or if it is it's not an Ehcache one). It looks like you might have the cache configured as by-value. Without further configuration this means Ehcache is going to resort to a serialization based copying/detachment to enforce/ensure the by-value semantics. It looks however like the key in the query cache isn't serializable so things break. I'm fairly sure you'd see this in any/all Java versions.

All that said I'm happy to look at a reproducible test case if you can provide one.

Chris

P.S. You can also run the Ehcache 3 tests themselves against Java 11 (or any other JVM you choose) by executing ./gradlew test -PtestVM=<path to your test jvm>

hos-p commented 5 years ago

Contended is an annotation and so it isn't a hard requirement. We do have an explicit dependency on Unsafe at the moment, which would be problematic for anyone using Ehcache 3 in a modular environment. Long term the best solution for this would be MR-JAR with a Java 8 version of the heap store that uses Unsafe and a Java 9+ version that uses Var Handles. That's not hard to write... but I had been holding off on getting better tooling support for building, testing and maintaining Multi-Release JARs.

So I assume no java 11 support in following months by releasing multi-release jar,

chrisdennis commented 5 years ago

I've filed a feature request with Gradle for improved tooling support (gradle/gradle#10046). If that gets traction quickly then it's a possibility. While that is an open issue I'm hesitant to roll my own gradle MR-JAR solution. The only other option would be to prep the changes needed for the Java 9 heap map in a branch which could be compiled if someone needed (or rebased on top of a release tag - if they wanted a Java 9 compatible pseudo-release). For now things work in a non-modular Java 11 environment (actually my testing indicates it works in a non-modular Java 14 environment as of this moment).

ripunjDev commented 4 years ago

I am also facing similar issue with Ehcache 3.x version and getting below exception with JDk11. So any idea to fix this.

EXCEPTION STACK TRACE = Unable to make field private jdk.internal.reflect.ConstructorAccessorImpl jdk.internal.reflect.DelegatingConstructorAccessorImpl.delegate accessible: module java.base does not "opens jdk.internal.reflect" to unnamed module @1e6a3214

ERROR STACK TRACE = [java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:340), java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:280),

ripunjDev commented 4 years ago

But when I have replaced it with hazelcast it works fine.

chrisdennis commented 4 years ago

See my comment in the closing of that thread. There are no imminent plans for a modular Ehcache 3 or an MR-JAR based one. That said I don't know any reason that Ehcache 3 won't work when used in a non-modular Java 11 environment or when used as an 'automatic module' (beyond the fact that the byte-based sizing feature needs permissions to reflectively access all stored types).

linghengqian commented 2 years ago

I am very curious, does the situation mentioned in this issue still exist two years later?