This is an automated email from the ASF dual-hosted git repository. svenmeier pushed a commit to branch WICKET-6558-prevent-lock-after-detach in repository https://gitbox.apache.org/repos/asf/wicket.git
commit 7eb27f6cb47a1a69dc4eec8ed0ce4c9039a09318 Author: Sven Meier <svenme...@apache.org> AuthorDate: Wed Aug 14 11:13:19 2019 +0200 WICKET-6558 no lock after detach --- .../main/java/org/apache/wicket/Application.java | 19 ++++------------- .../src/main/java/org/apache/wicket/Session.java | 13 ++++++++++++ .../wicket/util/tester/BaseWicketTester.java | 24 ++++++++++++++-------- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/wicket-core/src/main/java/org/apache/wicket/Application.java b/wicket-core/src/main/java/org/apache/wicket/Application.java index dde8c38..d9b726a 100644 --- a/wicket-core/src/main/java/org/apache/wicket/Application.java +++ b/wicket-core/src/main/java/org/apache/wicket/Application.java @@ -1569,23 +1569,12 @@ public abstract class Application implements UnboundListener, IEventSink, IMetad @Override public void onDetach(final RequestCycle requestCycle) { - IPageManager pageManager; - - if (Session.exists()) - { - pageManager = Session.get().getPageManager(); - } else { - pageManager = internalGetPageManager(); - } - pageManager.detach(); + internalGetPageManager().detach(); - if (Application.exists()) + IRequestLogger requestLogger = getRequestLogger(); + if (requestLogger != null) { - IRequestLogger requestLogger = Application.get().getRequestLogger(); - if (requestLogger != null) - { - requestLogger.requestTime((System.currentTimeMillis() - requestCycle.getStartTime())); - } + requestLogger.requestTime((System.currentTimeMillis() - requestCycle.getStartTime())); } } }); 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 ac37e44..3080b2b 100644 --- a/wicket-core/src/main/java/org/apache/wicket/Session.java +++ b/wicket-core/src/main/java/org/apache/wicket/Session.java @@ -113,6 +113,12 @@ public abstract class Session implements IClusterable, IEventSink, IMetadataCont /** Logging object */ private static final Logger log = LoggerFactory.getLogger(Session.class); + /** records if pages have been unlocked for the current request */ + private static final MetaDataKey<Boolean> PAGES_UNLOCKED = new MetaDataKey<>() + { + private static final long serialVersionUID = 1L; + }; + /** records if session has been invalidated by the current request */ private static final MetaDataKey<Boolean> SESSION_INVALIDATED = new MetaDataKey<>() { @@ -670,6 +676,9 @@ public abstract class Session implements IClusterable, IEventSink, IMetadataCont { detachFeedback(); + pageAccessSynchronizer.get().unlockAllPages(); + RequestCycle.get().setMetaData(PAGES_UNLOCKED, true); + if (isSessionInvalidated()) { invalidateNow(); @@ -915,6 +924,10 @@ public abstract class Session implements IClusterable, IEventSink, IMetadataCont */ public final IPageManager getPageManager() { + if (Boolean.TRUE.equals(RequestCycle.get().getMetaData(PAGES_UNLOCKED))) { + throw new WicketRuntimeException("pages have already been unlocked - synchronized access is no longer possible"); + } + IPageManager manager = Application.get().internalGetPageManager(); return pageAccessSynchronizer.get().adapt(manager); } diff --git a/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java b/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java index 3cf02f9..c643baa 100644 --- a/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java +++ b/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java @@ -25,6 +25,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.nio.charset.Charset; import java.text.ParseException; +import java.time.Duration; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; @@ -123,14 +124,12 @@ import org.apache.wicket.request.mapper.IRequestMapperDelegate; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.request.resource.IResource; import org.apache.wicket.request.resource.ResourceReference; -import org.apache.wicket.settings.ApplicationSettings; import org.apache.wicket.settings.RequestCycleSettings.RenderStrategy; import org.apache.wicket.util.lang.Args; import org.apache.wicket.util.lang.Classes; import org.apache.wicket.util.lang.Generics; import org.apache.wicket.util.resource.StringResourceStream; import org.apache.wicket.util.string.Strings; -import java.time.Duration; import org.apache.wicket.util.visit.IVisit; import org.apache.wicket.util.visit.IVisitor; import org.slf4j.Logger; @@ -495,12 +494,21 @@ public class BaseWicketTester */ protected void cleanupFeedbackMessages(IFeedbackMessageFilter filter) { - ApplicationSettings applicationSettings = application.getApplicationSettings(); - IFeedbackMessageFilter old = applicationSettings.getFeedbackMessageCleanupFilter(); - applicationSettings.setFeedbackMessageCleanupFilter(filter); - getLastRenderedPage().detach(); - getSession().detach(); - applicationSettings.setFeedbackMessageCleanupFilter(old); + + IVisitor<Component, Void> clearer = new IVisitor<Component, Void>() + { + @Override + public void component(Component component, IVisit<Void> visit) + { + if (component.hasFeedbackMessage()) { + component.getFeedbackMessages().clear(filter); + } + } + }; + clearer.component(getLastRenderedPage(), null); + getLastRenderedPage().visitChildren(clearer); + + getSession().getFeedbackMessages().clear(filter); } /**