Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 546159 - NullPointerException when adding items to Mac OS native toolbar with Java 11
Summary: NullPointerException when adding items to Mac OS native toolbar with Java 11
Status: VERIFIED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.10   Edit
Hardware: PC Mac OS X
: P3 normal (vote)
Target Milestone: 4.13 M1   Edit
Assignee: Lakshmi P Shanmugam CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-04-05 10:59 EDT by Andreu B CLA
Modified: 2019-07-15 02:11 EDT (History)
4 users (show)

See Also:


Attachments
Snippet (879 bytes, application/octet-stream)
2019-05-29 08:26 EDT, Lakshmi P Shanmugam CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andreu B CLA 2019-04-05 10:59:46 EDT
The code below creates a shell and adds a ToolItem to Mac's native toolbar (the one that is visually integrated with the title bar, as described in #222859)




import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;

public class App {

    public static void main(String[] args) {

        Display display = new Display();
        Shell shell = new Shell();

        ToolBar toolBar = shell.getShell().getToolBar();

        if (null != toolBar) {
            ToolItem toolItem = new ToolItem(toolBar, SWT.NONE);
            toolItem.setText("Some text");
        }

        shell.pack();
        shell.open();

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }

        display.dispose();

    }
}



This works correctly when run in Mac OS 10.13, SWT 4.10 and Java 1.8.0_181 (same JVM for compiling and running). However, the same snippet, with Java 11.0.2, results in the following exception. I have not tried other Java versions yet, nor compiling and running with different JVMs.



Exception in thread "main" java.lang.NullPointerException
	at org.eclipse.swt.widgets.Scrollable.getClientArea(Scrollable.java:206)
	at org.eclipse.swt.widgets.ToolBar.relayout(ToolBar.java:653)
	at org.eclipse.swt.widgets.ToolBar.createItem(ToolBar.java:289)
	at org.eclipse.swt.widgets.ToolItem.<init>(ToolItem.java:98)
	at t3.App.main(App.java:19)


