I have a native application that launches a JVM and interacts with it through the JNI API. The native application constructs a (complex) JVM object and passes it as parameter in a method call. The problem is that in some cases, on determinate inputs, the JVM crashes during the execution of the method with:
Exception in thread "Thread-1" java.lang.IncompatibleClassChangeError
I learned that this exception is thrown by the JVM when some incompatible binary changes has been made to a class used by a client that is not aware of the changes. However, I don't see how this could happen: in my case the JVM has only one fat jar in the classpath. I can't find duplicate classes in it, and the client code is always compiled to produce the fat jar.
On "What causes java.lang.IncompatibleClassChangeError?" I found that there is another potential reason: a method called via JNI with objects of the wrong type, e.g. in the wrong order. So, I added dynamic checks with IsInstanceOf
to check the type of any object passed to the JVM. Unfortunately, all the checks succeed.
How can I debug this? The exception has no message (e.g. no message like "Expected non-static field ChildClass.message"). This may hint that it's a problem caused by the JNI, and not by the "more common" case of an incompatible binary change in a library.
I tried -verbose:class
but I don't see anything strange in the log. The last loaded class seems a common Scala lambda function, nothing strange:
[Loaded a.b.c.FastPrettyPrinter$$$Lambda$457/868352876 from a.b.c.FastPrettyPrinter$]
Is there an exhaustive list, or explanation, of what might cause an IncompatibleClassChangeError
when calling JVM methods via the JNI?