Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » [E4] Preference annotation and the e4 dependency injection architecture
[E4] Preference annotation and the e4 dependency injection architecture [message #538597] Tue, 08 June 2010 07:55 Go to next message
Stephane Begaudeau is currently offline Stephane BegaudeauFriend
Messages: 458
Registered: April 2010
Location: Nantes (France)
Senior Member

I have two very different questions :

1- despite several attempts, I didn't succeed in making the @Preference annotation work and I can't find a complete example to understand how to use it, and the wiki is not helping (http://wiki.eclipse.org/E4/EAS/Preferences). I know how you are supposed to use it thanks to this example : http://tomsondev.bestsolution.at/2010/05/17/a-week-at-e4-sha re-me-please/

But I didn't succeed in storing a value in the preference store and then getting it back thanks to the annotation even if I'm convinced that it's very easy and I'm just missing something. So do you have a simple example for storing a data in the preference store and then getting it back with @Preference ?


2- I have a question on the behavior of your dependency injection architecture. I have created a class, representing a view, similar to this :

public class Test {
@Inject
public Test(Composite parent) { /* do nothing */ }

@Inject
public void doSomething(@Optional @Named("selection") IFile file) { /* do nothing */}
}

When my class is loaded both the constructor and the method are called due to the @Inject annotation. Latter while using my application if I select an IFile my "doSomething" method is called, it works as expected.

So I was wondering, how the dependency injection system knows that it has to call my method.

I know that, for the event system, the event broker is using the event admin system from Equinox, and I know thanks to the" OSGI and Equinox" book (page 257) that OSGI register the listener of an event in its service registry, thanks to this message ( http://www.eclipse.org/forums/index.php?t=msg&th=167787& amp;start=0&) I know that it can happen only with the @Inject annotation on the method that need to be called.

So my theory is that when my object is created, the dependency injection engine sees the @Inject annotation and "tells" OSGI to register my method as "a service that need to be called when the selection changes". And when the selection changes, the platform tells OSGI "if you have a service that need to be called, do it". Am I right ? Is that the same for @Execute or @CanExecute ? If not, how does the dependency injection engine know how to call my method ?
Re: [E4] Preference annotation and the e4 dependency injection architecture [message #538660 is a reply to message #538597] Tue, 08 June 2010 11:04 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
Am 08.06.10 09:55, schrieb Stephane Begaudeau:
> I have two very different questions :
>
> 1- despite several attempts, I didn't succeed in making the @Preference
> annotation work and I can't find a complete example to understand how to
> use it, and the wiki is not helping
> (http://wiki.eclipse.org/E4/EAS/Preferences). I know how you are
> supposed to use it thanks to this example :
> http://tomsondev.bestsolution.at/2010/05/17/a-week-at-e4-sha re-me-please/
>

If it is not working as advertised this is a bug and needs to be fixed.
I'll try to add it to one of my demos to see whether it works or not.

> But I didn't succeed in storing a value in the preference store and then
> getting it back thanks to the annotation even if I'm convinced that it's
> very easy and I'm just missing something. So do you have a simple
> example for storing a data in the preference store and then getting it
> back with @Preference ?
>
>
> 2- I have a question on the behavior of your dependency injection
> architecture. I have created a class, representing a view, similar to
> this :
>
> public class Test {
> @Inject
> public Test(Composite parent) { /* do nothing */ }
>
> @Inject
> public void doSomething(@Optional @Named("selection") IFile file) { /*
> do nothing */}
> }
>
> When my class is loaded both the constructor and the method are called
> due to the @Inject annotation. Latter while using my application if I
> select an IFile my "doSomething" method is called, it works as expected.
> So I was wondering, how the dependency injection system knows that it
> has to call my method.
>
> I know that, for the event system, the event broker is using the event
> admin system from Equinox, and I know thanks to the" OSGI and Equinox"
> book (page 257) that OSGI register the listener of an event in its
> service registry, thanks to this message
> ( http://www.eclipse.org/forums/index.php?t=msg&th=167787& amp;start=0&) I
> know that it can happen only with the @Inject annotation on the method
> that need to be called.
>
> So my theory is that when my object is created, the dependency injection
> engine sees the @Inject annotation and "tells" OSGI to register my
> method as "a service that need to be called when the selection changes".
> And when the selection changes, the platform tells OSGI "if you have a
> service that need to be called, do it". Am I right ? Is that the same
> for @Execute or @CanExecute ? If not, how does the dependency injection
> engine know how to call my method ?
>

No the DI-Container remembers in a locale context (IEclipseContext) -
you can compare it to a Hierarchical-HashMap - which values it has
injected into your instance and whenever this value changes it reinjects
the value.

@Execute and @CanExecute are a bit different because that's not really
injection what's happening there.

The command-framework does something similar. When the instance is
created it looks for @CanExecute and calls it with parameters in the
context and remember which values it used because they could lead to an
activation state change - now whenever one of the keys (the fully
qualified classname, the value in @Named()) changes it recalls this method.

The execute-method is only triggered by the Command-Framework wants to
execute the command and then determines the values that need to be
passed in.

Tom
Re: [E4] Preference annotation and the e4 dependency injection architecture [message #538686 is a reply to message #538660] Tue, 08 June 2010 12:20 Go to previous messageGo to next message
Paul Webster is currently offline Paul WebsterFriend
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Tom Schindl wrote:
> No the DI-Container remembers in a locale context (IEclipseContext) -
> you can compare it to a Hierarchical-HashMap - which values it has
> injected into your instance and whenever this value changes it reinjects
> the value.
>
> @Execute and @CanExecute are a bit different because that's not really
> injection what's happening there.
>
> The command-framework does something similar. When the instance is
> created it looks for @CanExecute and calls it with parameters in the
> context and remember which values it used because they could lead to an
> activation state change - now whenever one of the keys (the fully
> qualified classname, the value in @Named()) changes it recalls this method.
>
> The execute-method is only triggered by the Command-Framework wants to
> execute the command and then determines the values that need to be
> passed in.


Just a clarification. @Inject sets up what we call a RunAndTrack.
Every access to an IEclipseContext variable (like @Named("selection"))
is recorded in internal structures. When you set a variable on an
IEclipseContext fires and event and every RunAndTrack that accessed that
variable is re-run (causing your doSomething(*) method to be invoked again.

@CanExecute/@Execute/@Persist/@Focus are annotations that the framework
uses when it needs to call a method on client code. So rather than
implementing IHandler, you can provide an object with annotated methods
@CanExecute or @Execute. They use the same mechanism to turn
IEclipseContext variables into parameters for the method, but no RAT is
associated with them so they do not respond to variable changes.

PW


--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Re: [E4] Preference annotation and the e4 dependency injection architecture [message #539616 is a reply to message #538686] Fri, 11 June 2010 14:03 Go to previous messageGo to next message
Artur Kronenberg is currently offline Artur KronenbergFriend
Messages: 159
Registered: August 2009
Senior Member
Hi,

how exactly do we use the @Preferences annotation?

I have a method that is supposed to get called when a preference is changed that looks like this:

@Inject
	public void keyChanged(@Preference(value="myKey") final String value){
		System.out.println(value);
	}


This method is called when starting my application. At that point the value is null cause the preference hasn't been changed yet.

later in my application, the value is changed like this:
Preferences node = new DefaultScope().getNode("preferenceid");
						node.put("myKey", "NewValue");
						


My annotated method however isn't called after this.

If I debug the put method it runs into a firePreferenceChanged method. This method however checks if listeners are registered. Since my annotation doesn't require explicit registering as a listener the listeners in the preferences class is empty and there is no event fired.

Do I have to change my preference node in a different way in order to make the annotation above working?

Kind regards,
Artur
Re: [E4] Preference annotation and the e4 dependency injection architecture [message #540113 is a reply to message #539616] Tue, 15 June 2010 00:38 Go to previous messageGo to next message
Paul Webster is currently offline Paul WebsterFriend
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Which build are you using? I know we changed some of the @Preference
code recently:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=316375
https://bugs.eclipse.org/bugs/show_bug.cgi?id=316361

Possibly some other areas.

PW



--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Re: [E4] Preference annotation and the e4 dependency injection architecture [message #541132 is a reply to message #540113] Fri, 18 June 2010 12:54 Go to previous messageGo to next message
Artur Kronenberg is currently offline Artur KronenbergFriend
Messages: 159
Registered: August 2009
Senior Member
Hi,

I checked out the required bundles form CVS Head.
It doesn't seem to be either one of those bugs.

My method with the Inject is still just called when starting up my application. Later, when changing the preference Node, my method is not called again.

Is the way I am using the preference annotation right?

You seem to have changed the API recently since I get a discouraged access in my code when I updated the e4 bundles today. Do I use the API differently now?

Kind regards,
Artur
Re: [E4] Preference annotation and the e4 dependency injection architecture [message #541145 is a reply to message #541132] Fri, 18 June 2010 13:05 Go to previous messageGo to next message
Paul Webster is currently offline Paul WebsterFriend
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Artur Kronenberg wrote:
> Is the way I am using the preference annotation right?

I'd open a bug at
https://bugs.eclipse.org/bugs/enter_bug.cgi?product=E4&c omponent=UI If
you include a simple usecase, we might be able to narrow it down.

>
> You seem to have changed the API recently since I get a discouraged
> access in my code when I updated the e4 bundles today. Do I use the API
> differently now?

No, just our API is provisional and has now been marked as such. That's
generating the warnings.

The latest builds are:
e4 SDK build (tools to develop e4 RCP apps):
http://download.eclipse.org/e4/downloads/drops/I20100617-211 0

4.0 SDK build:
http://download.eclipse.org/e4/sdk/drops/I20100617-2238


--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Re: [E4] Preference annotation and the e4 dependency injection architecture [message #541175 is a reply to message #541145] Fri, 18 June 2010 14:41 Go to previous messageGo to next message
Artur Kronenberg is currently offline Artur KronenbergFriend
Messages: 159
Registered: August 2009
Senior Member
I opened a bug for this scenario:


https://bugs.eclipse.org/bugs/show_bug.cgi?id=317304

Hope this helps,

Kind regards,
Artur
Re: [E4] Preference annotation and the e4 dependency injection architecture [message #577269 is a reply to message #538660] Tue, 08 June 2010 12:21 Go to previous messageGo to next message
Paul Webster is currently offline Paul WebsterFriend
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Tom Schindl wrote:
> No the DI-Container remembers in a locale context (IEclipseContext) -
> you can compare it to a Hierarchical-HashMap - which values it has
> injected into your instance and whenever this value changes it reinjects
> the value.
>
> @Execute and @CanExecute are a bit different because that's not really
> injection what's happening there.
>
> The command-framework does something similar. When the instance is
> created it looks for @CanExecute and calls it with parameters in the
> context and remember which values it used because they could lead to an
> activation state change - now whenever one of the keys (the fully
> qualified classname, the value in @Named()) changes it recalls this method.
>
> The execute-method is only triggered by the Command-Framework wants to
> execute the command and then determines the values that need to be
> passed in.


Just a clarification. @Inject sets up what we call a RunAndTrack.
Every access to an IEclipseContext variable (like @Named("selection"))
is recorded in internal structures. When you set a variable on an
IEclipseContext fires and event and every RunAndTrack that accessed that
variable is re-run (causing your doSomething(*) method to be invoked again.

@CanExecute/@Execute/@Persist/@Focus are annotations that the framework
uses when it needs to call a method on client code. So rather than
implementing IHandler, you can provide an object with annotated methods
@CanExecute or @Execute. They use the same mechanism to turn
IEclipseContext variables into parameters for the method, but no RAT is
associated with them so they do not respond to variable changes.

PW


--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Re: [E4] Preference annotation and the e4 dependency injection architecture [message #577521 is a reply to message #577269] Fri, 11 June 2010 14:03 Go to previous messageGo to next message
Artur Kronenberg is currently offline Artur KronenbergFriend
Messages: 159
Registered: August 2009
Senior Member
Hi,

how exactly do we use the @Preferences annotation?

I have a method that is supposed to get called when a preference is changed that looks like this:

@Inject
public void keyChanged(@Preference(value="myKey") final String value){
System.out.println(value);
}

This method is called when starting my application. At that point the value is null cause the preference hasn't been changed yet.

later in my application, the value is changed like this:
Preferences node = new DefaultScope().getNode("preferenceid");
node.put("myKey", "NewValue");


My annotated method however isn't called after this.

If I debug the put method it runs into a firePreferenceChanged method. This method however checks if listeners are registered. Since my annotation doesn't require explicit registering as a listener the listeners in the preferences class is empty and there is no event fired.

Do I have to change my preference node in a different way in order to make the annotation above working?

Kind regards,
Artur
Re: [E4] Preference annotation and the e4 dependency injection architecture [message #577650 is a reply to message #577521] Tue, 15 June 2010 00:38 Go to previous messageGo to next message
Paul Webster is currently offline Paul WebsterFriend
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Which build are you using? I know we changed some of the @Preference
code recently:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=316375
https://bugs.eclipse.org/bugs/show_bug.cgi?id=316361

Possibly some other areas.

PW



--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Re: [E4] Preference annotation and the e4 dependency injection architecture [message #577933 is a reply to message #540113] Fri, 18 June 2010 12:54 Go to previous messageGo to next message
Artur Kronenberg is currently offline Artur KronenbergFriend
Messages: 159
Registered: August 2009
Senior Member
Hi,

I checked out the required bundles form CVS Head.
It doesn't seem to be either one of those bugs.

My method with the Inject is still just called when starting up my application. Later, when changing the preference Node, my method is not called again.

Is the way I am using the preference annotation right?

You seem to have changed the API recently since I get a discouraged access in my code when I updated the e4 bundles today. Do I use the API differently now?

Kind regards,
Artur
Re: [E4] Preference annotation and the e4 dependency injection architecture [message #577957 is a reply to message #577933] Fri, 18 June 2010 13:05 Go to previous messageGo to next message
Paul Webster is currently offline Paul WebsterFriend
Messages: 6859
Registered: July 2009
Location: Ottawa
Senior Member

Artur Kronenberg wrote:
> Is the way I am using the preference annotation right?

I'd open a bug at
https://bugs.eclipse.org/bugs/enter_bug.cgi?product=E4&c omponent=UI If
you include a simple usecase, we might be able to narrow it down.

>
> You seem to have changed the API recently since I get a discouraged
> access in my code when I updated the e4 bundles today. Do I use the API
> differently now?

No, just our API is provisional and has now been marked as such. That's
generating the warnings.

The latest builds are:
e4 SDK build (tools to develop e4 RCP apps):
http://download.eclipse.org/e4/downloads/drops/I20100617-211 0

4.0 SDK build:
http://download.eclipse.org/e4/sdk/drops/I20100617-2238


--
Paul Webster
http://wiki.eclipse.org/Platform_Command_Framework
http://wiki.eclipse.org/Command_Core_Expressions
http://wiki.eclipse.org/Menu_Contributions
http://wiki.eclipse.org/Menus_Extension_Mapping
http://help.eclipse.org/galileo/index.jsp?topic=/org.eclipse .platform.doc.isv/guide/workbench.htm


Re: [E4] Preference annotation and the e4 dependency injection architecture [message #577993 is a reply to message #541145] Fri, 18 June 2010 14:41 Go to previous messageGo to next message
Artur Kronenberg is currently offline Artur KronenbergFriend
Messages: 159
Registered: August 2009
Senior Member
I opened a bug for this scenario:


https://bugs.eclipse.org/bugs/show_bug.cgi?id=317304

Hope this helps,

Kind regards,
Artur
Re: [E4] Preference annotation and the e4 dependency injection architecture [message #650351 is a reply to message #577993] Mon, 24 January 2011 14:26 Go to previous messageGo to next message
Sebastian is currently offline SebastianFriend
Messages: 61
Registered: March 2010
Member
Seems like you kind of forget the nodePath:

@Inject
	@Preference(value = "test.URI", nodePath = "testProject")
	String serverUri;

and
IEclipsePreferences node = DefaultScope.INSTANCE.getNode("testProject");
		node.put("test.URI", "value");

This way, it works out fine Smile
Re: [E4] Preference annotation and the e4 dependency injection architecture [message #729510 is a reply to message #650351] Mon, 26 September 2011 11:27 Go to previous messageGo to next message
Christian Hanster is currently offline Christian HansterFriend
Messages: 22
Registered: March 2011
Junior Member
Hey Guys,

I also have problems with the @Preference annotation and the injection now.
In my application I have a class which I add to the context with:
Bundle bundle = FrameworkUtil.getBundle(getClass());
BundleContext bundleContext = bundle.getBundleContext();
IEclipseContext eclipseCtx =   EclipseContextFactory.getServiceContext(bundleContext);
ContextInjectionFactory.make(MyClass.class,eclipseCtx);

In the class there is a method like:
@Inject
public void hookEvents(@Preference(value="USERNAME",nodePath="/default/testProject") String username)
	{
		System.out.println(username);
	}

This method is called at the beginning because I can see an output ("null") at the console.
When I now change the preference in an other bundle of my application with:
IEclipsePreferences node = DefaultScope.INSTANCE.getNode("testProject");
node.put("USERNAME", "test");;


The new value is not injected again. The crazy thing is I have the same method in a part of my application (In the same bundle which changes the value). There the new value is injected Sad and I see an output. Perhaps it is a bug or I have done something wrong

I use Eclipse 4.1.0 Build: I20110620-1631

Christian
Re: [E4] Preference annotation and the e4 dependency injection architecture [message #729515 is a reply to message #729510] Mon, 26 September 2011 11:33 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas SchindlFriend
Messages: 6651
Registered: July 2009
Senior Member
[...]

> This method is called at the beginning because I can see an output
> ("null") at the console.
> When I now change the preference in an other bundle of my application with:
>
> IEclipsePreferences node = DefaultScope.INSTANCE.getNode("testProject");
> node.put("USERNAME", "test");;

Isn't the flush() missing?

Tom
Re: [E4] Preference annotation and the e4 dependency injection architecture [message #729520 is a reply to message #729515] Mon, 26 September 2011 11:50 Go to previous messageGo to next message
Christian Hanster is currently offline Christian HansterFriend
Messages: 22
Registered: March 2011
Junior Member
No,

also with the flush() it is only injected in the method of the part element. In the other class it is never injected Sad

Christian
Re: [E4] Preference annotation and the e4 dependency injection architecture [message #729541 is a reply to message #729520] Mon, 26 September 2011 13:03 Go to previous message
Christian Hanster is currently offline Christian HansterFriend
Messages: 22
Registered: March 2011
Junior Member
I don't understand this anymore. I have build another project for testing and there the same methods work Sad
So there have to be a mistake in my bundle.

Edit: I found the problem. When I start the application with some Spring bundles (Spring dm) it does not work but without these bundles it works fine Smile

Thanks for your help.
Christian

[Updated on: Mon, 26 September 2011 14:01]

Report message to a moderator

Previous Topic:how to show XP style components
Next Topic:How to get an E4 service inside PropertyTester class ?
Goto Forum:
  


Current Time: Fri Apr 19 20:33:09 GMT 2024

Powered by FUDForum. Page generated in 0.04076 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top