What is the simplest way to have some sort of DI in RCP application?
I need to register dependencies and use them in different parts of application: wizards, dialogs, properties pages, etc.
What I have: a product with bunch of plugins.
What I need: at start of Eclipse RCP product I need to read some files, keep this data in memory and make it accesible to different UI elements(among different plugins) without using of singletons.
I cant pass this data in constructors when creating consumers, because consumers are UI elements which often created by RCP platform and I dont have direct access for their creation.
Eclipse 4.3 supports DI. This works best for a RCP created as a pure Eclipse 4 application which does not use Eclipse 3 compatibility code ('e4' mode). Objects which are defined in the new application model are created using DI, but it is also possible to create other objects (dialogs for example) using injection.
For an introduction to Eclipse 4 RCP see http://www.vogella.com/articles/EclipseRCP/article.html
For an Eclipse 3 application a part can get the Eclipse Context needed for injection using
IWorkbenchPartSite site = part.getSite();
IEclipseContext parentContext = (IEclipseContext) site.getService(IEclipseContext.class);
Use org.eclipse.e4.core.contexts.ContextInjectionFactory for injection.
Or, if you are still using an Eclipse 3 application, you can use the Eclipse Plugin Registry to define extension points and extensions. This also amounts to Dependency Injection, without the injection :-)
Related
I want to make a java application that supports plug ins. Now my core will use jars for certain processes. If my plug ins where to also use these jars, do the plug ins of my application need to configure their build path to include the jars they would also use or is their a way so that the jars can be imported similar to how I import packages from the main application
Guice and Spring are tools for dependency injection, which means that creating objects is easier with them because they take care of instantiating objects and placing them into other objects that depends on them.
Now, when we talk about plugins, we usually are talking too about dynamically loading new classes into a running app. Think on eclipse IDE. Its architecture was designed from the beginning to be "pluggable", like, you can download jars and eclipse will add them to the running application without the need of application restart.
In this case, if you want to build pluggable apps, in a sense of dynamic classloading, I'd recommend you not to go through this path, but to research subjects such as OSGI. One popular OSGI framework is http://felix.apache.org/
Another approach for application extension (we may call this pluggable too, somehow, I guess), depending on how your app is organized and what it does, is to develop a DSL (http://en.wikipedia.org/wiki/Domain-specific_language) for it and extend it letting people adding scripts to it. Isn't something like this when a browser let you add pieces of funcionality written in javascript? Groovy makes DSL easier in some aspects, for java programmers. (see http://docs.codehaus.org/display/GROOVY/Writing+Domain-Specific+Languages)
If you want dynamic plugable systems OSGI can give you this, but OSGI its IMMO a over-complicated technology, use only if you are really sure that needs this dynamic plug-ability.
Other option for builds extensible systems its use de ServiceProvider mechanism, this is a core java mechanism, for example its the one that JDBC implementations use, you can put a JDBC driver in your classpath and the application can find it and use it without needing that you explicitly import the driver classes in your code.
This is an example of using ServiceProvider in your owns applications: http://docs.oracle.com/javase/tutorial/ext/basics/spi.html#limitations-of-the-service-loader-api
Its of course more limited than OSGI, but its very easy to use when you get the idea, and you don't need any external library because its a java core mechanism.
EDIT: about the libraries.
In runtime: With ServiceProvicer there is no separate classloaders (you can implement off course, but by default, in OSGI its implemented this separation), in runtime if your plugin need X class and this class is in the classpath all is ok, the limitation its that the main application and all the plugins use this version of the dependency (guice 3 for example) and you cannot have one plugin using X version and other plugin using X+2 version if this version are not compatible. (this is the famous hell .jar, and one of the principal motivations behind jigsaw project for example).
In compile time, include the dependency in your pom, ant build file, gradle build file or whatever build system your use as usual.
I'm currently working on an application in Java that contains a core set of functionality, this has to be extended for several different purposes (~10 different purposes) and as such, the best solution that came to mind was the option to add plugins to expand the functionality when needed as opposed to having a different code base for each.
Is the best way of doing this simply creating an interface and extending that in the relevant plugins?
public coreCode()
{
// Core
doThis();
doThat();
// Call plugin code
plugin.doStuff();
}
// Plugin
public interface PluginInterface()
{
doStuff();
...
}
I've looked into JSF etc but due to work limitations (not spcifically authorized etc), they are sadly not a viable option.
--EDIT--
It should roughly work like this:
purpose A, B and C require a certain set of functionality and so plugin1 is developed for them, bundled with them and then deployed. purpose D and E require a different set so plugin2 is developed for them, bundled and deployed. etc.
For plugins you could create a certain directory where class files implementing a certain interface or extending a certain abstract class are located. Then you can create new instances of these classes and see if they are an instance of the abstract class/interface you want them to be, then make a certain list of them and give users the ability to enable/disable them. If they are enabled you can then cast and execute them.
I would suggest you to look into OSGi - a dynamic component model where applications are developed and deployed as a set of bundles/plug-ins that can be added, started, stopped and removed remotely without even requiring a reboot of the core/host application.
You can model your application on the Eclipse RCP platform (one the best implementations of OSGi) and create a head-less (without any UI) core RCP application. All other application functionalities would then be developed as plug-ins that can come bundled or added later on to your core RCP application in any combination you like (or your clients may request) even after the application has gone live.
If you're application would have a UI and you like the Eclipse IDE's look and functionalities like "New Project" Wizards, use of Perspectives to change the layout of Views, Workspaces, context-sensitive Help functionality and over-the-network updates through plug-in repositories etc. then it's definitely worth considering. Have a look at this RCP FAQ page to see if this fits your needs.
The only thing that put developers off is that it has a bit of a steep learning curve. The dependencies are always declared declaratively with XMLs and within the code all the components are so de-coupled that you always find yourself interacting with the framework more.
The use of JFace for building UI components puts a lot of stress on the separation between the Model and the View. So, while all of this translates to good application design it doesn't allow rapid application development if one is new to the framework. Most of its other complexities come from the fact that RCP just has so much to offer.
I have a Java EE based REST api application. It has a layered architecture like the following:
Resources (Jax-rs resources)
Object Validation
Object Mapper
Service Layer
Repository Layer
JPA Entities
Everything is wired using Spring dependency injection.
I need to design this core application in such a way that it allows other external developers to write extensions/plugins and override or extends any minor or major functionality in the core. Think of it like Wordpress CMS in Java EE if that helps. How would you design a plugin system around the current architecture?
One obvious way that I can think of is override or add new functionality to the proper resource (with validation, objectmapper), service, repository and entity and create a jar + xml out of it. But I want to make sure that the plugin developer has to write the absolutely minimum amount of code to get the new functionality working, while reusing mush of the core code.
Assume, you want to create a wordpress blog post extension that lets you create blog posts with few extra fields that don't exist in core yet. What would be the simplest and cleanest way to go about designing the current Java EE app, so its easy for the plugin/extension developers? Any patterns that could be useful like strategy or template method pattern?
Are there any open source Java CMS that follow the model using Spring/JPA and standard technologies?
I think you mean to extend the functionality, rather than override the core. Typical architecture examples define concerns which can be overridden (separate from core) and make provisions. Eclipse framework achieves this using a combination of plugin-extensions & extension-points mechanism. This is taken further using OSGI bundling.
Another alternative is to breakdown the application into smaller independent modules/services. All you need to do is host these modules over an ESB/Application Integrator (like Mule/Spring Integration) and allow users to configure their version of routing/transformation. Extension would mean creation of new transformers which get added to the message flow.
what would be a recommended way to work with Spring application context within Eclipse RCP project.
I have a Swing based application that is wired together by Spring and its configurations. What would be the best strategy for these two, without too many conflicts between them (I'm just beginning with Eclipse RCP, and I am mostly worried about how similarly eclipse plugin.xml looks in comparison with xxx-context.xml.
Thank you for help.
I think the best way to use Spring in Eclipse RCP project is to use it with Spring Dynamic Modules. I define beans in diffrent contexts over the plugins and export some of them as osgi services to allow beans from other plugins use them in dependency injection. Also I implemented some kind of ServiceAccessor (singleton wrapper over osgi service accessor) that displays "waiting services to be registered" dialog to user until all necessary services will be registered.
I've been working with Visual Studio for a long long time, but now I'm been requested to work on a Java web project. We've decide to use Spring MVC as framework, and we want to use Log4J (for logging obviously =P) and JUnit for unit testing. Now, in the "Microsoft way" I will create a Solution, and I'll add A web project and a Unit testing project; now that I'm usign Netbeans, is it possible to do like that? Or how should I organize my projects?
Thanks for sharing your experience!
Have you thought about using Maven as a way to manage your project? I've heard really good things about it.
You can find a list of what Maven is, exactly, here.
In short, it has the following goals (I took these from the web site):
Making the build process easy
Providing a uniform build system
Providing quality project information
Providing guidelines for best practices development
Allowing transparent migration to new features
Try to use maven, and there is a standard way for a project :)
In Netbeans you specify what type of project you want to create, say Java Web Application. Netbeans will then create the files and folders to support that project. Within the project view explorer, you can see the 'Test Packages' node, this is where you add java classes to support your unit testing. When you add a unit test, Netbeans will add a reference to the correct JUnit library to your project (you can see this on project properties > libraries > compile test).
For Spring MVC, the same goes. You add a dependency in Netbeans, either at project creation time, or from the properties dialog afterwards.
This is just tip of the iceberg. So I hope this information allows you to at least get started and you can return with more specific questions as you get further in.