From ec59f519fe8286b7fadad2b7712f6b32f2b31939 Mon Sep 17 00:00:00 2001 From: Erik Brakkee Date: Sat, 12 Oct 2013 14:09:09 +0200 Subject: [PATCH] UTILS-17 CDI integration in wicket can lead to null pointer exceptions after deserialization The InjectIonBehavior does injection after deserialization only when beforeRender is called, but beforeRender() is not always the first call done after deserialization. Therefore, InjectionBehavior should do injection straight after deserialization (if needed). Injection is now done at deserialization. --- .../ComponentInstantiationInjector.java | 12 ++++---- .../wicket/inject/InjectionBehavior.java | 28 +++++++++++++------ .../wicket/inject/InjectionBehaviorTest.java | 9 +++--- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/wicket/joe/src/main/java/org/wamblee/wicket/inject/ComponentInstantiationInjector.java b/wicket/joe/src/main/java/org/wamblee/wicket/inject/ComponentInstantiationInjector.java index cdda947d..d4bb39dc 100644 --- a/wicket/joe/src/main/java/org/wamblee/wicket/inject/ComponentInstantiationInjector.java +++ b/wicket/joe/src/main/java/org/wamblee/wicket/inject/ComponentInstantiationInjector.java @@ -29,12 +29,12 @@ import org.wamblee.inject.SimpleInjector; * for standard Java EE injection into components. Or, other injection * frameworks can be used. *

- * + *

*

* To use this injector override {@link WebApplication#init()} and add the * listener: *

- * + *

*

  * @Override
  * protected void init() {
@@ -42,11 +42,10 @@ import org.wamblee.inject.SimpleInjector;
  *     addComponentInstantiationListener(new ComponentInstantiationInjector());
  * }
  * 
- * + * * @author Erik Brakkee */ -public class ComponentInstantiationInjector implements - IComponentInstantiationListener { +public class ComponentInstantiationInjector implements IComponentInstantiationListener { private SimpleInjector injector; @@ -60,7 +59,6 @@ public class ComponentInstantiationInjector implements @Override public void onInstantiation(Component aComponent) { injector.inject(aComponent); - aComponent.add(new InjectionBehavior()); + aComponent.add(new InjectionBehavior(aComponent)); } - } diff --git a/wicket/joe/src/main/java/org/wamblee/wicket/inject/InjectionBehavior.java b/wicket/joe/src/main/java/org/wamblee/wicket/inject/InjectionBehavior.java index 659be7a7..45da4a98 100644 --- a/wicket/joe/src/main/java/org/wamblee/wicket/inject/InjectionBehavior.java +++ b/wicket/joe/src/main/java/org/wamblee/wicket/inject/InjectionBehavior.java @@ -15,6 +15,8 @@ */ package org.wamblee.wicket.inject; +import java.io.IOException; + import org.apache.wicket.Component; import org.apache.wicket.behavior.AbstractBehavior; import org.wamblee.inject.InjectorBuilder; @@ -22,27 +24,35 @@ import org.wamblee.inject.InjectorBuilder; /** * Injection behavior that performs dependency injection after * serialization/deserialisation of the object. - * + * * @author Erik Brakkee - * */ public class InjectionBehavior extends AbstractBehavior { private static final long serialVersionUID = 7363393083209418693L; - private transient boolean injectionUptodate; + private Component _component; + private boolean _injectionUptodate; /** * Constructs the behavior. */ - public InjectionBehavior() { - injectionUptodate = true; + public InjectionBehavior(Component aComponent) { + _component = aComponent; + } + + private void writeObject(java.io.ObjectOutputStream stream) throws IOException { + stream.defaultWriteObject(); + } + + private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + injectIfNeeded(_component); } - @Override - public void beforeRender(Component aComponent) { - if (!injectionUptodate) { + private void injectIfNeeded(Component aComponent) { + if (!_injectionUptodate) { InjectorBuilder.getInjector().inject(aComponent); - injectionUptodate = true; + _injectionUptodate = true; } } } diff --git a/wicket/joe/src/test/java/org/wamblee/wicket/inject/InjectionBehaviorTest.java b/wicket/joe/src/test/java/org/wamblee/wicket/inject/InjectionBehaviorTest.java index d54de1ce..e9ba180c 100644 --- a/wicket/joe/src/test/java/org/wamblee/wicket/inject/InjectionBehaviorTest.java +++ b/wicket/joe/src/test/java/org/wamblee/wicket/inject/InjectionBehaviorTest.java @@ -53,21 +53,22 @@ public class InjectionBehaviorTest { @Test public void testNoInjectionInitially() { - InjectionBehavior behavior = new InjectionBehavior(); + Component component = mock(Component.class); + InjectionBehavior behavior = new InjectionBehavior(component); behavior.beforeRender(component); verifyNoMoreInteractions(injector); } @Test public void testInjectOnlyOnceAfterDeserialisation() throws Exception { - InjectionBehavior behavior = new InjectionBehavior(); + Component component = mock(Component.class); + InjectionBehavior behavior = new InjectionBehavior(component); behavior = ObjectSerializationUtils.deserialize( ObjectSerializationUtils.serialize(behavior), InjectionBehavior.class); - behavior.beforeRender(component); - verify(injector).inject(same(component)); + verify(injector).inject(any(Component.class)); reset(injector); behavior.beforeRender(component); verifyNoMoreInteractions(injector); -- 2.31.1