Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » Calling getObject On A Populated Part Returns null
Calling getObject On A Populated Part Returns null [message #922230] Mon, 24 September 2012 17:21 Go to next message
Rob Hatcherson is currently offline Rob Hatcherson
Messages: 27
Registered: July 2009
Location: Fort Worth, TX, USA
Junior Member
I have a part that's being created from a view descriptor loaded from a fragment e4xmi file. The part and its contained contribution are being created and are showing up and working as expected.

However... when I call getObject() on the part null is returned. I've tried this at various points ranging from just after part creation to later in a handler triggered by a button on the part's toolbar.

I have other parts that are also working fine, and where calling getObject() returns the contained instantiated contribution. I expected this would always be the case for populated parts.

Is it normal/expected that calling getObject() on a populated part will sometimes return null?
Re: Calling getObject On A Populated Part Returns null [message #922845 is a reply to message #922230] Tue, 25 September 2012 07:46 Go to previous messageGo to next message
Brian de Alwis is currently offline Brian de Alwis
Messages: 127
Registered: January 2012
Senior Member

Sounds like you don't have the right object -- perhaps you have something from the snippets or part descriptors?. Trace up the part's container chain and verify that you're getting the right part.
Re: Calling getObject On A Populated Part Returns null [message #923007 is a reply to message #922845] Tue, 25 September 2012 10:31 Go to previous messageGo to next message
Rob Hatcherson is currently offline Rob Hatcherson
Messages: 27
Registered: July 2009
Location: Fort Worth, TX, USA
Junior Member
Hi Brian,

Thanks for the reply. You wrote:

>> Sounds like you don't have the right object -- perhaps you have
>> something from the snippets or part descriptors?. Trace up the part's
>> container chain and verify that you're getting the right part.

Given my relative E4-noobness anything is possible Smile. I have aired at least one other careless user error on the forums, and this one might be another.

This part is being created from a view descriptor that's defined in a fragment e4xmi file. I'm creating the part from a utility class in a snippet that looks something like this:

    final EPartService partService = context.get( EPartService.class ) ;
    MPart part = partService.createPart( viewDescriptor ) ;
    ...some other stuff happens here...
    partService.activate( part ) ;

If I call part.getObject() just after activate() returns then I get null. I thought perhaps this is too early to ask for the object, so I added a button on the part's toolbar. The associated handler is similar to:

    @Execute
    public void execute( @Named(IServiceConstants.ACTIVE_PART) MPart part ) {
        System.err.println( ">>>> part label = " + part.getLabel() ) ;
        if( part.getObject() != null ) {
            System.err.println( "Part object class = " + part.getObject().getClass().getName() ) ;
        } else {
            System.err.println( "The part's object was null" ) ;
        }
    }

This also always says the object is null. The label that gets printed is the right one, and in this case this should be (and appears to be) the only such part in the window. Between the label being what I expect and the ACTIVE_PART annotation on the argument, I expect this is the part I'm looking at in the on-screen window.

On your advice I stopped in this handler in the debugger and looked at part.getParent().getParent()... (seemed easier than rooting through the data structures where I'm not quite sure what I'm looking at yet), and I see something like Part->PartSashContainer->Perspective->PerspectiveStack->TrimmedWindow, so I'm pretty sure it's the real part - or at least it's "a" real part, but it also appears to be the right one.

This may have nothing to do with it, but this is the only part in our nascent system that's being created from a view descriptor (because it happens to be the only one with a toolbar currently, and this was easier to create in the model editor). The other parts are created like this:

    MPart part = MBasicFactory.INSTANCE.createPart() ;
    part.setCloseable( true ) ;
    part.setToBeRendered( true ) ;
    part.setVisible( true ) ;
    part.setContributionURI( whateverItIs ) ;
    ...some other stuff happens here...
    partService.activate( part ) ;

For these I can call part.getObject() just after activate() returns and I get a non-null object of the expected type. The part created via the view descriptor and the part created by the code snippet immediately above ultimately end up at the same partService.activate(); the primary difference is that one is created from a view descriptor, and one is created through MBasicFactory.INSTANCE.createPart().


Is it safe to say that at no time should an instantiated and populated on-screen part return null from getObject()? I would not expect this, but sometimes large and complex frameworks have little corner cases that do surprising things.
Re: Calling getObject On A Populated Part Returns null [message #923043 is a reply to message #923007] Tue, 25 September 2012 11:03 Go to previous messageGo to next message
Sopot Cela is currently offline Sopot Cela
Messages: 589
Registered: December 2010
Senior Member

The setObject is called in the ContributedStackRenderer. This means that it has to go through the renderer. I'm making a wild guess that it does not. Have you tried showPart(part,Active[or VISIBLE]) instead of the activation?
Re: Calling getObject On A Populated Part Returns null [message #923104 is a reply to message #923043] Tue, 25 September 2012 11:51 Go to previous message
Rob Hatcherson is currently offline Rob Hatcherson
Messages: 27
Registered: July 2009
Location: Fort Worth, TX, USA
Junior Member
Hi Sopot. You wrote:

>> The setObject is called in the ContributedStackRenderer.
>> This means that it has to go through the renderer. I'm
>> making a wild guess that it does not. Have you tried
>> showPart(part,Active[or VISIBLE]) instead of the activation?

Your comment made me realize that I hadn't tried the painfully obvious approach yet of setting a breakpoint in MPartImpl's setObject method and doing some stack examination. Just a little more poking around after doing that and I found the problem:

The setObject call was in fact being made from ContributedPartRenderer, but the object being passed in was null. Hmmmmm...

I looked a little further back in the stack trace and was reminded that we have a custom contribution factory in the loop that lets us mention plain class names as contribution URIs. The view being created was throwing a NullPointerException that was unfortunately being swallowed by this custom contribution factory. Fixing the originating exception - and of course fixing the custom contribution factory to not swallow the exception :-/ - has cleared up the issue.

Both partService.showPart... and partService.activate... now have the desired effect.

The part I'm less clear on is what Magic allowed the part contribution to go ahead and show up anyway despite the exception. The contribution had already been instantiated, and the exception occurred in a @PostConstruct method. So... perhaps the contribution already existed in some half-constructed state somewhere and was allowed to survive and be used anyway.

Sopot and Brian: gentlemen, thanks for the constructive input.
Previous Topic:Juno build trouble
Next Topic:How to forestall the window closing
Goto Forum:
  


Current Time: Sat Apr 19 09:04:04 EDT 2014

Powered by FUDForum. Page generated in 0.01727 seconds