-
Bug
-
Resolution: Unresolved
-
P4
-
11, 16, 17
This was found initially by a combination of PopupStressTest.java and -Xcheck:jni
because the exception is completely swallowed somewhere in native.
It is a problem in JDK 16 as well as JDK 17.
Tracking it down took some extra some instrumentation because the only information was
"WARNING in native method: JNI call made with exception pending"
I suspect this lack of information is what happens when we call into Java from
a thread which otherwise has no Java code on the stack - ie the AppKit thread ?
I then tracked this down using the new JNF replacement code where I was able to insert
(*env)->ExceptionDescribe() and got
Exception in thread "AppKit Thread" java.lang.NullPointerException: Cannot invoke "sun.lwawt.LWComponentPeer.getBounds()" because "cp" is null
at java.desktop/sun.lwawt.LWComponentPeer.windowToLocal(LWComponentPeer.java:1334)
at java.desktop/sun.lwawt.LWComponentPeer.windowToLocal(LWComponentPeer.java:1328)
at java.desktop/sun.lwawt.LWWindowPeer.notifyMouseEvent(LWWindowPeer.java:926)
at java.desktop/sun.lwawt.macosx.CPlatformResponder.handleMouseEvent(CPlatformResponder.java:84)
at java.desktop/sun.lwawt.macosx.CPlatformView.deliverMouseEvent(CPlatformView.java:182)
Using this you can confirm the same at the Java level
at java.base/java.lang.Thread.dumpStack(Thread.java:1377)
at java.desktop/sun.lwawt.LWComponentPeer.windowToLocal(LWComponentPeer.java:1337)
at java.desktop/sun.lwawt.LWComponentPeer.windowToLocal(LWComponentPeer.java:1328)
at java.desktop/sun.lwawt.LWWindowPeer.notifyMouseEvent(LWWindowPeer.java:926)
at java.desktop/sun.lwawt.macosx.CPlatformResponder.handleMouseEvent(CPlatformResponder.java:84)
at java.desktop/sun.lwawt.macosx.CPlatformView.deliverMouseEvent(CPlatformView.java:182)
The problem is this code in LWComponentPeer.java :
public Point windowToLocal(Point p, LWWindowPeer wp) {
LWComponentPeer<?, ?> cp = this;
while (cp != wp ) {
Rectangle cpb = cp.getBounds();
p.x -= cpb.x;
p.y -= cpb.y;
cp = cp.getContainerPeer();
}
The problem is that you can get "null" returned from getContainerPeer() and this is then de-referenced
when you re-enter the loop.
This gets thrown back to native.
I don't know for sure if this should never have returned null but I suspect it can happen if the peer is disposed()
and so a check for null is warranted.
One thing I don't understand right now is that JNI warning that kicked this off.
I have been given to understand that JNFCall* methods do something along the lines of
wrap the exception object in an NSException, then the clear Java exception and throw the NSException
which would then result in some useful debugging information.
But (a) there's no such debugging info, (b) there's that JNI warning.
So it is more like *nothing* is done and the code carries on.
I strongly suspect that at least for the JNI exception warning that the problem lies *inside* the JNF framework
since if I check after the return from JNFCall* there's no pending exception.
i.e. in the process of doing whatever it is doing it fails to follow the rules.
That doesn't explain why the exception is then completely swallowed with no information at all when
supposedly it does something "useful".
If in the appkit case it ever does raise an NSException and we catch that somewhere in the run loop
I don't see where we'd log anything useful to know where it came from.