I have a class, which is either EJB or POJO (I don't know). I have to make an instance of this class. Is there any pattern for this operation? Or I should manually check for EJB annotations and then do JNDI lookup?
public Object instantiate(Class c) {
return /* ... */
}
EJB classes should be instantiated only by the container. Otherwise they are not EJB. If you want to obtain an EJB instance, look it up via JNDI, or inject it.
You can see if a class is supposed to be an EJB by verifying its annotations:
if (clazz.isAnnotationPresent(Stateless.class)
|| clazz.isAnnotationPresent(Statefull.class)) { .. };
(and message-driven, perhaps)
POJO (Plain Object Java Object) is normall instantiated with the new operator.
MyClass myClass = new MyClass( args )
It can also be created via reflection.
MyClass myClass = MyClass.class.newInstance();
Yes, you will need to check for EJB3 annotations and somehow figure out what it's JNDI name is (which may depend on your container).
The Seam framework does this using a JNDI name pattern (see the seam documentation). This way the Seam contexts can have a mix of POJOs and EJBs in them.
EJB3 is almost POJO that definitely has default constructor. There is no problem to instantiate it. The same is about any class that have default constructor.
Just say
clazz.newInstance();
and you are done.
If you are writing method that creates instances of any class this method should be parametrized:
public <T> T instance(Class<T> clazz)
Related
I have a Serializable Bean class which consist of an interface instance dozerMapper of MapperIF. Everything was working fine before I added PersistentManager in the context.xm file in my tomcat server. With the PersistentManager I am storing all the Objects in session as a file to the folder. But after i added the PersistentManager it started throwing NotSerializableException because of the MapperIF interface inside my Bean class. Adding transient keyword to the MapperIF could solve the NotSerializableException, But it ends up with the NullPointerException as the dozerMapper.map is coming null in the below code. So how can i handle this situation for serializing my bean class.
#Autowired
private transient MapperIF dozerMapper;
public Preferences getUiPreferences() {
if (this.uiPreferences == null) {
this.uiPreferences = ((Preferences) this.dozerMapper.map(
getPrefernces(), Preferences.class));
}
return this.uiPreferences;
}
The MapperIF interface (or its Dozer 5.x replacement Mapper) does not extend Serializable. Its standard implementation classes do not implement it either. Therefore the standard implementations are not going to be serializable.
I can think of ways to solve this:
Don't put the MapperIF reference into an object that you save in the session. It doesn't really belong there. Here's what the javadocs for the DozerBeanMapper class say:
This should be used/defined as a singleton within your application. This class performs several one-time initializations and loads the custom xml mappings, so you will not want to create many instances of it for performance reasons. Typically a system will only have one DozerBeanMapper instance per VM. If you are using an IOC framework (i.e Spring), define the Mapper as singleton="true". If you are not using an IOC framework, a DozerBeanMapperSingletonWrapper convenience class has been provided in the Dozer jar.
This implies that you shouldn't need to put a MapperIF object into a session.
Declare the field as transient and implement a custom readObject method that will repopulate the field (from somewhere) when you deserialize.
Implement your own custom MapperIF / Mapper class that is serializable. (I haven't looked, but this could be a lot of work ... or impossible.)
While I've found examples in CDI where you setup #Produces (kinda factory like) or using the CDI javax.enterprise.inject.spi.Unmanaged concepts, they all seem to presume that CDI will be the one creating the instance of the class on its own terms and lifecycle (which makes sense).
However, there are situations where CDI simply cannot create the instance.
Such as a 3rd party library (that isn't using CDI itself) which is creating the object internally and giving it to you.
Now, how can I take these already instantiated objects (which incidentally are final objects with no default constructor), and make them available for my CDI managed beans to then use?
Here's a simplified example.
public class Foo
{
#Inject
private ByteBuffer buf;
public void go()
{
// do something, with buffer
}
}
public void process() {
ByteBuffer buf = ByteBuffer.allocate(500);
// TODO: how to add "buf" to current context?
Foo foo = CDI.current().select(Foo.class,AnyLiteral.INSTANCE).get();
foo.go();
}
Now, I realize that for this specific example, I could eaily just pass in the ByteBuffer, or setup a #Produces for ByteBuffer, or even have Foo make the ByteBuffer itself. (all of which would be easier). I chose ByteBuffer, because it exhibits the same problems I'm facing with the 3rd party library
The instances are valid beans
I have no control over its source
Instances are created by the library
Those instances are final and cannot be wrapped, overridden, or proxied
The use case also has situations where there are nested CDI references that could also use access to this #Inject ByteBuffer buf;.
Ideally it would be keen to have this be a pure CDI api technique, and not something that is weld or implementation specific.
I've devled into custom Scope creation as well, thinking that might be a solution for this, having a sort of #BufferScope that identifies the start() and end() of this instance. But none of the examples and documentation make this very clear with regards to objects that CDI just cannot call newInstance() or produce() on. The object instantiation is out of my hands, but the ability to present it to a CDI Scope is possible, along with even managing the ultimate death / destruction of that instance.
Proxying is not the same as wrapping. A customary workaround is to create a ByteBufferHolder (insert your class here) that adapts the custom builder flow into a bean that understands that it's inside the DI context.
I'm not sure I agree with the original assertion that CDI assumes it is constructing the instances. For example, I use the following in a JSF application to inject the current FacesContext instance....
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import javax.faces.context.FacesContext;
public class FacesContextProducer {
#Produces #RequestScoped FacesContext getFacesContext() {
return FacesContext.getCurrentInstance();
}
}
At nowhere do I create the FacesContext instance. All that is required is that what has been created by the external framework is accessible.
So, if there is an external source from which you are getting instances, as long as you can get the correct one, the #Produces approach should still work?
There is some fundamental misunderstanding here. CDI is not required to construct the bean instances it can serve through producer methods. A Dependent scope will work just fine if the class is not proxyable. You can also make a wrapper class for the object, and put said class instances in whichever scope you need.
You use a producer method, which can be as simple as something like this:
#Produces
#ApplicationScoped
private Foo produceFoo() {
final Foo instance = // acquire one of those instances you're talking about
return instance;
}
If for whatever reason that doesn't work for you, you can alternatively write a portable extension and programmatically add a Bean that does what you want. So something like this in CDI 2.0+ (untested):
private void afterBeanDiscovery(#Observes final AfterBeanDiscovery event) {
final Foo instance = // acquire one of these final instances you're talking about
event.addBean()
.scope(ApplicationScoped.class)
.qualifiers(whateverYouNeed)
.addTransitiveTypeClosure(instance.getClass())
.createWith(cc -> instance) // you may also need .destroyWith()
;
}
Once you have this "producing side" set up, then in any CDI bean anywhere you can do:
#Inject
private Foo foo;
I have a project that I am in the process of making OSGi compatible. The code relies on Java SPI for adding implementations (META-INF/services). I don't want to use SPI in OSGi environments (e.g. by using SPI Fly), I'd rather use the OSGi way. However, I want to keep SPI support for non-OSGi environments. My approach has been the following:
The factories look something like this (using BND annotations):
#Component
class MyFactory implements MyFactoryService {
public MyFactory() {
...
}
//This method is reserved for non-OSGi use (uses SPI to find implementations)
public static MyFactory newInstance() {
MyFactory ret = new MyFactory();
Iterator<MyDiscoverable> i = ServiceLoader.load(MyDiscoverable.class).iterator();
while (i.hasNext()) {
ret.addFactory(i.next());
}
}
#Reference
public void addFactory(MyDiscoverable f) {
...
}
}
In an OSGi context, MyFactory is in an OSGi private package and must be retrieved through the service registry using the MyFactoryService interface. MyFactory is then populated by the OSGi framework using the #Reference annotation (or rather the declarative service generated from it).
If the implementations of MyDiscoverable require other factories similar to MyFactory, I put something like this in MyFactory.newInstance():
public static MyFactory newInstance() {
MyFactory ret = new MyFactory();
MyOtherFactory other = MyOtherFactory.newInstance();
Iterator<MyDiscoverable> i = ServiceLoader.load(MyDiscoverable.class).iterator();
while (i.hasNext()) {
MyDiscoverable x = i.next();
//This method is also annotated with #Reference in the implementation, to support OSGi use
x.setReference(other);
ret.addFactory(x);
}
}
This works alright in both OSGi and SPI context. One issue I have with this is that the factory must know which other factories each implementation might need (and supply them). This is because I haven't found a way to let the implementation create their own instances of the factories without making it incompatible with OSGi. This limitation is manageable for the most part, but it isn't acceptable as a general solution.
Is there a better way? If so, how?
One way would be to explicitly provide MyDiscoverable with the information that it was created through newInstance, e,g. x.populateWithSPI(). This way, setReference could be called by the implementation itself with e.g. MyOtherFactory.newInstance()
OSGI is uses an IOC container and like all IOC containers (Guice, Spring, etc..), the IOC container must be responsible for the instantiation of a class.
SPI enables discovery of implementations at runtime and SPI instantiates those implementations as part of the discovery.
You can't use the same class for SPI and OSGI (or any other IOC container) without a hack because they have different ways of instantiating a class. I recommend keeping the two approaches separate.
You could create a wrapper class around MyFactoryService that is used by SPI. The class could be called MyFactoryServiceProvider and it could return a class reference for MyFactoryService for you to instantiate and then pass references of MyDiscoverable to it.
I have created a OSGI service with declarative services to inject an object that implements an interface. If I inject the object in a class that is attached to the application model (handler,part,....) it is working fine. If I inject it in a class that is not attached to the application model it is always returning null.
Is it possible to use DI in classes that are not attached to the application model? I looked in the vogella tutorials but somehow I don't find a solution.
I know of three ways of how Eclipse 4 can inject objects in your classes:
During start-up the Eclipse runtime looks for relevant annotations in the classes it instantiates.
Objects injected in 1. are tracked and will be re-injected if changed.
Manually triggering injection using the ContextInjectionFactory and IEclipseContext.
What you want may be possible with the third option. Here is a code example:
ManipulateModelhandler man = new ManipulateModelhandler();
//inject the context into an object
//IEclipseContext iEclipseContext was injected into this class
ContextInjectionFactory.inject(man,iEclipseContext);
man.execute();
The problem is, however; that the IEclipseContext already needs to be injected into a class that can access the object that needs injection. Depending on the number of necessary injections, it might be more useful to use delegation instead (testability would be one argument).
#Inject
public void setFoo(Foo foo) {
//Bar is not attached to the e4 Application Model
bar.setFoo(foo);
}
Therefore, a better solution is probably using the #Creatable annotation.
Simply annotate your class, and give it a no-argument constructor.
#Creatable
public class Foo {
public Foo () {}
}
Using #Inject on that type as in the method above, will let Eclipse instantiate and inject it.
The disadvantage is that you cannot control the object creation anymore, as you would with ContextInjectionFactory.inject(..).
I refactored out some part of e(fx)clipse in order to achieve that. Have a look at this. Sorry for the shameless plug...
How we can manually inject an object without using the facility of containers. I did something similar through reflection as follows.
Class actionClass = Class.forName("SampleClass");
Object actionObject = actionClass.newInstance();
Method reqMethod = actionClass.getMethod("setRequest", HttpServletRequest.class);
reqMethod.invoke(actionObject,request);
is it the right way to do DI?
My intention is to pass request object to different controller classes dynamically from a dispatcher filter,where we get request and response objects.
I am fearing about the performace of reflection.Is there any replacement for doing DI?
Dependency injection is nothing more than providing a class with its dependencies, rather than have it find them itself (via singletons/lookups etc.). So you can do it in code trivially thus:
DatabaseConnection dc = new DatabaseConnection();
MyDAO dao = new MyDAO(dc);
(pseudocode). Here the MyDAO is being injected with a database connection. If that database connection implements an interface you can easily mock this out during testing.
Well, when you set one object into another object using setter method or through a constructor it also is the dependency injection. Dependency injection only means creating relationship(dependency) in objects.
Using reflection as you did is just another form of it.
Why would you use reflection? Why not simply:
SampleClass action = new SampleClass();
action.setRequest(request);
That does the same thing, but is more readable, allows the compiler to check that the types and methods actually exist, provides you with Javadoc for the Method invoked, enables your IDE to assist in refactorings, ...
And it still is dependency injection, because the action doesn't go looking for its request, but receives the request during initialization.
Edit: Thorbjørn requested I show how that action would be used. It would itself be injected (using a setter) into whatever component uses the action. The component would then use the injected action object.
SampleClass action = new SampleClass();
action.setRequest(request);
Servlet servlet = new ActionBasedServlet();
servlet.setAction(action);
If servlet is intended to live longer than action, i.e. it should use a fresh Action each time it needs one, one can instead setter-inject an ActionFactory into servlet.
In this concrete case, I'd question whether the action really needs to keep a request as part of its state, or can be immutable and simply act on the request passed by the Servlet as method parameter. In that case, the boot-time initialization would do:
SampleClass action = new SampleClass();
Servlet servlet = new ActionBasedServlet();
servlet.setAction(action);
and ActionBasedServlet would define
public void serve(Request req, Response resp) {
foo();
action.act(req, resp);
bar();
}
Dependency Injection implies you get properly initialized references appearing "by magic".
You call the setRequest() method with the request object, but DI frequently also allows for setting the fields without invoking methods.
Guice does not as such require a container, but uses class loader magic started in the main method. Would that be useable for you?
Spring framework is one of the most popular DI implementations. It is also opensource.
You can check out the class org.springframeowrk.beans.BeanUtils, specifically the methods copyProperties (all 4 of them) for examples on how to do this.
For more info you can also see the class hierarchy of org.springframework.beans.factory.BeanFactory for different strategies.