Home » Eclipse Projects » Eclipse 4 » No e4 support for a simple scenario?(DI e4xmi Annotations Problem)
|
Re: No e4 support for a simple scenario? [message #1085327 is a reply to message #1084696] |
Mon, 12 August 2013 19:30 |
Erdal Karaca Messages: 854 Registered: July 2009 |
Senior Member |
|
|
I hope you mean POJO as E4 does not support .NET
There are some solutions I can think of:
- [SIMPLE] the students set up a simple plugin/bundle project and provide a specific manifest header (which would be an implementation of a Game interface/class), this shouldn't be that complicated (even for students), then, the GameService would scan all installed bundles and look for that marker entry in the manifest headers of each bundle (BundleContext provides this already)
- [COMPLICATED] the students set up a simple java project which they export as plain jar file, then, you could use something like "reflections" (see [1]) to scan the class paths, either at build time or at run time, i.e. search for all classes that are annotated with @Game
- [COMPLEX] use AspectJ to scan for all classes that are annotated with @Game, either at run time or at build time
[1] http://code.google.com/p/reflections/
Anatoli Barski wrote on Mon, 12 August 2013 02:50Hello and thanks for help in advance,
I want users to be able to provide Game-Plugins for my pure e4-application. A game is just a visualization using swt/xwt. The plugins will be provided by students, so I don't want them to learn osgi or e4 concepts when everything they want: add some fancy swt. There will be about 40 visualizations.
Ideally I would provide @Game annotation for a visualization POCO. This POCO should be picked up, instantiated and added to a GameService, then a part would be created using a PartDescriptor, this part would receive it's content from Game POCO.
I spent a few days elaborating this scenario to find out there seems to be no way.
Anatoli
|
|
|
Re: No e4 support for a simple scenario? [message #1085732 is a reply to message #1085327] |
Tue, 13 August 2013 09:33 |
Anatoli Barski Messages: 5 Registered: August 2013 |
Junior Member |
|
|
Hallo Erdal, thank you for your suggestions!
you're right, POJOs they are I keep switching between .NET and Java.
Quote:- [SIMPLE] the students set up a simple plugin/bundle project and provide a specific manifest header (which would be an implementation of a Game interface/class), this shouldn't be that complicated (even for students), then, the GameService would scan all installed bundles and look for that marker entry in the manifest headers of each bundle (BundleContext provides this already)
This one is actually quite simple, but in what way is this better than to provide an extension point the students would extend. I think it is totally the same but lacks tool support. I can also think there would be more than only one setting: e.g. name of the game and the implementing class, for which a student needs to type a resource uri. With annotation he would not need this uri and would have intellisense for parameters and also use plain java tools (annotation)
Quote:[COMPLICATED] the students set up a simple java project which they export as plain jar file, then, you could use something like "reflections" (see [1]) to scan the class paths, either at build time or at run time, i.e. search for all classes that are annotated with @Game
I think this is interesting idea, but as you stated too complicated workflow to establish. I would also need add a reference to those jars from my core project, every time a plugin is added.
Quote:[COMPLEX] use AspectJ to scan for all classes that are annotated with @Game, either at run time or at build time
[1] code.google.com/p/reflections/
This one is a "do it yourself" solution. I'm currently evaluating this using BundleWiring.listResources(): I think I'll get problems with bundle lifecycle. I have to scan the bundles when they come and go from my core plugin, so I have to make sure the core game-plugin is started before the game-plugins, for which I think you have to provide a separate feature with p2.inf file including a startup level, which I think is a "don't do it" in osgi context and may introduce other issues. Correct me if I'm wrong.
When I find a "Game"-Class, I want to instantiate this, create and add a part to a partstack. Where do I get the applications IEclipseContext? When I can get this, what if EModelService is not yet injected? It seems I would have to store the annotated "Game-Classes" until "@PostContextCreate" using the lifecycle hook.
In general it is the same work JPAAnnotationScanner from apache aries does. (but I also need to interfere with the model)
svn.apache.org/repos/asf/aries/tags/org.apache.aries.jpa.container-1.0.0/src/main/java/org/apache/aries/jpa/container/annotation/impl/JPAAnnotationScanner.java
This leads me to a general criticism on e4 annotation & DI & app model "break through" as these are main features of e4. IMHO the ability to define own annotations in e4 is useless: the most advanced example I have seen was LeapMotionController, which could also be implemented as an osgi service providing context function interface.
blog.vogella.com/2013/07/30/leap-motion-in-eclipse-4"
I think the ability to define own annotations and get objects injected would be great (would be similar to what gemini blueprint provides but less).
I think the problem with that approach is that the application context in e4 is "ui driven" (it is called model, but it is actually a ui-definition): if you are not extending the model, you don't get access to the context, so you cannot use DI.
I think this is the reason why Type-Annotations are not supported by ExtendedObjectSupplier.
I also think to allow this we need some work on e4 infrastructure, and I'm looking now how to workaround.
I really appreciate your answers and would like to discuss if this is a major issue, or my misunderstanding or a good feature request.
Regards! Anatoli
[Updated on: Tue, 13 August 2013 09:38] Report message to a moderator
|
|
|
Re: No e4 support for a simple scenario? [message #1085763 is a reply to message #1085732] |
Tue, 13 August 2013 10:36 |
Erdal Karaca Messages: 854 Registered: July 2009 |
Senior Member |
|
|
Quote:
Quote:- [SIMPLE] the students set up a simple plugin/bundle project and provide a specific manifest header (which would be an implementation of a Game interface/class), this shouldn't be that complicated (even for students), then, the GameService would scan all installed bundles and look for that marker entry in the manifest headers of each bundle (BundleContext provides this already)
This one is actually quite simple, but in what way is this better than to provide an extension point the students would extend. I think it is totally the same but lacks tool support. I can also think there would be more than only one setting: e.g. name of the game and the implementing class, for which a student needs to type a resource uri. With annotation he would not need this uri and would have intellisense for parameters and also use plain java tools (annotation)
One of your requirement was to "hide" e4 (this implies e3?) and osgi concepts from students. So, you are now saying that using extensions would be ok? Then, that would be the best solution, I think.
Quote:
I think the ability to define own annotations and get objects injected would be great (would be similar to what gemini blueprint provides but less).
I think the problem with that approach is that the application context in e4 is "ui driven" (it is called model, but it is actually a ui-definition): if you are not extending the model, you don't get access to the context, so you cannot use DI.
The root context is a BundleContext/OSGi aware IEclipseContext: EclipseContextFactory.getServiceContext(bundleContext)
So, you can use E4 DI without UI.
But still wonder why you need DI at all, as all the students have to do is to "add some fancy swt"?
Quote:
I think this is the reason why Type-Annotations are not supported by ExtendedObjectSupplier.
I also think to allow this we need some work on e4 infrastructure, and I'm looking now how to workaround.
I am not sure if we need E4 DI to mimic Spring DI.
|
|
|
Re: No e4 support for a simple scenario? [message #1085780 is a reply to message #1085763] |
Tue, 13 August 2013 11:08 |
Anatoli Barski Messages: 5 Registered: August 2013 |
Junior Member |
|
|
Quote:One of your requirement was to "hide" e4 (this implies e3?) and osgi concepts from students. So, you are now saying that using extensions would be ok? Then, that would be the best solution, I think.
It's still not ok: my point is - I don't want them to learn how to use extension points, let them learn how to put the stuff in osgi manifest is a nice idea, but in the end still worse than extending eclipse bundles (this knowledge you can reuse and you have to enter basically same information either in plugin.xml or in manifest.mf
I think defining a "part"-Class(with @PostConstruct annotation) with @Game(name="NumberShark") and beeing able to inject provided services would be a lot more elegant solution. (This is why I need DI, they will at least need to inject Logger/StatusReporter and then may be TranslationService and GameService,...)
Quote:The root context is a BundleContext/OSGi aware IEclipseContext: EclipseContextFactory.getServiceContext(bundleContext)
So, you can use E4 DI without UI.
I tried this already: if I put this line into my Core Game Bundle Activator, those components are inside the context (EModelService to find the part stack is missing):
{org.eclipse.e4.ui.workbench.swt.modeling.EMenuService=org.eclipse.e4.ui.workbench.swt.modeling.MenuServiceCreationFunction@3deac601, org.eclipse.e4.core.services.statusreporter.StatusReporter=org.jcryptool.core.logging.StatusReporterCF@6d8b69, org.eclipse.e4.core.services.events.IEventBroker=org.eclipse.e4.ui.services.events.EventBrokerFactory@17db9ab7, debugString=OSGi context for bundle: org.jcryptool.games, org.jcryptool.games.GamesService=org.jcryptool.games.GamesServiceCF@528a709d, org.eclipse.core.runtime.IProgressMonitor=org.eclipse.e4.ui.internal.workbench.ProgressMonitorFunction@7ee77dc0, org.eclipse.e4.ui.workbench.modeling.EPartService=org.eclipse.e4.ui.internal.workbench.PartServiceCreationFunction@ff10957, org.eclipse.e4.tools.services.IResourcePool=org.eclipse.e4.tools.services.impl.ResourcePoolFactory@199c36ee}
Quote:I am not sure if we need E4 DI to mimic Spring DI.
Why do we need e4 DI to mimic Spring DI? Hmmm I don't know why Spring DI (gemini blueprint) was not included in e4 instead of defining an own way, I accept: there might be reasons. But I'm still wondering why not.
So why implement DI at all? Because IoC is great! But what we have is a very limited IoC which is strictly coupled with the application model.
An example:
I think defining an osgi-service to be able to inject objects outside of application model is too heavy. This is why there is @Creatable annotation, but it doesn't work for classes not coupled to the application model. I would rather expect @Service annotation for classes which need to be registered as osgi services. This would be easy to accomplish if we had a proper annotation processing & DI in place.
[Updated on: Tue, 13 August 2013 20:02] Report message to a moderator
|
|
|
Re: No e4 support for a simple scenario? [message #1086096 is a reply to message #1085780] |
Tue, 13 August 2013 20:18 |
Erdal Karaca Messages: 854 Registered: July 2009 |
Senior Member |
|
|
Anatoli Barski wrote on Tue, 13 August 2013 13:08
I think defining a "part"-Class(with @PostConstruct annotation) with @Game(name="NumberShark") and beeing able to inject provided services would be a lot more elegant solution. (This is why I need DI, they will at least need to inject Logger/StatusReporter and then may be TranslationService and GameService,...)
Your framework could handle this itself using ContextInjectionFactory.inject(gameInstance,context) where context is the IEclipseContext you have populated with the required services or just use ContextInjectionFactory.make(...) where you read the extensions...
Quote:
Quote:The root context is a BundleContext/OSGi aware IEclipseContext: EclipseContextFactory.getServiceContext(bundleContext)
So, you can use E4 DI without UI.
I tried this already: if I put this line into my Core Game Bundle Activator, those components are inside the context (EModelService to find the part stack is missing):
{org.eclipse.e4.ui.workbench.swt.modeling.EMenuService=org.eclipse.e4.ui.workbench.swt.modeling.MenuServiceCreationFunction@3deac601, org.eclipse.e4.core.services.statusreporter.StatusReporter=org.jcryptool.core.logging.StatusReporterCF@6d8b69, org.eclipse.e4.core.services.events.IEventBroker=org.eclipse.e4.ui.services.events.EventBrokerFactory@17db9ab7, debugString=OSGi context for bundle: org.jcryptool.games, org.jcryptool.games.GamesService=org.jcryptool.games.GamesServiceCF@528a709d, org.eclipse.core.runtime.IProgressMonitor=org.eclipse.e4.ui.internal.workbench.ProgressMonitorFunction@7ee77dc0, org.eclipse.e4.ui.workbench.modeling.EPartService=org.eclipse.e4.ui.internal.workbench.PartServiceCreationFunction@ff10957, org.eclipse.e4.tools.services.IResourcePool=org.eclipse.e4.tools.services.impl.ResourcePoolFactory@199c36ee}
Quote:I am not sure if we need E4 DI to mimic Spring DI.
Why do we need e4 DI to mimic Spring DI? Hmmm I don't know why Spring DI (gemini blueprint) was not included in e4 instead of defining an own way, I accept: there might be reasons. But I'm still wondering why not.
So why implement DI at all? Because IoC is great! But what we have is a very limited IoC which is strictly coupled with the application model.
I would rather say it is a very lightweight DI engine highly specialized to the needs of the Eclipse platform
Note: I am no E4 committer or the like, so, do not expect my personal opinions/suggestions to match with those of the E4 team...
|
|
|
Re: No e4 support for a simple scenario? [message #1091362 is a reply to message #1086096] |
Wed, 21 August 2013 11:59 |
Anatoli Barski Messages: 5 Registered: August 2013 |
Junior Member |
|
|
Thanks for your input, Erdal,
I kinda got it to work with an own annotation scanner, I don't think it can make a blueprint, because I don't think I'm dealing well with bundle lifecycle, but for my environment it works. Here is the link to a simple bundle demonstrating the approach:
github.com/jcryptool/core/tree/e4/org.jcryptool.games
Explanation:
In the Activator I have a bundleTracker with GameBundleTrackerCustomizer
BundleTracker<?> bundleTracker = new BundleTracker<>(context, Bundle.ACTIVE, new GameBundleTrackerCustomizer<Object>());
bundleTracker.open();
GameBundleTrackerCustomizer's method addingBundle is called for each bundle, so I can scan them for annotations using BundleWiring#listResources
To load the classes, I use BundleDelegatingClassLoader from Spring DM
docjar.com/html/api/org/springframework/osgi/util/BundleDelegatingClassLoader.java.html
Then I have osgi service GameService to register those classes I have found for future use.
[Updated on: Wed, 21 August 2013 11:59] Report message to a moderator
|
|
|
Re: No e4 support for a simple scenario? [message #1092460 is a reply to message #1091362] |
Thu, 22 August 2013 20:41 |
Eclipse User |
|
|
|
First of all ExtendedObjectSuppliers are *designed* not to care about the IEclipseContext.
An injector needs to have a supplier from where to get stuff from.
One way to supply objects to the requestors of the injections (your pojo) is to use this hierarchic context story where objects are splattered along this tree of contexts ( the @Inject way ). If you don't like it how the hierarchic contexts work between themselves (lookup mechanisms, instantiations etc.) you can customize it with context functions. If you don't like the contexts story altogether, you can provide an ExtendedObjectSupplier which defines a completely different way for the injector to supply objects to the requestors (@UIEventTopic, @Preference in the platform are cases of injections managed through extended suppliers).
I also think there are places which we can tune to be better in our EOS story, of course.
Even though most of the DI goes on in the IEclipseContext-s of the model (it *is* a model in the sense that it models the workbench, it models its properties, its behavior and its relationships with widget-agnostic language), it is in no way dependent on having the application model around. Just create a child out of a leaf and do the ContextInjectionFactory#make. This will give you all that is available in that branch. I've explained it some time ago here http://www.eclipse.org/forums/index.php/mv/msg/481466/1048998/#msg_1048998 .
As I said, while I absolutely know it's not perfect, the Eclipse 4 DI was designed to help people build relatively complex RCP applications with as better a design as possible. I'm not familiar with the internals of the Spring DI engine but maybe Guice is closer to what you need, even though I'm not sure I've understood your usecase well enough.
Feedback is always appreciated and we do have strong discussions on Bugzilla regarding the runtime stuff (which includes the DI part of the framework).
|
|
|
Re: No e4 support for a simple scenario? [message #1095229 is a reply to message #1092460] |
Mon, 26 August 2013 20:12 |
Erdal Karaca Messages: 854 Registered: July 2009 |
Senior Member |
|
|
The E4 DI (and I think Guice, too) is a dependency injection engine that "injects" values into objects that are managed by that engine (denoted by the known annotations).
Anatoli's use case was somehow different: He wanted the DI engine to "fetch" all types annotated with @Game to manage their instances. This would have required that the DI engine scan all bundle class paths and parse their byte-code to determine if a type had that annotation set...
This is one main focus of aspect oriented programming and not covered by DI engines like E4 DI (and maybe should not due to its complexity and performance impact).
Sopot Cela wrote on Thu, 22 August 2013 22:41First of all ExtendedObjectSuppliers are *designed* not to care about the IEclipseContext.
An injector needs to have a supplier from where to get stuff from.
One way to supply objects to the requestors of the injections (your pojo) is to use this hierarchic context story where objects are splattered along this tree of contexts ( the @Inject way ). If you don't like it how the hierarchic contexts work between themselves (lookup mechanisms, instantiations etc.) you can customize it with context functions. If you don't like the contexts story altogether, you can provide an ExtendedObjectSupplier which defines a completely different way for the injector to supply objects to the requestors (@UIEventTopic, @Preference in the platform are cases of injections managed through extended suppliers).
I also think there are places which we can tune to be better in our EOS story, of course.
Even though most of the DI goes on in the IEclipseContext-s of the model (it *is* a model in the sense that it models the workbench, it models its properties, its behavior and its relationships with widget-agnostic language), it is in no way dependent on having the application model around. Just create a child out of a leaf and do the ContextInjectionFactory#make. This will give you all that is available in that branch. I've explained it some time ago here http://www.eclipse.org/forums/index.php/mv/msg/481466/1048998/#msg_1048998 .
As I said, while I absolutely know it's not perfect, the Eclipse 4 DI was designed to help people build relatively complex RCP applications with as better a design as possible. I'm not familiar with the internals of the Spring DI engine but maybe Guice is closer to what you need, even though I'm not sure I've understood your usecase well enough.
Feedback is always appreciated and we do have strong discussions on Bugzilla regarding the runtime stuff (which includes the DI part of the framework).
|
|
|
Re: No e4 support for a simple scenario? [message #1095301 is a reply to message #1095229] |
Mon, 26 August 2013 22:40 |
Anatoli Barski Messages: 5 Registered: August 2013 |
Junior Member |
|
|
Quote:One way to supply objects to the requestors of the injections (your pojo) is to use this hierarchic context story where objects are splattered along this tree of contexts ( the @Inject way ). If you don't like it how the hierarchic contexts work between themselves (lookup mechanisms, instantiations etc.) you can customize it with context functions. If you don't like the contexts story altogether, you can provide an ExtendedObjectSupplier which defines a completely different way for the injector to supply objects to the requestors (@UIEventTopic, @Preference in the platform are cases of injections managed through extended suppliers).
Can you suggest a way for a bundle which does not provide a part to participate in E4 DI, which means: be able to inject Messages/Translations, inject a Logger, inject EModelService, ECommandService, EHandlerService,...
What I actually don't like about it:
1) I never know for sure, if the stuff I need like ECommandService will be available in the context or not. I'm not 100% sure, but I think I could not fire a Command from Processor, because ECommandService was not available.
2) There is no composition root, using ContextInjectionFactory is a service-Locator anti-pattern. This also introduces race conditions: I inject something into context at runtime (after bootstrap) to be able to depend on it later, but when I try to inject it from context, I have to be sure it is already in that context.
Thanks for the Guice advice, very interesting read: code.google.com/p/google-guice/wiki/OSGi
Though as Erdal stated, I think Guice will be able to inject objects managed by Guice, which does not cover EModelService for instance. I want give it a try and see if I can benefit from Guice.
Quote:He wanted the DI engine to "fetch" all types annotated with @Game to manage their instances. This would have required that the DI engine scan all bundle class paths and parse their byte-code to determine if a type had that annotation set... I think scanning byte-code is one solution for DI, there is also reflection, I also think it does not have to be a performance killer, because most of injection should happen at bootstrap process of the application.
|
|
| |
Goto Forum:
Current Time: Mon Sep 23 10:06:45 GMT 2024
Powered by FUDForum. Page generated in 0.03767 seconds
|