Bug 400581 - @Inject method called with null argument even if method is annotated with @Optional
Summary: @Inject method called with null argument even if method is annotated with @Op...
Status: RESOLVED INVALID
Alias: None
Product: Platform
Classification: Eclipse Project
Component: Runtime (show other bugs)
Version: 4.2.1   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: platform-runtime-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-02-12 09:38 EST by Joachim Fuchs CLA
Modified: 2015-05-26 06:31 EDT (History)
11 users (show)

See Also:


Attachments
snippet from a view to test @Optional's startup behaviour (490 bytes, application/octet-stream)
2013-02-19 16:12 EST, Joachim Fuchs CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Joachim Fuchs CLA 2013-02-12 09:38:07 EST
Hi,

using Eclipse 4.2.1 I observed the following:

@Inject
@Optional
public void myMethod(@Named(IServiceConstants.ACTIVE_SELECTION)MyObject o) {
}

The method gets called at application startup. There is no MyObject instance loaded or displayed. As far as I unterstand the @Optional annotation at method level the method should not be called. 

The same code without the @Named annotation works as expected.

Cheers
 Joachim
Comment 1 Sven Klemm CLA 2013-02-12 10:56:02 EST
Hi,

my problem is similar to the one of joachim:

having a method annotated like this:

 	@Inject
	public void setTodo(@Optional @Named(IServiceConstants.ACTIVE_SELECTION) MyObject o) {
	}

it is called twice - i expected it is called only once through application startup.

If the @Named is ommitted than it is called only once, but @Name should do only the "address stuff".

Maybe my test or opion is wrong?

Thanks
Sven
Comment 2 Lars Vogel CLA 2013-02-15 01:47:51 EST
@Paul, maybe some hints for potential contributors where to look would be helpful?
Comment 3 Paul Webster CLA 2013-02-15 16:15:38 EST
First check, is it just active selection, or does it happen with any @Named constant?

PW
Comment 4 Joachim Fuchs CLA 2013-02-19 16:12:38 EST
Created attachment 227293 [details]
snippet from a view to test @Optional's startup behaviour
Comment 5 Joachim Fuchs CLA 2013-02-19 16:13:27 EST
(In reply to comment #3)
> First check, is it just active selection, or does it happen with any @Named
> constant?
Well, I tried ACTIVE_SELECTION, ACTIVE_PART and ACTIVE_SHELL and they all are passed as null with @PostContextCreate. 

The ACTIVE_PART is being passed 3 times as null before being an object reference:

F expecting the active shell Shell {}
G expecting the active part  null
unexpected E inject optional method selection null
G expecting the active part  null
F expecting the active shell Shell {}
G expecting the active part  null
F expecting the active shell Shell {}
G expecting the active part  org...
F expecting the active shell Shell {}
G expecting the active part  org...
F expecting the active shell Shell {}

(see code attachement above)
Comment 6 Brian de Alwis CLA 2014-04-29 17:13:49 EDT
@Optional on a method means: if the key cannot be resolved, the injection should be skipped rather than raise an InjectionException.

null is an acceptable value to be set in the context, and it is different from a key being removed from the context.  i.e.,

    context.set(SOMEKEY, null);

means anybody listening for SOMEKEY will be injected with null.

If you look through the code, there are a number of places where the ACTIVE_SELECTION is explicitly set to null, such as when there is no active part and hence no active selection.  If you weren't injected with null, you'd have no way to know that the active selection changed to nothing.  null is the equivalent of an empty IStructuredSelection in the 3.x selection model.
Comment 7 Lars Vogel CLA 2015-05-26 06:31:48 EDT
(In reply to Brian de Alwis from comment #6)
> @Optional on a method means: if the key cannot be resolved, the injection
> should be skipped rather than raise an InjectionException.
> 
> null is an acceptable value to be set in the context, and it is different
> from a key being removed from the context.  i.e.,
> 
>     context.set(SOMEKEY, null);
> 
> means anybody listening for SOMEKEY will be injected with null.

Maybe we should add this to the Javadoc of @Optional? Opened Bug 468291 for this.