Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » DI Injection for Handlers(@Execute @Creatable)
DI Injection for Handlers [message #1174717] Thu, 07 November 2013 09:19 Go to next message
Ludwig Moser is currently offline Ludwig MoserFriend
Messages: 365
Registered: July 2009
Senior Member
Hello,

i am developing an E4 application with compatibility layer for E3 code because my actual code is E3 but i need some features from E4.

Overview of the Problem:
Createable (DAO)
E3 Handler (which needs the createable
E4 Handler, wrapping the E3 Handler (to use DI)
E4 Handler does not get the DAO (the Createable)

for example i got an DAO (Data Access Object) defined like this:
@Creatable
public class DAO {

	@Inject
	@Preference(nodePath="/instance")
	IEclipsePreferences preferences;

	@Inject
	@GeminiPersistenceContext(unitName = "configured", properties = {
			@GeminiPersistenceProperty(name = PersistenceUnitProperties.JDBC_DRIVER, valuePref = @Preference(nodePath="/instance", value="jdbc_driver")),
			@GeminiPersistenceProperty(name = PersistenceUnitProperties.JDBC_URL, valuePref = @Preference(nodePath="/instance", value="jdbc_url")),
			@GeminiPersistenceProperty(name = PersistenceUnitProperties.JDBC_USER, valuePref = @Preference(nodePath="/instance", value="jdbc_user")),
			@GeminiPersistenceProperty(name = PersistenceUnitProperties.JDBC_PASSWORD, valuePref = @Preference(nodePath="/instance", value="jdbc_pwd")),
			@GeminiPersistenceProperty(name = PersistenceUnitProperties.LOGGING_LEVEL, value = "FINE"),
			@GeminiPersistenceProperty(name = PersistenceUnitProperties.WEAVING, value = "false"),
			@GeminiPersistenceProperty(name = PersistenceUnitProperties.WEAVING_INTERNAL, value = "false"),
			@GeminiPersistenceProperty(name = GeminiPersistenceProperties.GEMINI_REINIT) })
	private EntityManager em;

	@Inject
	public DAO() {
		preferences.put(GeminiPersistenceProperties.GEMINI_REINIT, "false");
		try {
			preferences.flush();
		} catch (BackingStoreException e) {
			e.printStackTrace();
		}
	}

	public Object void  save(Object dataObj) throws SQLException {
		checkConnection();
		EntityTransaction trx = em.getTransaction();
		trx.begin();
		em.persist(dataObj);
		trx.commit();
	}

	@PreDestroy
	public void destroy() {
		if (em != null && em.isOpen()) {
			em.close();
		}
	}

	private void checkConnection() throws SQLException {
		if (em == null) {
			throw new SQLException(
					"EntityManager is null. Not connected to database!");
		}
	}
}


further i got an handler (POJO)
public class TestSaveDBHandler {

	@Execute
	public void execute(@Named(IServiceConstants.ACTIVE_SHELL) Shell shell,
			DAO dao) throws InvocationTargetException, InterruptedException {

		try {
			// Via injected DAO
			Contact c = BioofficeFactory.eINSTANCE.createContact();
			c.setFirstName("Ludwig");
			c.setLastName("Spitzenst├Ątter via DAO");
			System.out.println("dao=" + dao);
			System.out.println("contact=" + c);
			dao.save(c);
		} catch (Exception e) {
			MessageDialog.openError(shell, "Error persisting Contact",
					"Something went wrong in the DAO \n " + e.getMessage());
		}
	}
}


i wrap this pojo handler to an E4 handler:
import org.eclipse.e4.tools.compat.parts.DIHandler;

public class E4TestSaveDBHandler extends DIHandler<TestSaveDBHandler> {

	public E4TestSaveDBHandler() {
		super(TestSaveDBHandler.class);
	}
}


last but not least i define the handler in my plugin.xml
<command
            defaultHandler="handlers.E4TestSaveDBHandler"
            id="TestSaveDBHandler"
            name="TestSaveDBHandler">
       </command>


when executing the command in the rcp app i get the following exception
Caused by: org.eclipse.e4.core.di.InjectionException: Unable to process "TestSaveDBHandler#execute()": no actual value was found for the argument "DAO".
	at org.eclipse.e4.core.internal.di.InjectorImpl.reportUnresolvedArgument(InjectorImpl.java:412)
	at org.eclipse.e4.core.internal.di.InjectorImpl.invokeUsingClass(InjectorImpl.java:239)
	at org.eclipse.e4.core.internal.di.InjectorImpl.invoke(InjectorImpl.java:213)
	at org.eclipse.e4.core.contexts.ContextInjectionFactory.invoke(ContextInjectionFactory.java:90)
	at org.eclipse.e4.tools.compat.parts.DIHandler.execute(DIHandler.java:48)
	at org.eclipse.ui.internal.handlers.HandlerProxy.execute(HandlerProxy.java:290)
	at org.eclipse.ui.internal.handlers.E4HandlerProxy.execute(E4HandlerProxy.java:90)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:56)
	... 37 more


as DAO is defined as @Createable it shoule be available. so what am i missing?
i am not sure if this makes any difference: i do start the app via my .product

[Updated on: Thu, 07 November 2013 09:29]

Report message to a moderator

Re: DI Injection for Handlers [message #1176317 is a reply to message #1174717] Fri, 08 November 2013 08:59 Go to previous messageGo to next message
Johannes Spreemann is currently offline Johannes SpreemannFriend
Messages: 19
Registered: August 2013
Location: Germany/Netherlands
Junior Member
I introduced my POJO classes with @Creatable annotation to the Application Context manually in the constructor. I don't know why it only worked in that way in my application but maybe you can try this too like:

@Inject
	public DAO(MApplication application) {
                application.getContext().set(this.getClass().getName(), this);
		preferences.put(GeminiPersistenceProperties.GEMINI_REINIT, "false");
		try {
			preferences.flush();
		} catch (BackingStoreException e) {
			e.printStackTrace();
		}
	}

Re: DI Injection for Handlers [message #1176335 is a reply to message #1176317] Fri, 08 November 2013 09:15 Go to previous messageGo to next message
Ludwig Moser is currently offline Ludwig MoserFriend
Messages: 365
Registered: July 2009
Senior Member
just tried it. but still fails with exactly the same exception.
there is no place where i need to register the DAO (@Createable) right??
Re: DI Injection for Handlers [message #1176370 is a reply to message #1176335] Fri, 08 November 2013 09:38 Go to previous messageGo to next message
Johannes Spreemann is currently offline Johannes SpreemannFriend
Messages: 19
Registered: August 2013
Location: Germany/Netherlands
Junior Member
The code, I've posted above, adds your POJO to the Application Context manually but I never used the compatibility from e3 to e4.
There is no other place to register your class with @Creatable. Instead of using the application context you could try to use the IEclipseContext instead of the MApplication.

Sometimes the InjectionException is misleading because I also got this Exception when another exception occurred in a different class that was connected to the injected one.
What happens when you use your handler without injecting the DAO (Just for debug)?
Re: DI Injection for Handlers [message #1176433 is a reply to message #1176370] Fri, 08 November 2013 10:30 Go to previous messageGo to next message
Ludwig Moser is currently offline Ludwig MoserFriend
Messages: 365
Registered: July 2009
Senior Member
i followed your hint and found out that an exception gets raised in my DAO.

@Creatable
public class DAO {

	@Inject
	@Preference
	IEclipsePreferences preferences;



	@Inject
	public DAO() {
		System.out.println("DAO: preferences="+preferences);
	}
}

the preferences in the dao is null, which should not happen (no clue why!) any ideas about this one?
Re: DI Injection for Handlers [message #1176439 is a reply to message #1176370] Fri, 08 November 2013 10:32 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 1412
Registered: July 2012
Senior Member
Have you checked that the EntityManager is available? Maybe there is no DAO instance available because it could not be created because of a missing EntityManager?

I'm not sure about it, but that would be a step in finding the issue. Comment everything related to the EntityManager and try again. Just to be sure to search in the right direction.
Re: DI Injection for Handlers [message #1176500 is a reply to message #1176439] Fri, 08 November 2013 11:20 Go to previous messageGo to next message
Ludwig Moser is currently offline Ludwig MoserFriend
Messages: 365
Registered: July 2009
Senior Member
everything with EntityManager is commented out (its not ready)
but the Preferences should be ready. (i got another exampe which uses the @Preferences exactly the same way i do?!)
Re: DI Injection for Handlers [message #1176580 is a reply to message #1176500] Fri, 08 November 2013 12:21 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 1412
Registered: July 2012
Senior Member
As you can read here http://www.vogella.com/articles/EclipseRCP/article.html#context_ieclipsecontextdefaults Preferences are not stored in the context but are injected via OSGi services. Maybe your configuration is not setup correctly. Have you checked that the necessary plugins are started correctly with the correct auto start level?
http://wiki.eclipse.org/Eclipse4/RCP/FAQ#Why_won.27t_my_application_start.
Re: DI Injection for Handlers [message #1176600 is a reply to message #1176580] Fri, 08 November 2013 12:37 Go to previous messageGo to next message
Ludwig Moser is currently offline Ludwig MoserFriend
Messages: 365
Registered: July 2009
Senior Member
pretty sure, as the DAO itself gets injected (but the preferences inside do not)
will check on monday, and leave a reply - thanks for your help in the meantime! really appreciate it!
Re: DI Injection for Handlers [message #1182375 is a reply to message #1176580] Tue, 12 November 2013 06:27 Go to previous message
Ludwig Moser is currently offline Ludwig MoserFriend
Messages: 365
Registered: July 2009
Senior Member
for the preferences: i got an working example which uses Preferences exactly the same way i do.

for the autostart

i got four plugins starting:
javax.persistence - 2 - true
org.eclipse.gemini.dbaccess.derby - 2 - true
org.eclipse.gemini.dbaccess.microsoftsqlserver - 2 - true
org.eclipse.gemini.jpa - 4 - true

afaik this should be fine.
Previous Topic:How to implement Save As for our Part.
Next Topic:Part on top of a PartSashContainer
Goto Forum:
  


Current Time: Fri Nov 28 17:15:46 GMT 2014

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

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