Repository: wicket Updated Branches: refs/heads/master 4b07e9a29 -> 8b6fcd869
WicketWICKET-6334 WicketObjects#sizeof() should detach Sessions CheckingObjectOutputStream now use the IObjectChecker's only when a IManageablePage is being serialized. Anything else won't be checked. Project: http://git-wip-us.apache.org/repos/asf/wicket/repo Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/8b6fcd86 Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/8b6fcd86 Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/8b6fcd86 Branch: refs/heads/master Commit: 8b6fcd869ceb96f7b4ea003d3d5665a1626390ad Parents: 4b07e9a Author: Martin Tzvetanov Grigorov <[email protected]> Authored: Mon Mar 6 21:18:43 2017 +0100 Committer: Martin Tzvetanov Grigorov <[email protected]> Committed: Mon Mar 6 21:18:43 2017 +0100 ---------------------------------------------------------------------- .../main/java/org/apache/wicket/Session.java | 3 +- .../checker/CheckingObjectOutputStream.java | 17 +-- .../checker/DifferentPageCheckerTest.java | 6 +- .../checker/NotDetachedModelCheckerTest.java | 108 +++++++++++++++++++ .../objects/checker/SessionCheckerTest.java | 29 ++++- .../serialize/java/JavaSerializerTest.java | 43 -------- .../wicket/util/io/SerializableCheckerTest.java | 43 ++++++-- .../inspector/SessionSizeModelTest.java | 13 ++- 8 files changed, 196 insertions(+), 66 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/wicket/blob/8b6fcd86/wicket-core/src/main/java/org/apache/wicket/Session.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/Session.java b/wicket-core/src/main/java/org/apache/wicket/Session.java index e7f9c14..059805f 100644 --- a/wicket-core/src/main/java/org/apache/wicket/Session.java +++ b/wicket-core/src/main/java/org/apache/wicket/Session.java @@ -35,6 +35,7 @@ import org.apache.wicket.event.IEvent; import org.apache.wicket.event.IEventSink; import org.apache.wicket.feedback.FeedbackMessage; import org.apache.wicket.feedback.FeedbackMessages; +import org.apache.wicket.model.IDetachable; import org.apache.wicket.page.IPageManager; import org.apache.wicket.page.PageAccessSynchronizer; import org.apache.wicket.request.Request; @@ -106,7 +107,7 @@ import org.slf4j.LoggerFactory; * @author Eelco Hillenius * @author Igor Vaynberg (ivaynberg) */ -public abstract class Session implements IClusterable, IEventSink +public abstract class Session implements IClusterable, IEventSink, IDetachable { private static final long serialVersionUID = 1L; http://git-wip-us.apache.org/repos/asf/wicket/blob/8b6fcd86/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/CheckingObjectOutputStream.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/CheckingObjectOutputStream.java b/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/CheckingObjectOutputStream.java index 4978c0e..2299e42 100644 --- a/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/CheckingObjectOutputStream.java +++ b/wicket-core/src/main/java/org/apache/wicket/core/util/objects/checker/CheckingObjectOutputStream.java @@ -36,7 +36,9 @@ import java.util.Map; import java.util.Set; import org.apache.wicket.Component; +import org.apache.wicket.Page; import org.apache.wicket.WicketRuntimeException; +import org.apache.wicket.page.IManageablePage; import org.apache.wicket.util.lang.Classes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -348,14 +350,17 @@ public class CheckingObjectOutputStream extends ObjectOutputStream nameStack.add(simpleName); traceStack.add(new TraceSlot(obj, fieldDescription)); - for (IObjectChecker checker : checkers) + if (obj instanceof IManageablePage || (traceStack.size() > 1 && traceStack.get(0).object instanceof IManageablePage)) { - IObjectChecker.Result result = checker.check(obj); - if (result.status == IObjectChecker.Result.Status.FAILURE) + for (IObjectChecker checker : checkers) { - String prettyPrintMessage = toPrettyPrintedStack(Classes.name(cls)); - String exceptionMessage = result.reason + '\n' + prettyPrintMessage; - throw new ObjectCheckException(exceptionMessage, result.cause); + IObjectChecker.Result result = checker.check(obj); + if (result.status == IObjectChecker.Result.Status.FAILURE) + { + String prettyPrintMessage = toPrettyPrintedStack(Classes.name(cls)); + String exceptionMessage = result.reason + '\n' + prettyPrintMessage; + throw new ObjectCheckException(exceptionMessage, result.cause); + } } } http://git-wip-us.apache.org/repos/asf/wicket/blob/8b6fcd86/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/DifferentPageCheckerTest.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/DifferentPageCheckerTest.java b/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/DifferentPageCheckerTest.java index 8752d2d..380b00d 100644 --- a/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/DifferentPageCheckerTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/DifferentPageCheckerTest.java @@ -21,7 +21,7 @@ import java.io.ObjectOutputStream; import java.io.OutputStream; import org.apache.wicket.Component; -import org.apache.wicket.MockPageWithLink; +import org.apache.wicket.MockPageWithOneComponent; import org.apache.wicket.Page; import org.apache.wicket.markup.html.WebComponent; import org.apache.wicket.markup.html.form.login.MockHomePage; @@ -51,8 +51,8 @@ public class DifferentPageCheckerTest extends WicketTestCase } }; - WebComponent component = new ComponentThatKeepsAReferenceToAnotherPage(MockPageWithLink.LINK_ID); - MockPageWithLink rootPage = new MockPageWithLink(); + WebComponent component = new ComponentThatKeepsAReferenceToAnotherPage(MockPageWithOneComponent.COMPONENT_ID); + MockPageWithOneComponent rootPage = new MockPageWithOneComponent(); rootPage.add(component); byte[] serialized = serializer.serialize(rootPage); assertNull("The produced byte[] must be null if there was an error", serialized); http://git-wip-us.apache.org/repos/asf/wicket/blob/8b6fcd86/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/NotDetachedModelCheckerTest.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/NotDetachedModelCheckerTest.java b/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/NotDetachedModelCheckerTest.java new file mode 100644 index 0000000..260178b --- /dev/null +++ b/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/NotDetachedModelCheckerTest.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.wicket.core.util.objects.checker; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; + +import org.apache.wicket.MockPageWithOneComponent; +import org.apache.wicket.markup.html.WebComponent; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.LoadableDetachableModel; +import org.apache.wicket.serialize.java.JavaSerializer; +import org.apache.wicket.util.tester.WicketTestCase; +import org.junit.Test; + +/** + * Tests for {@link NotDetachedModelChecker}. + * <p> + * Tests that the serialization fails when a checking ObjectOutputStream is + * used with NotDetachedModelChecker and there is a non-detached LoadableDetachableModel + * in the object tree. + * </p> + */ +public class NotDetachedModelCheckerTest extends WicketTestCase +{ + /** + * https://issues.apache.org/jira/browse/WICKET-4812 + * https://issues.apache.org/jira/browse/WICKET-6334 + */ + @Test + public void whenSerializingPage_thenItsComponentsShouldBeChecked() { + JavaSerializer serializer = new JavaSerializer("JavaSerializerTest") + { + @Override + protected ObjectOutputStream newObjectOutputStream(OutputStream out) throws IOException + { + IObjectChecker checker = new NotDetachedModelChecker(); + return new CheckingObjectOutputStream(out, checker); + } + }; + + MockPageWithOneComponent page = new MockPageWithOneComponent(); + page.add(new ComponentWithAttachedModel(MockPageWithOneComponent.COMPONENT_ID)); + + final byte[] serialized = serializer.serialize(page); + assertNull("The produced byte[] must be null if there was an error", serialized); + } + + /** + * https://issues.apache.org/jira/browse/WICKET-4812 + * https://issues.apache.org/jira/browse/WICKET-6334 + */ + @Test + public void whenSerializingNonPageComponent_thenItsSubComponentsShouldNotBeChecked() { + JavaSerializer serializer = new JavaSerializer("JavaSerializerTest") + { + @Override + protected ObjectOutputStream newObjectOutputStream(OutputStream out) throws IOException + { + IObjectChecker checker = new NotDetachedModelChecker(); + return new CheckingObjectOutputStream(out, checker); + } + }; + + final ComponentWithAttachedModel component = new ComponentWithAttachedModel("id"); + + final byte[] serialized = serializer.serialize(component); + assertThat(serialized, is(notNullValue())); + } + + private static class ComponentWithAttachedModel extends WebComponent + { + private final IModel<String> member = new LoadableDetachableModel<String>() + { + @Override + protected String load() + { + return "modelObject"; + } + }; + + public ComponentWithAttachedModel(final String id) + { + super(id); + + // attach the model object + member.getObject(); + } + } +} http://git-wip-us.apache.org/repos/asf/wicket/blob/8b6fcd86/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/SessionCheckerTest.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/SessionCheckerTest.java b/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/SessionCheckerTest.java index 94e8ea7..7a40f3c 100644 --- a/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/SessionCheckerTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/core/util/objects/checker/SessionCheckerTest.java @@ -16,10 +16,14 @@ */ package org.apache.wicket.core.util.objects.checker; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + import java.io.IOException; import java.io.ObjectOutputStream; import java.io.OutputStream; +import org.apache.wicket.MockPageWithOneComponent; import org.apache.wicket.Session; import org.apache.wicket.markup.html.WebComponent; import org.apache.wicket.markup.html.WebMarkupContainer; @@ -53,15 +57,36 @@ public class SessionCheckerTest extends WicketTestCase } }; - WebMarkupContainer container = new WebMarkupContainer("container"); + MockPageWithOneComponent page = new MockPageWithOneComponent(); + WebMarkupContainer container = new WebMarkupContainer(MockPageWithOneComponent.COMPONENT_ID); + page.add(container); // WICKET-6196 force container#children to be an array container.add(new Label("id1")); container.add(new ComponentWithAReferenceToTheSession("id2")); - byte[] serialized = serializer.serialize(container); + byte[] serialized = serializer.serialize(page); assertNull("The produced byte[] must be null if there was an error", serialized); } + /** + * https://issues.apache.org/jira/browse/WICKET-6334 + */ + @Test + public void sessionCheckerShouldNotCheckSerializationOfTheSessionItself() { + JavaSerializer serializer = new JavaSerializer("JavaSerializerTest") + { + @Override + protected ObjectOutputStream newObjectOutputStream(OutputStream out) throws IOException + { + IObjectChecker checker = new SessionChecker(); + return new CheckingObjectOutputStream(out, checker); + } + }; + final Session session = new WebSession(new MockWebRequest(Url.parse(""))); + final byte[] serialized = serializer.serialize(session); + assertThat(serialized, is(notNullValue())); + } + private static class ComponentWithAReferenceToTheSession extends WebComponent { private final Session member = new WebSession(new MockWebRequest(Url.parse(""))); http://git-wip-us.apache.org/repos/asf/wicket/blob/8b6fcd86/wicket-core/src/test/java/org/apache/wicket/serialize/java/JavaSerializerTest.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/serialize/java/JavaSerializerTest.java b/wicket-core/src/test/java/org/apache/wicket/serialize/java/JavaSerializerTest.java index c90414c..7c09701 100644 --- a/wicket-core/src/test/java/org/apache/wicket/serialize/java/JavaSerializerTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/serialize/java/JavaSerializerTest.java @@ -29,11 +29,7 @@ import java.io.Serializable; import org.apache.wicket.WicketRuntimeException; import org.apache.wicket.core.util.objects.checker.CheckingObjectOutputStream; -import org.apache.wicket.core.util.objects.checker.IObjectChecker; -import org.apache.wicket.core.util.objects.checker.NotDetachedModelChecker; import org.apache.wicket.markup.html.WebComponent; -import org.apache.wicket.model.IModel; -import org.apache.wicket.model.LoadableDetachableModel; import org.apache.wicket.util.io.IOUtils; import org.apache.wicket.util.tester.WicketTestCase; import org.junit.Test; @@ -45,45 +41,6 @@ public class JavaSerializerTest extends WicketTestCase { /** * https://issues.apache.org/jira/browse/WICKET-4812 - * - * Tests that the serialization fails when a checking ObjectOutputStream is - * used with NotDetachedModelChecker and there is a non-detached LoadableDetachableModel - * in the object tree. - */ - @Test - public void notDetachedModel() - { - JavaSerializer serializer = new JavaSerializer("JavaSerializerTest") - { - @Override - protected ObjectOutputStream newObjectOutputStream(OutputStream out) throws IOException - { - IObjectChecker checker = new NotDetachedModelChecker(); - return new CheckingObjectOutputStream(out, checker); - } - }; - - IModel<String> model = new NotDetachedModel(); - model.getObject(); - WebComponent component = new WebComponent("id", model); - byte[] serialized = serializer.serialize(component); - assertNull("The produced byte[] must be null if there was an error", serialized); - } - - /** - * A Model used for #notDetachedModel() test - */ - private static class NotDetachedModel extends LoadableDetachableModel<String> - { - @Override - protected String load() - { - return "loaded"; - } - } - - /** - * https://issues.apache.org/jira/browse/WICKET-4812 * * Tests that serialization fails when using the default ObjectOutputStream in * JavaSerializer and some object in the tree is not Serializable http://git-wip-us.apache.org/repos/asf/wicket/blob/8b6fcd86/wicket-core/src/test/java/org/apache/wicket/util/io/SerializableCheckerTest.java ---------------------------------------------------------------------- diff --git a/wicket-core/src/test/java/org/apache/wicket/util/io/SerializableCheckerTest.java b/wicket-core/src/test/java/org/apache/wicket/util/io/SerializableCheckerTest.java index 0fdce37..171caf1 100644 --- a/wicket-core/src/test/java/org/apache/wicket/util/io/SerializableCheckerTest.java +++ b/wicket-core/src/test/java/org/apache/wicket/util/io/SerializableCheckerTest.java @@ -21,23 +21,20 @@ import static org.hamcrest.Matchers.is; import java.io.IOException; import java.io.NotSerializableException; import java.io.Serializable; -import java.util.Map; -import java.util.Set; -import org.apache.wicket.core.util.objects.checker.CheckingObjectOutputStream; -import org.apache.wicket.core.util.objects.checker.ObjectSerializationChecker; import org.apache.wicket.core.util.objects.checker.AbstractObjectChecker; import org.apache.wicket.core.util.objects.checker.CheckingObjectOutputStream; -import org.apache.wicket.core.util.objects.checker.IObjectChecker; +import org.apache.wicket.core.util.objects.checker.ObjectSerializationChecker; +import org.apache.wicket.markup.html.WebPage; +import org.apache.wicket.page.IManageablePage; +import org.apache.wicket.util.tester.WicketTestCase; import org.apache.wicket.util.value.ValueMap; -import org.hamcrest.Matchers; -import org.junit.Assert; import org.junit.Test; /** * @author Pedro Santos */ -public class SerializableCheckerTest extends Assert +public class SerializableCheckerTest extends WicketTestCase { /** @@ -120,7 +117,33 @@ public class SerializableCheckerTest extends Assert assertTrue(exceptionMessage.contains(NonSerializableType.class.getName())); } - private static class IdentityTestType implements Serializable + private static class ManageablePage implements IManageablePage + { + @Override + public boolean isPageStateless() + { + return false; + } + + @Override + public int getPageId() + { + return 0; + } + + @Override + public void detach() + { + } + + @Override + public boolean setFreezePageId(boolean freeze) + { + return false; + } + } + + private static class IdentityTestType extends ManageablePage { private static final long serialVersionUID = 1L; @@ -133,7 +156,7 @@ public class SerializableCheckerTest extends Assert } } - private static class TestType2 implements Serializable + private static class TestType2 extends WebPage { private static final long serialVersionUID = 1L; ProblematicType problematicType = new ProblematicType(); http://git-wip-us.apache.org/repos/asf/wicket/blob/8b6fcd86/wicket-devutils/src/test/java/org/apache/wicket/devutils/inspector/SessionSizeModelTest.java ---------------------------------------------------------------------- diff --git a/wicket-devutils/src/test/java/org/apache/wicket/devutils/inspector/SessionSizeModelTest.java b/wicket-devutils/src/test/java/org/apache/wicket/devutils/inspector/SessionSizeModelTest.java index af5b583..3af0218 100644 --- a/wicket-devutils/src/test/java/org/apache/wicket/devutils/inspector/SessionSizeModelTest.java +++ b/wicket-devutils/src/test/java/org/apache/wicket/devutils/inspector/SessionSizeModelTest.java @@ -16,6 +16,8 @@ */ package org.apache.wicket.devutils.inspector; +import static org.hamcrest.Matchers.containsString; + import org.apache.wicket.Session; import org.apache.wicket.mock.MockApplication; import org.apache.wicket.protocol.http.WebSession; @@ -23,13 +25,17 @@ import org.apache.wicket.request.Request; import org.apache.wicket.request.Response; import org.apache.wicket.util.tester.WicketTester; import org.junit.Assert; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; /** * @author Pedro Santos */ public class SessionSizeModelTest extends Assert { + @Rule + public ExpectedException expectedException = ExpectedException.none(); /** * @see <a href="https://issues.apache.org/jira/browse/WICKET-3355">WICKET-3355</a> @@ -37,6 +43,11 @@ public class SessionSizeModelTest extends Assert @Test public void testToleranceOnProblematicSessions() { + expectedException.expect(IllegalStateException.class); + expectedException.expectMessage(containsString("A problem occurred while serializing an object. " + + "Please check the earlier logs for more details. Problematic object: " + + "org.apache.wicket.devutils.inspector.SessionSizeModelTest$TestSession")); + new WicketTester(new MockApplication() { @Override @@ -46,7 +57,7 @@ public class SessionSizeModelTest extends Assert } }); SessionSizeModel model = new SessionSizeModel(); - assertEquals(null, model.getObject()); + model.getObject(); } /**
