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

"java.lang.AssertionError: java.lang.NoSuchFieldException: target" on s390x with Corda #6870

Open
rickcrook opened this issue Feb 12, 2021 · 5 comments

Comments

@rickcrook
Copy link
Contributor

duplicated from: eclipse-openj9/openj9#11957

Summary of problem

Exception raised java.lang.AssertionError: java.lang.NoSuchFieldException: target while running java -jar corda.jar

A quick scan of the internet shows this has been seen before puniverse/quasar#321 and been added to #5139.
Switching to Hotspot (as per one suggestion) yields a deeper issue see #11956 & adoptium/adoptium-support#257

  / ____/     _________/ /___ _
 / /     __  / ___/ __  / __ `/         If at first you don't succeed, 
/ /___  /_/ / /  / /_/ / /_/ /          then we have something in common!
\____/     /_/   \__,_/\__,_/

--- Corda Open Source 4.6 (85e387e) -------------------------------------------------------------

Steps to reproduce

running java -jar corda.jar in docker image adoptopenjdk/openjdk8:jdk8u275-b01 on s390x/LinuxOne
note: Official Corda docker images have not been compiled for s390x architecture

Symptoms

app.log

Analysis

Thanks to @joransiu for this.

From the app.log:

Caused by: java.lang.NoSuchFieldException: target
	at java.lang.Class.getDeclaredFieldImpl(Native Method) ~[?:1.8.0_275]
	at java.lang.Class.getDeclaredField(Class.java:825) ~[?:1.8.0_275]
	at co.paralleluniverse.common.reflection.GetDeclaredField.run(GetDeclaredField.java:17) ~[quasar-core-0.7.13_r3.jar:0.7.13_r3]
	at co.paralleluniverse.common.reflection.GetDeclaredField.run(GetDeclaredField.java:6) ~[quasar-core-0.7.13_r3.jar:0.7.13_r3]
	at java.security.AccessController.doPrivileged(AccessController.java:734) ~[?:1.8.0_275]
	at co.paralleluniverse.concurrent.util.ThreadAccess.<clinit>(ThreadAccess.java:53) ~[quasar-core-0.7.13_r3.jar:0.7.13_r3]

https://github.com/corda/quasar/blob/v0.7.13_r3/quasar-core/src/main/java/co/paralleluniverse/concurrent/util/ThreadAccess.java#L53

Given the getter/setters for this target field are Runnable type, the corresponding private field within OpenJ9 Thread implementation would be runnable (https://github.com/eclipse/openj9/blob/master/jcl/src/java.base/share/classes/java/lang/Thread.java#L96).

As private fields are usually not externalized, arguably, the issue lies in quasar code making an implementation-dependent assumption. FWIW, the other three fields that are queried do exist in our Thread implementation.

Solution

update the field name from target to runnable (alternatively, add another query for runnable if target is not found).

@pron already made the change to the R3 fork of the quasar code in Nov 2018 which made it into release-0.8.2_r3 but not v0.7.13_r3 (release 30 Jul 2020):
corda/quasar@25031be#diff-e236b21e9830dc9153172ac25b37aa2df6cc81e9ec201105a26c95bc50fbe7f7

Could we have this change made for JDK8 version of Corda and included in next Corda release.

@joransiu
Copy link

Looking at the referenced change above, the implementation was updated to use VarHandle [1]. However, it's still searching for a field named target. As such, I still expect a NoSuchFieldException to be thrown still with OpenJ9 JDK. Perhaps we can update to catch that exception, and requery with:

try {
    // Query Thread.target Runnable field from HotSpot implementation
    TARGET = l.findVarHandle(Thread.class, "target", Runnable.class); 
} catch (NoSuchFieldException e) {
    // Query Thread.runnable Runnable field from OpenJ9.
    TARGET = l.findVarHandle(Thread.class, "runnable", Runnable.class); 
}

While this code is a bit unpleasant, it is querying the internals (private field of Thread class in this case) that may vary across different implementations.

[1] corda/quasar@25031be#diff-e236b21e9830dc9153172ac25b37aa2df6cc81e9ec201105a26c95bc50fbe7f7R50

@joransiu
Copy link

Btw, VarHandles and MethodHandles.Lookup.findVarHandle API were introduced in Java 9. I expect the changes from corda/quasar@25031be are likely part of the migration towards Java 9+ support.

If we need a Java 8 compatible fix, we can make a similar change against the existing code: i.e. still use GetDeclaredField(..), but also query runnable field name as fallback:
https://github.com/corda/quasar/blob/v0.7.13_r3/quasar-core/src/main/java/co/paralleluniverse/concurrent/util/ThreadAccess.java#L53

@rickcrook
Copy link
Contributor Author

Solution 1: s390x support for Corda supported JVMs
https://docs.corda.net/docs/corda-enterprise/4.7/platform-support-matrix.html
These are the two supported JVMs for Corda - Oracle JDK 8 JVM 8u251 and Azul Zulu Enterprise 8u252,
I don't believe either are supported on s390x.
If I can install either on s390x architecture then we may be able to avoid a code change.

Solution 2: Corda support for s390x supported JVMs
I am using adoptopenjdk/openjdk8:jdk8u275-b01 image
The JVM in this image is supported on s390x arch but will required a Corda code change in quasar-core-0.7.13_r3.jar

@rickcrook
Copy link
Contributor Author

https://github.com/dazraf/quasar/tree/fix-for-ibm-jvm

@dazraf has fixed the reflection of the target field; this version is agnostic now to either the Oracle / OpenJDK and IBM JVMs; version number to 0.7.13_lab577 (which is essential to avoid the build attempting to pick up its internal dependencies from the local maven repo).

@nargas-ritu
Copy link
Contributor

Created CORDA-4193 for an internal review

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

No branches or pull requests

3 participants