Announcement Announcement Module
Collapse
No announcement yet.
Beans marked @Configurable are not injected when deserialized by Tomcat SESSIONS.ser Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Beans marked @Configurable are not injected when deserialized by Tomcat SESSIONS.ser

    I noticed this behavior on a Struts 1.2.9 based (legacy) application with Spring 2.5.4, spring-tomcat-weaver-2.5.4, Tomcat 6.0.14.

    Code:
    public class MyForm implements Serializable {
       private Foo myFoo; // getters and setters
    }
    
    public class Foo imlements Serializable {
       private Bar myBar; // getters setters
    }
    
    @Configurable("barTemplate")
    public class Bar implements Serializable {
       @Autowired(required=true)
       private transient SessionFactory hello;
       // other transient dependencies ...
    }
    The XML configures Bar as a prototype bean.

    The correct context:spring-configured and context:load-time-weaver settings are applied, etc (since it works on a cold start of Tomcat).

    Everything works fine when starting for the first time. However, restarting Tomcat causes to write SESSIONS.ser and upon rebooting, to deserialize MyForm, which it does. However, none of the dependencies in Bar are set!

    But if I shutdown Tomcat, delete the SESSIONS.ser file, and reboot, then everything will work.

    Weird.

    Any advice greatly appreciated.

  • #2
    Hi,

    if I remember correctly the deserialization support comes with spring 3.x, you can however add a naming interface with the readResolve-method and implement your own aspect. I did that once, but then upgraded to spring 3.x.

    Regards

    Jakob

    Edit: Some example code, I just found:
    Code:
    package eu.codecamp.utils.lib.aspects.spring;
    
    
    
    import java.lang.reflect.ParameterizedType;
    
    import java.lang.reflect.Type;
    
    import java.util.HashMap;
    
    import java.util.List;
    
    import java.util.Map;
    
    
    
    import org.apache.commons.logging.Log;
    
    import org.apache.commons.logging.LogFactory;
    
    import org.aspectj.lang.JoinPoint;
    
    import org.aspectj.lang.annotation.After;
    
    import org.aspectj.lang.annotation.Aspect;
    
    
    
    @Aspect
    
    public class DeserializeDependencyInjectionAspect {
    
    
    
    	private static final Log log = LogFactory.getLog(DeserializeDependencyInjectionAspect.class);
    
    	@SuppressWarnings("rawtypes")
    
    	private Map<Class, IDeserializeDependencyInjector> injectorMap;
    
    	
    
    	@SuppressWarnings("rawtypes")
    
    	public DeserializeDependencyInjectionAspect() {
    
    		injectorMap = new HashMap<Class, IDeserializeDependencyInjector>();
    
    	}
    
    	
    
    	@SuppressWarnings("rawtypes")
    
    	public void setInjectors(
    
    			List<IDeserializeDependencyInjector> injectors) {
    
    		injectorMap.clear();
    
    		for (IDeserializeDependencyInjector injector : injectors) {
    
    			try {
    
    				Type injectorType = injector.getClass().getGenericInterfaces()[0];
    
    				Class targetClass = (Class)((ParameterizedType)injectorType).getActualTypeArguments()[0];
    
    				injectorMap.put(targetClass, injector);
    
    			} catch (ClassCastException e) {
    
    				log.error(e);
    
    			}
    
    		}
    
    	}
    
    
    
    	@SuppressWarnings({ "unchecked", "rawtypes" })
    
    	@After("execution(Object eu.codecamp.utils.lib.domain.IDeserializationSupport.readResolve() throws java.io.ObjectStreamException)")
    
    	public void injectDependencies(JoinPoint jp) {
    
    		try {
    
    			Object target = jp.getTarget();
    
    			Class targetClass = target.getClass();
    
    			if (injectorMap.containsKey(targetClass)) {
    
    				try {
    
    					IDeserializeDependencyInjector injector = injectorMap.get(targetClass);
    
    					injector.injectDependencies(target);
    
    				} catch (ClassCastException e) {
    
    					log.error(e);
    
    				}
    
    			}
    
    		} catch (NullPointerException e) {
    
    			e.printStackTrace();
    
    		}
    
    	}
    
    
    
    }
    Code:
    package eu.codecamp.utils.lib.aspects.spring;
    
    public interface IDeserializeDependencyInjector<TargetClass> {
    
    	public void injectDependencies(TargetClass target);
    }
    Code:
    package eu.codecamp.utils.lib.domain;
    
    
    
    import java.io.ObjectStreamException;
    
    import java.io.Serializable;
    
    
    
    public interface IDeserializationSupport extends Serializable {
    
    	
    
    	public Object readResolve() throws ObjectStreamException;
    
    }
    Last edited by Jakob O.; Feb 7th, 2011, 03:53 PM.

    Comment

    Working...
    X