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.)
Related
In a simple Spring boot application I have my component like this:
#Data
#Component
public class GenericHandler {
private String path;
private HandlerType type;
}
And my properties might look like this:
my.handlers[0].path='/vol1/abc'
my.handlers[0].type='Single'
my.handlers[1].path='/vol1/dora'
my.handlers[1].type='MultiSequence'
I tried decorating with the GenericHandler-class with #ConfigurationProperties(prefix="my.handlers") and getting a list of all component instances in a service using
#Autowired
private List<GenericHandler> handlers;
But that created just one component, ignoring the property values at all.
How can I get one component instance per my.handlers property-entry?
You need a wrapper class
#Component
#ConfigurationProperties(prefix="my.handlers")
#Data
public class GenericHandlerWrapper {
private List<GenericHandler> handlers;
...
}
Then you can autowire the GenericHandlerWrapper
Update
As #zoolway pointed out in the comments, for the properties in the question to work as it is, #ConfigurationProperties(prefix="my.handlers") should be changed to #ConfigurationProperties(prefix="my")
That's not possible. What can be done is this:
#Data
#Component
public class GenericHandler {
private List<String> path;
private List<HandlerType> type;
}
I dealt with a similar issue in a different manner. I created a factory and an interface. The factory would hold different implementations of that interface In your case, GenericHandler would be your interface. Then you write any number of implementations of your interface and each implementation is declared as a Component. So, Spring will instantiate it as bean upon a startup (you might use #Lazy(false) to force the instantiation at startup) using some infrastructure that I wrote each bean of that interface will self-insert itself into its factory. Then at any part of your code in any bean, you can use the factory to access concrete implementation (base on your property "type" for example). The beauty is that you don't need to inject all the implementations in your bean at the time of writing but access needed implementation dynamically at run-time. I found this to be a useful pattern and created an infrastructure that does most of the work for you and published it as an Open Source library called MgntUtils. The detailed description of the idea (including reference to the library) could be found here. Also detailed explanation with examples of how to use it can be found in library Javadoc here. The library is available (with source code and Javadoc) as Maven artifacts and on the Github. Also a general article about the MgntUtils library could be found here
Explanation & Workaround
Currently I am using JAX-RS and letting JAXB bindings automatically handle converting the data to XML and JSON for me in a JEE6 project. Everything is working absolutely fantastically until I try to create a generic response object to wrap all of my information in.
When I attempt to use my generic response class com.eln00b.Wrapper (which contains a private Object result attribute within it) I get:
javax.xml.bind.MarshalException - with linked exception: [com.sun.istack.SAXException2: class com.eln00b.CustomObject nor any of its super class is known to this context. javax.xml.bind.JAXBException: class com.eln00b.CustomObject nor any of its super class is known to this context.]
So I add to com.eln00b.Wrapper:
#XmlSeeAlso ({com.eln00b.CustomObject})
public class Wrapper {
}
Everything works fine.
The Problem
I want this to be extremely generic. I do not want t constantly add classes to the #XmlSeeAlso annotation on the com.eln00b.Wrapper class. How do I have the system automatically locate all of my classes for the JAXB context?
Even if it's a hack where I use something like Reflections to load the data, that's fine. I'm just not sure how to get the context to load all of that data without the #XmlSeeAlso annotation. With the large amount of annotations I will be creating it will just simply not work.
How It Worked Manually
It worked manually just by adding the data like so doing manual conversions. However, I do not want to use manual XML/JSON creation unless I absolutely need to (I don't want to deal with content negotiation or anything like that).
Sample:
JAXBContext.newInstance(new Class[] {Wrapper.class, CustomObject.class});
So here is what the essence of the custom resolver looks like:
#Provider
#Produces ({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public class JaxbContextResolver implements ContextResolver<JAXBContext> {
#Override
public JAXBContext getContext(Class<?> type) {
// load appropriate context data
Class[] bindTypes = ...
// create
try {
return JAXBContext.newInstance(bindTypes);
} catch (JAXBException e) {
// todo: this can be handled better but works for the example
throw new RuntimeException(e);
}
}
}
Now, the processing for "load appropriate context data" is pretty simple. By basically mimicking #XmlSeeAlso using runtime data:
Create a custom something (annotation, processing method, whatever) that marks a particular field/method as "contextual"
Load the field/method data pulling the data types out
Make sure you do not load duplicates and check for infinite recursion possibilities
Now, I used some caching to help make things more efficient for myself. I also created a slightly more complex setup for my root object where it actually kept track of the class data on its own and made it pretty speedy. I also created an alternative that marked classes as "contextual" that I used package inspection to load via annotations and just automatically add to the context but I have not checked efficiency on that yet. I have some ideas for a 3rd implementation, but I want to get more benchmarking completed.
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...
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)
I wanted to understand the best way to integrate Gilead with GXT and hibernate. This article http://code.google.com/webtoolkit/articles/using_gwt_with_hibernate.html describes the usage of Gilead with GWT.
Most of the GXT components are bound using custom classes that inherit BaseModelData, does this mean we need to convert the bean that is persisted (LightEntity bean) to the custom class that extends BaseModelData before binding to the GXT compoenent. Is my understanding correct ? If yes, what is the advantage I get by doing this, I would need to use dozer/hand code conversion yet again ?
The examples on the gilead site as pathetic, can anyone provide a link where a complete example of using GXT with Gilead and hibernate is present ?
Thanks
You do not need to have your DAOs implement BaseModelData.
What you have to do is for each DAO class you create an interface in your GWT client package. You have to extend BeanModelMarker and use the #BEAN annotation. This tells EXT GWT that your DAO can be used as a BeanModel
package org.gwtapp.client.model;
import com.extjs.gxt.ui.client.data.BeanModelMarker;
import com.extjs.gxt.ui.client.data.BeanModelMarker.BEAN;
#BEAN(org.vnsny.domain.MyClass.class)
public interface MyClassBeanModel extends BeanModelMarker {
}
Then when you need to create a BeanModel from your class you use the BeanModelFactory
BeanModel model = BeanModelLookup.get().getFactory(
MyClass.class).createModel(myClassObj);
Also when you are using data components and retrieving a collection typed as a superclass with subclasses instances you will need to add this setting to the bean reader
reader.setFactoryForEachBean(true);
If you don't set a factory for each bean, the reader will try to cast all objects as the class of the first instance of the collection
Ex:
Super class = Animal
SubClasses = Dog, Cat
In the remote method you return a list of Animal: List and create the bean model interface for each class.