Debugging shows that in the failing run (Java 11), the toolBar's field "view" never gets assigned in ToolBar.createHandle(), while it does get assigned in the working run (Java 8)
Comment 1 Andreu B CLA 2019-04-05 13:07:13 EDT
It works well up to Java 10. Only Java 11 makes it fail.
Comment 2 Niraj Modi CLA 2019-04-08 03:17:47 EDT
(In reply to Andreu B from comment #0)
> This works correctly when run in Mac OS 10.13, SWT 4.10 and Java 1.8.0_181
> (same JVM for compiling and running). However, the same snippet, with Java
> 11.0.2, results in the following exception. I have not tried other Java
> versions yet, nor compiling and running with different JVMs.

Did you try with latest Eclipse/SWT 4.11 with Java11 combination:
https://download.eclipse.org/eclipse/downloads/drops4/R-4.11-201903070500/
Comment 3 Andreu B CLA 2019-04-08 06:23:50 EDT
Sorry for not testing latest version.

I can reproduce too with Java 11 and SWT 4.11.
Comment 4 Lakshmi P Shanmugam CLA 2019-04-19 07:43:21 EDT
I can reproduce this on Java 11. 
The problem is in ToolBar.java:249. When running with Java 11, class name is NSTitlebarContainerView instead of the expected NSToolbarView.
Comment 5 Matthias Fuchs CLA 2019-05-23 06:42:52 EDT
@Niraj Modi:
This is still valid for for SWT 4.11!

Btw why is the SWT maven version for 4.11 defined as 3.110.0?
> https://mvnrepository.com/artifact/org.eclipse.platform/org.eclipse.swt/3.110.0

The contents on the jar match the manual download you posted!

Maven SWT seems to be non-working in general (version mismatches) ...
Comment 6 Matthias Fuchs CLA 2019-05-23 13:17:33 EDT
I "fixed" it with this code:

// this fixes a nullpointer exception because unfortunately the Toolbar
// class searches for a NSToolbar instance and won't find one, because
// it finds a NSTitlebarContainerView instead
// so we fake a unified toolbar (kinda ...)
NSView widget = (NSView) new SWTView().alloc();
widget.init();
toolbar.view = widget;

NSView subWidget = (NSView) new SWTView().alloc();
subWidget.init();
widget.addSubview(subWidget);

Run this before you add any toolbar items!
Comment 7 Eclipse Genie CLA 2019-05-29 08:19:14 EDT
New Gerrit change created: https://git.eclipse.org/r/143015
Comment 8 Lakshmi P Shanmugam CLA 2019-05-29 08:22:01 EDT
(In reply to Matthias Fuchs from comment #6)
> I "fixed" it with this code:
> 
> // this fixes a nullpointer exception because unfortunately the Toolbar
> // class searches for a NSToolbar instance and won't find one, because
> // it finds a NSTitlebarContainerView instead
> // so we fake a unified toolbar (kinda ...)
> NSView widget = (NSView) new SWTView().alloc();
> widget.init();
> toolbar.view = widget;
> 
> NSView subWidget = (NSView) new SWTView().alloc();
> subWidget.init();
> widget.addSubview(subWidget);
> 
> Run this before you add any toolbar items!
Do the ToolItems also appear correctly with this fix?
Where did you add this code, can you please provide a Gerrit patch so that we can try it out?
Comment 9 Lakshmi P Shanmugam CLA 2019-05-29 08:24:28 EDT
(In reply to Eclipse Genie from comment #7)
> New Gerrit change created: https://git.eclipse.org/r/143015

This patch fixes the NPEs and ToolItems also seem to appear correctly. But, I get this warning when running the attached snippet. Interestingly this warning doesn't appear if the ToolItem has an image.

java[677:14683] It's not legal to call -layoutSubtreeIfNeeded on a view which is already being laid out.  If you are implementing the view's -layout method, you can call -[super layout] instead. Break on void _NSDetectedLayoutRecursion(void) to debug.  This will be logged only once.  This may break in the future.
Comment 10 Lakshmi P Shanmugam CLA 2019-05-29 08:26:24 EDT
Created attachment 278768 [details]
Snippet
Comment 11 Lakshmi P Shanmugam CLA 2019-05-29 08:28:50 EDT
(In reply to Lakshmi Shanmugam from comment #9)
> (In reply to Eclipse Genie from comment #7)
> > New Gerrit change created: https://git.eclipse.org/r/143015
> 
> This patch fixes the NPEs and ToolItems also seem to appear correctly. But,
> I get this warning when running the attached snippet. Interestingly this
> warning doesn't appear if the ToolItem has an image.
> 
> java[677:14683] It's not legal to call -layoutSubtreeIfNeeded on a view
> which is already being laid out.  If you are implementing the view's -layout
> method, you can call -[super layout] instead. Break on void
> _NSDetectedLayoutRecursion(void) to debug.  This will be logged only once. 
> This may break in the future.

@Till, do you have any idea why I get this warning?
Comment 12 Lakshmi P Shanmugam CLA 2019-06-04 05:15:57 EDT
Moving to 4.13 as the warning in the patch is not resolved yet.
Comment 13 Till Brychcy CLA 2019-06-25 13:59:34 EDT
(In reply to Lakshmi Shanmugam from comment #11)
> @Till, do you have any idea why I get this warning?

Sorry, didn't have time to look at this earlier.

I've set a breakpoint in _NSDetectedLayoutRecursion as suggested, and here is the stack trace leading to it:

 frame #0: 0x00007fff347fbfac AppKit`_NSDetectedLayoutRecursion
    frame #1: 0x00007fff3401d548 AppKit`-[NSWindow(NSConstraintBasedLayout) _layoutViewTree] + 148
    frame #2: 0x00007fff3400b741 AppKit`-[NSWindow _setFrame:updateBorderViewSize:] + 973
    frame #3: 0x00007fff3400b05a AppKit`-[NSWindow _oldPlaceWindow:] + 519
    frame #4: 0x00007fff3400a61f AppKit`-[NSWindow _setFrameCommon:display:stashSize:] + 2814
    frame #5: 0x00007fff34009b0e AppKit`-[NSWindow _setFrame:display:allowImplicitAnimation:stashSize:] + 192
    frame #6: 0x00007fff34009a47 AppKit`-[NSWindow setFrame:display:] + 51
    frame #7: 0x00007fff34014139 AppKit`-[NSWindow setFrame:display:animate:] + 130
    frame #8: 0x00007fff3414e3b1 AppKit`-[NSThemeFrame _growWindowReshapeContentAndToolbarView:withOldToolbarFrameSize:animate:] + 1371
    frame #9: 0x00007fff3414dd5d AppKit`-[NSThemeFrame _reshapeContentAndToolbarView:withOldToolbarFrameSize:resizeWindow:animate:] + 543
    frame #10: 0x00007fff34148cd7 AppKit`-[NSThemeFrame _toolbarFrameSizeChanged:oldSize:] + 63
    frame #11: 0x00007fff34148c3d AppKit`-[NSWindow _toolbarFrameSizeChanged:oldSize:] + 93
    frame #12: 0x00007fff34141aa5 AppKit`-[NSToolbarView _layoutDirtyItemViewersAndTileToolbar] + 3069
    frame #13: 0x00007fff3414ea39 AppKit`-[NSToolbarView layout] + 66
    frame #14: 0x00007fff340209a7 AppKit`_NSViewLayout + 587
    frame #15: 0x00007fff34020324 AppKit`-[NSView _layoutSubtreeWithOldSize:] + 452
    frame #16: 0x00007fff340205a5 AppKit`-[NSView _layoutSubtreeWithOldSize:] + 1093
    frame #17: 0x00007fff3401ddc4 AppKit`-[NSView _layoutSubtreeIfNeededAndAllowTemporaryEngine:] + 1358
    frame #18: 0x00007fff3401d548 AppKit`-[NSWindow(NSConstraintBasedLayout) _layoutViewTree] + 148
    frame #19: 0x00007fff3400b741 AppKit`-[NSWindow _setFrame:updateBorderViewSize:] + 973
    frame #20: 0x00007fff3400b05a AppKit`-[NSWindow _oldPlaceWindow:] + 519
    frame #21: 0x00007fff3400a61f AppKit`-[NSWindow _setFrameCommon:display:stashSize:] + 2814
    frame #22: 0x00007fff34009b0e AppKit`-[NSWindow _setFrame:display:allowImplicitAnimation:stashSize:] + 192
    frame #23: 0x00007fff34009a47 AppKit`-[NSWindow setFrame:display:] + 51
    frame #24: 0x000000010cc7b1aa libswt-pi-cocoa-4928r7.jnilib`Java_org_eclipse_swt_internal_cocoa_OS_objc_1msgSend__JJLorg_eclipse_swt_internal_cocoa_NSRect_2Z + 186
    frame #25: 0x000000010df15a88
    frame #26: 0x000000010defce70
    frame #27: 0x000000010defd35d
    frame #28: 0x000000010defd35d
    frame #29: 0x000000010defd35d
    frame #30: 0x000000010defd35d
    frame #31: 0x000000010defd35d
    frame #32: 0x000000010def57a7
    frame #33: 0x00000001084ef6ce libjvm.dylib`JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*) + 1710
    frame #34: 0x0000000108526565 libjvm.dylib`jni_invoke_static(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*) + 447
    frame #35: 0x000000010851f2f1 libjvm.dylib`jni_CallStaticVoidMethod + 349
    frame #36: 0x00000001069738ca java`JavaMain + 2500
    frame #37: 0x00000001069757f2 java`__JVMInit_block_invoke_1 + 81
    frame #38: 0x00007fff38b4455c Foundation`__NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 7
    frame #39: 0x00007fff38b44464 Foundation`-[NSBlockOperation main] + 68
    frame #40: 0x00007fff38b1a1dd Foundation`-[__NSOperationInternal _start:] + 685
    frame #41: 0x00007fff38b9e7f2 Foundation`__NSThreadPerformPerform + 328
    frame #42: 0x00007fff368c4083 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #43: 0x00007fff368c4029 CoreFoundation`__CFRunLoopDoSource0 + 108
    frame #44: 0x00007fff368a79eb CoreFoundation`__CFRunLoopDoSources0 + 195
    frame #45: 0x00007fff368a6fb5 CoreFoundation`__CFRunLoopRun + 1189
    frame #46: 0x00007fff368a68be CoreFoundation`CFRunLoopRunSpecific + 455
    frame #47: 0x0000000106976472 java`CreateExecutionEnvironment + 871
    frame #48: 0x000000010697207c java`JLI_Launch + 1952
    frame #49: 0x00000001069784cf java`main + 101
    frame #50: 0x00000001069718d4 java`start + 52

Where the java stacktrace calling NSWindow setFrame:display: is:

org.eclipse.swt.widgets.Shell.setBounds(int, int, int, int, boolean, boolean) line: 1689	
org.eclipse.swt.widgets.Shell(org.eclipse.swt.widgets.Control).setSize(org.eclipse.swt.graphics.Point) line: 4285	
org.eclipse.swt.widgets.Shell(org.eclipse.swt.widgets.Control).pack(boolean) line: 2791	
org.eclipse.swt.widgets.Shell(org.eclipse.swt.widgets.Control).pack() line: 2765	
org.eclipse.swt.snippets.Bug546159SkinnedToolbar.main(java.lang.String[]) line: 19
Comment 14 Till Brychcy CLA 2019-06-25 14:01:12 EDT
But actually, I see the same error message also without the patch when running with java 8, so I think the patch can be merged as is.
Comment 15 Till Brychcy CLA 2019-06-25 15:20:57 EDT
(In reply to Lakshmi Shanmugam from comment #9)
> This patch fixes the NPEs and ToolItems also seem to appear correctly. But,
> I get this warning when running the attached snippet. Interestingly this
> warning doesn't appear if the ToolItem has an image.

Hmmm - I also get the warning if the item has an image or even if I add the item, but set neither text nor image.
Comment 17 Lakshmi P Shanmugam CLA 2019-06-26 07:05:13 EDT
(In reply to Till Brychcy from comment #13)
Thanks for looking into this and providing the stack trace, it's very useful. May be the Toolbar layout code needs some refactoring. Will investigate further.
Comment 18 Lakshmi P Shanmugam CLA 2019-07-01 05:23:10 EDT
(In reply to Lakshmi Shanmugam from comment #17)
> (In reply to Till Brychcy from comment #13)
> Thanks for looking into this and providing the stack trace, it's very
> useful. May be the Toolbar layout code needs some refactoring. Will
> investigate further.
The ToolBar.layoutUnified() code doesn't seem to return the correct width based on the ToolItems, the code needs refactoring. Opened Bug 548821 to track this.
Comment 19 Lakshmi P Shanmugam CLA 2019-07-01 05:24:41 EDT
The NPE when using Shell unified toolbar is fixed.
Comment 20 Lakshmi P Shanmugam CLA 2019-07-15 02:11:10 EDT
Verified with build I20190711-1805.