rocksdb icon indicating copy to clipboard operation
rocksdb copied to clipboard

Refactor AbstractEventListener to cache Class instance in JNI code

Open rhubner opened this issue 1 year ago • 1 comments

Problem:

NoClassDefFoundError thrown from JNI code when EventListener is setup.

Condition to replicate :

RocksDB jar must be loaded with a custom class loader, for example Web container, Spring boot, …

Cause:

Limitation of java class loader in JNI API. JNI code is able to load classes from the same custom class loader only when the call to JNI was initiated from Java and from class loaded with the same class loader. Unfortunately in the callback, the call is initiated by RocksDB and then we attach to the existing JVM. In this situation, limitation of FindClass method takes place and JVM is able to only load classes which are specified on start of JVM.

Solution:

To overcome this limitation, in EventListenerJniCallback constructor JNI code, we load all instances of java.lang.Class required later by the callback and make them global references. Because in this phase, JNI code is called from Java, JVM knows where to look for these classes. Then later we are able to create instances of these classes, even when the JNI code wasn’t initiated from Java code and the current thread was attached to JVM.

This PR fix #10686

rhubner avatar Jul 08 '24 07:07 rhubner

LGTM now. Happy for you to un-draft it.

alanpaxton avatar Jul 31 '24 10:07 alanpaxton