You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2019/10/31 07:36:45 UTC

[isis] branch v2 updated: ISIS-2158: silence PartialPageUpdate warnings for demo-app

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch v2
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/v2 by this push:
     new 04c9db9  ISIS-2158: silence PartialPageUpdate warnings for demo-app
04c9db9 is described below

commit 04c9db942263d8111de05bad283952a18700711c
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Oct 31 08:36:29 2019 +0100

    ISIS-2158: silence PartialPageUpdate warnings for demo-app
    
    we do this by providing a log4j2-spring.xml in applications'
    src/main/resources
---
 .../org/apache/isis/config/IsisConfigModule.java   |  23 -----
 .../java/org/apache/isis/config/IsisPresets.java   |   2 +
 .../resources/presets/SilenceWicket.properties     |  22 +++++
 .../components/actions/ActionParametersForm.java   |   1 +
 .../entity/icontitle/EntityIconAndTitlePanel.java  |   2 +-
 ...RepeatingViewWithDynamicallyVisibleContent.java |   6 +-
 .../isisapplib/IsisBlobOrClobPanelAbstract.java    |   4 +-
 .../scalars/reference/ReferencePanel.java          |   1 -
 .../widgets/buttons/ContainedButtonPanel.java      |   4 +-
 .../wicket/ui/panels/FormExecutorDefault.java      | 103 ++++++++++-----------
 .../isis/viewer/wicket/ui/panels/PanelBase.java    |   1 -
 .../wicket/ui/panels/PromptFormAbstract.java       |  13 +--
 .../isis/viewer/wicket/ui/util/Components.java     |  37 ++++++++
 .../domainapp/application/DemoAppManifest.java     |  10 ++
 .../apps/demo/src/main/resources/log4j2-spring.xml |  42 +++++++++
 .../isis/testdomain/logging/LoggerSetupTest.java   |  58 ++++++++++++
 16 files changed, 230 insertions(+), 99 deletions(-)

diff --git a/core/config/src/main/java/org/apache/isis/config/IsisConfigModule.java b/core/config/src/main/java/org/apache/isis/config/IsisConfigModule.java
index 1582223..83b382c 100644
--- a/core/config/src/main/java/org/apache/isis/config/IsisConfigModule.java
+++ b/core/config/src/main/java/org/apache/isis/config/IsisConfigModule.java
@@ -43,28 +43,5 @@ public class IsisConfigModule {
     public Map<String, String> getAsMap() {
         return new HashMap<>();
     }
-    
-//    /** @deprecated this is just a historical workaround */
-//    @Bean @Singleton
-//    public IsisConfigurationLegacy getConfigurationLegacy(
-//            ConfigurableEnvironment configurableEnvironment,
-//            IsisSystemEnvironment isisSystemEnvironment) {
-//        
-//        _Config.clear();
-//        
-//        val rawKeyValueMap = isisSystemEnvironment.getIocContainer()
-//                .copyEnvironmentToMap(configurableEnvironment);
-//        _Config.putAll(rawKeyValueMap);
-//
-//        log.info("Spring's context was passed over to Isis");
-//
-//        // dump config to log
-//        if(log.isInfoEnabled() && !isisSystemEnvironment.isUnitTesting()) {
-//            log.info("\n" + _Config.getConfiguration().toStringFormatted(isisSystemEnvironment));
-//        }    
-//        
-//        val isisConfigurationLegacy = _Config.getConfiguration(); // finalize config
-//        return isisConfigurationLegacy;
-//    }
 
 }
diff --git a/core/config/src/main/java/org/apache/isis/config/IsisPresets.java b/core/config/src/main/java/org/apache/isis/config/IsisPresets.java
index 1b2fbd3..e592896 100644
--- a/core/config/src/main/java/org/apache/isis/config/IsisPresets.java
+++ b/core/config/src/main/java/org/apache/isis/config/IsisPresets.java
@@ -45,6 +45,8 @@ public final class IsisPresets  {
     public static final String DebugMetaModel = "classpath:/presets/DebugMetaModel.properties";
     public static final String SilenceMetaModel = "classpath:/presets/SilenceMetaModel.properties";
     
+    public static final String SilenceWicket = "classpath:/presets/SilenceWicket.properties";
+    
     /**
      * @deprecated seems no longer required anyway
      */
diff --git a/core/config/src/main/resources/presets/SilenceWicket.properties b/core/config/src/main/resources/presets/SilenceWicket.properties
new file mode 100644
index 0000000..7862d5c
--- /dev/null
+++ b/core/config/src/main/resources/presets/SilenceWicket.properties
@@ -0,0 +1,22 @@
+#  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.
+
+
+# Seems to get picked up too late this way, instead use log4j2-spring.xml in applications' src/main/resources
+logging.level.org.apache.wicket.page.PartialPageUpdate = ERROR
+
+
diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersForm.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersForm.java
index e7c60e7..163744f 100644
--- a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersForm.java
+++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionParametersForm.java
@@ -22,6 +22,7 @@ import java.util.List;
 
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.Page;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.markup.html.WebMarkupContainer;
diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/icontitle/EntityIconAndTitlePanel.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/icontitle/EntityIconAndTitlePanel.java
index b65a243..a188d18 100644
--- a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/icontitle/EntityIconAndTitlePanel.java
+++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/icontitle/EntityIconAndTitlePanel.java
@@ -102,7 +102,7 @@ public class EntityIconAndTitlePanel extends PanelAbstract<ObjectAdapterModel> {
         final WebMarkupContainer entityLinkWrapper = addOrReplaceLinkWrapper(entityModel);
         addOrReplace(entityLinkWrapper);
     }
-
+    
     protected WebMarkupContainer addOrReplaceLinkWrapper(final ObjectAdapterModel entityModel) {
         val adapter = entityModel.getObject();
 
diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/col/RepeatingViewWithDynamicallyVisibleContent.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/col/RepeatingViewWithDynamicallyVisibleContent.java
index aaf61a1..11cef43 100644
--- a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/col/RepeatingViewWithDynamicallyVisibleContent.java
+++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/layout/bs3/col/RepeatingViewWithDynamicallyVisibleContent.java
@@ -24,7 +24,11 @@ import org.apache.wicket.markup.repeater.RepeatingView;
 
 import org.apache.isis.viewer.wicket.ui.panels.HasDynamicallyVisibleContent;
 
-public class RepeatingViewWithDynamicallyVisibleContent extends RepeatingView implements HasDynamicallyVisibleContent {
+public class RepeatingViewWithDynamicallyVisibleContent 
+extends RepeatingView 
+implements HasDynamicallyVisibleContent {
+
+    private static final long serialVersionUID = 1L;
 
     public RepeatingViewWithDynamicallyVisibleContent(final String id) {
         super(id);
diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobOrClobPanelAbstract.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobOrClobPanelAbstract.java
index 7a8e63d..b60aa64 100644
--- a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobOrClobPanelAbstract.java
+++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/isisapplib/IsisBlobOrClobPanelAbstract.java
@@ -301,9 +301,7 @@ public abstract class IsisBlobOrClobPanelAbstract<T extends NamedWithMimeType> e
 
         if(visibility != null) {
             component.setVisible(visibility == InputFieldVisibility.VISIBLE);
-            if (target != null) {
-                target.add(component);
-            }
+            Components.addToAjaxRequest(target, component);
         }
 
 
diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
index c9eb74e..c137a04 100644
--- a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
+++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/reference/ReferencePanel.java
@@ -34,7 +34,6 @@ import org.wicketstuff.select2.ChoiceProvider;
 import org.wicketstuff.select2.Settings;
 
 import org.apache.isis.commons.internal.collections._Lists;
-import org.apache.isis.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.metamodel.facets.object.autocomplete.AutoCompleteFacet;
 import org.apache.isis.metamodel.spec.ManagedObject;
 import org.apache.isis.metamodel.spec.ObjectSpecification;
diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.java
index 2d1f839..7c090c1 100644
--- a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.java
+++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/buttons/ContainedButtonPanel.java
@@ -31,6 +31,7 @@ import org.apache.wicket.model.Model;
 
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.viewer.wicket.ui.panels.PanelAbstract;
+import org.apache.isis.viewer.wicket.ui.util.Components;
 
 /**
  * A button contained within its own form.
@@ -62,8 +63,7 @@ public class ContainedButtonPanel extends PanelAbstract<Model<String>> {
                 ContainedButtonPanel.this.onSubmit();
                 if (target != null) {
                     for (final Component component : componentsToRerender) {
-                        //target.addComponent(component);
-                        target.add(component);
+                        Components.addToAjaxRequest(target, component);
                     }
                 }
             }
diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java
index ae79ba1..8729786 100644
--- a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java
+++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/FormExecutorDefault.java
@@ -18,9 +18,10 @@
  */
 package org.apache.isis.viewer.wicket.ui.panels;
 
-import java.util.List;
+import java.util.Collection;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -42,7 +43,7 @@ import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerComposite;
 import org.apache.isis.applib.services.hint.HintStore;
 import org.apache.isis.applib.services.message.MessageService;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
-import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.collections._Sets;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.metamodel.adapter.version.ConcurrencyException;
 import org.apache.isis.metamodel.facets.actions.redirect.RedirectFacet;
@@ -64,6 +65,7 @@ import org.apache.isis.viewer.wicket.model.models.ScalarModel;
 import org.apache.isis.viewer.wicket.ui.components.scalars.isisapplib.IsisBlobOrClobPanelAbstract;
 import org.apache.isis.viewer.wicket.ui.errors.JGrowlUtil;
 import org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage;
+import org.apache.isis.viewer.wicket.ui.util.Components;
 import org.apache.isis.webapp.context.IsisWebAppCommonContext;
 
 import lombok.val;
@@ -364,66 +366,55 @@ implements FormExecutor {
         requestCycle.setResponsePage(entityPage);
     }
 
+    
+    private static boolean shouldRedraw(final Component component) {
+        
+        // hmm... this doesn't work, because I think that the components
+        // get removed after they've been added to target.
+        // so.. still getting WARN log messages from XmlPartialPageUpdate
+
+        //                final Page page = component.findParent(Page.class);
+        //                if(page == null) {
+        //                    // as per logic in XmlPartialPageUpdate, this has already been
+        //                    // removed from page so don't attempt to redraw it
+        //                    return false;
+        //                }
+
+        final Object defaultModel = component.getDefaultModel();
+        if (!(defaultModel instanceof ScalarModel)) {
+            return true;
+        }
+        final ScalarModel scalarModel = (ScalarModel) defaultModel;
+        final UnchangingFacet unchangingFacet = scalarModel.getFacet(UnchangingFacet.class);
+        return unchangingFacet == null || ! unchangingFacet.value() ;
+    }
 
     private void addComponentsToRedraw(final AjaxRequestTarget target) {
-        final List<Component> componentsToRedraw = _Lists.newArrayList();
-        final List<Component> componentsNotToRedraw = _Lists.newArrayList();
+        final Set<Component> componentsToRedraw = _Sets.newHashSet();
+        final Set<Component> componentsNotToRedraw = _Sets.newHashSet();
 
         final Page page = target.getPage();
-        page.visitChildren(new IVisitor<Component, Object>() {
-            @Override
-            public void component(final Component component, final IVisit<Object> visit) {
-                if (component.getOutputMarkupId() && !(component instanceof Page)) {
-                    List<Component> listToAddTo =
-                            shouldRedraw(component)
-                            ? componentsToRedraw
-                                    : componentsNotToRedraw;
-                    listToAddTo.add(component);
-                }
+        page.visitChildren((component, visit) -> {
+            if (!Components.isRenderedComponent(component)){
+                return;
             }
-
-            private boolean shouldRedraw(final Component component) {
-
-                // hmm... this doesn't work, because I think that the components
-                // get removed after they've been added to target.
-                // so.. still getting WARN log messages from XmlPartialPageUpdate
-
-                //                final Page page = component.findParent(Page.class);
-                //                if(page == null) {
-                //                    // as per logic in XmlPartialPageUpdate, this has already been
-                //                    // removed from page so don't attempt to redraw it
-                //                    return false;
-                //                }
-
-                final Object defaultModel = component.getDefaultModel();
-                if (!(defaultModel instanceof ScalarModel)) {
-                    return true;
-                }
-                final ScalarModel scalarModel = (ScalarModel) defaultModel;
-                final UnchangingFacet unchangingFacet = scalarModel.getFacet(UnchangingFacet.class);
-                return unchangingFacet == null || ! unchangingFacet.value() ;
+            if(shouldRedraw(component)) {
+                componentsToRedraw.add(component);
+            } else {
+                componentsNotToRedraw.add(component);
             }
         });
 
-        for (Component componentNotToRedraw : componentsNotToRedraw) {
-            MarkupContainer parent = componentNotToRedraw.getParent();
-            while(parent != null) {
-                parent = parent.getParent();
-            }
+        for (Component component : componentsNotToRedraw) {
 
-            componentNotToRedraw.visitParents(MarkupContainer.class, new IVisitor<MarkupContainer, Object>() {
-                @Override
-                public void component(final MarkupContainer parent, final IVisit<Object> visit) {
-                    componentsToRedraw.remove(parent); // no-op if not in that list
-                }
+            component.visitParents(MarkupContainer.class, (parent, visit) -> {
+                componentsToRedraw.remove(parent); // no-op if not in that list
             });
-            if(componentNotToRedraw instanceof MarkupContainer) {
-                final MarkupContainer containerNotToRedraw = (MarkupContainer) componentNotToRedraw;
-                containerNotToRedraw.visitChildren(new IVisitor<Component, Object>() {
-                    @Override
-                    public void component(final Component parent, final IVisit<Object> visit) {
-                        componentsToRedraw.remove(parent); // no-op if not in that list
-                    }
+            
+            if(component instanceof MarkupContainer) {
+                val containerNotToRedraw = (MarkupContainer) component;
+                containerNotToRedraw.visitChildren((child, visit) -> {
+                        componentsToRedraw.remove(child); // no-op if not in that list
                 });
             }
         }
@@ -433,18 +424,18 @@ implements FormExecutor {
         }
 
         for (Component component : componentsToRedraw) {
-            target.add(component);
+            Components.addToAjaxRequest(target, component);
         }
     }
 
     private void debug(
-            final List<Component> componentsToRedraw,
-            final List<Component> componentsNotToRedraw) {
+            final Collection<Component> componentsToRedraw,
+            final Collection<Component> componentsNotToRedraw) {
         debug("Not redrawing", componentsNotToRedraw);
         debug("Redrawing", componentsToRedraw);
     }
 
-    private void debug(final String title, final List<Component> list) {
+    private void debug(final String title, final Collection<Component> list) {
         log.debug(">>> {}:", title);
         for (Component component : list) {
             log.debug(
diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PanelBase.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PanelBase.java
index 8f14538..f8837e5 100644
--- a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PanelBase.java
+++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PanelBase.java
@@ -64,7 +64,6 @@ public class PanelBase<T> extends GenericPanel<T> implements IsisWebAppCommonCon
         super(id, model);
     }
     
-    
     @Override
     public IsisWebAppCommonContext getCommonContext() {
         commonContext = CommonContextUtils.computeIfAbsent(commonContext);
diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java
index d9cd804..b15dc67 100644
--- a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java
+++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/panels/PromptFormAbstract.java
@@ -39,7 +39,6 @@ import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.util.string.AppendingStringBuffer;
 
 import org.apache.isis.commons.internal.collections._Lists;
-import org.apache.isis.commons.internal.exceptions._Exceptions.FluentException;
 import org.apache.isis.metamodel.spec.ManagedObject;
 import org.apache.isis.viewer.wicket.model.hints.UiHintContainer;
 import org.apache.isis.viewer.wicket.model.isis.WicketViewerSettings;
@@ -54,6 +53,7 @@ import org.apache.isis.viewer.wicket.ui.components.widgets.formcomponent.FormFee
 import org.apache.isis.viewer.wicket.ui.errors.JGrowlBehaviour;
 import org.apache.isis.viewer.wicket.ui.pages.PageAbstract;
 import org.apache.isis.viewer.wicket.ui.pages.entity.EntityPage;
+import org.apache.isis.viewer.wicket.ui.util.Components;
 
 public abstract class PromptFormAbstract<T extends BookmarkableModel<ManagedObject>
 & ParentEntityModelProvider
@@ -247,16 +247,7 @@ implements ScalarModelSubscriber2 {
             completePrompt(target);
 
             okButton.send(target.getPage(), Broadcast.EXACT, newCompletedEvent(target, form));
-            //TODO as of Wicket-8 we (for lack of a better solution) silently ignore java.lang.IllegalArgumentException:
-            // 'Cannot update component because its page is not the same as the one this handler has been created for.'
-
-            try {
-                target.add(form);
-            } catch (IllegalArgumentException cause) {
-                FluentException.of(cause)
-                .suppressIfMessageContains("Cannot update component because its page is not the same");
-            }
-
+            Components.addToAjaxRequest(target, form);
         }
 
     }
diff --git a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/Components.java b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/Components.java
index b33ff7b..b1a7522 100644
--- a/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/Components.java
+++ b/core/viewer-wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/util/Components.java
@@ -19,13 +19,24 @@
 
 package org.apache.isis.viewer.wicket.ui.util;
 
+import java.util.Set;
+
 import org.apache.wicket.Component;
 import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.Page;
+import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.page.PartialPageUpdate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import org.apache.isis.commons.internal.collections._Sets;
+import org.apache.isis.commons.internal.exceptions._Exceptions.FluentException;
 import org.apache.isis.viewer.wicket.ui.ComponentType;
 
+import lombok.val;
+
 public final class Components {
 
     private Components() {
@@ -85,5 +96,31 @@ public final class Components {
         final Component childComponent = container.get(wicketId);
         childComponent.setVisible(visibility);
     }
+    
+    public static boolean isRenderedComponent(final Component component) {
+        return (component.getOutputMarkupId() && !(component instanceof Page));
+    }
+
+    public static boolean hasPage(final Component component) {
+        return component.findParent(Page.class)!=null;
+    }
+    
+    public static void addToAjaxRequest(AjaxRequestTarget target, Component component) {
+
+        if (target == null || component == null) {
+            return;
+        }
+        
+        //TODO as of Wicket-8 we (for lack of a better solution) silently ignore 
+        // java.lang.IllegalArgumentException ...
+       
+        try {
+            target.add(component);
+        } catch (IllegalArgumentException cause) {
+            FluentException.of(cause)
+            .suppressIfMessageContains("Cannot update component because its page is not the same");
+        }
+        
+    }
 
 }
diff --git a/examples/apps/demo/src/main/java/domainapp/application/DemoAppManifest.java b/examples/apps/demo/src/main/java/domainapp/application/DemoAppManifest.java
index 0bdf687..00c6cc9 100644
--- a/examples/apps/demo/src/main/java/domainapp/application/DemoAppManifest.java
+++ b/examples/apps/demo/src/main/java/domainapp/application/DemoAppManifest.java
@@ -20,6 +20,8 @@ package domainapp.application;
 
 import javax.inject.Singleton;
 
+import org.apache.wicket.page.PartialPageUpdate;
+import org.slf4j.LoggerFactory;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
@@ -28,6 +30,7 @@ import org.springframework.context.annotation.PropertySource;
 import org.springframework.context.annotation.PropertySources;
 import org.springframework.core.io.ClassPathResource;
 
+import org.apache.isis.commons.internal.assertions._Assert;
 import org.apache.isis.config.IsisPresets;
 import org.apache.isis.config.beans.WebAppConfigBean;
 import org.apache.isis.extensions.fixtures.IsisBootFixtures;
@@ -47,6 +50,7 @@ import org.apache.isis.viewer.wicket.viewer.IsisBootWebWicket;
 
 import domainapp.dom.DemoModule;
 import domainapp.utils.LibraryPreloadingService;
+import lombok.val;
 
 /**
  * Makes the integral parts of the 'demo' web application.
@@ -56,6 +60,7 @@ import domainapp.utils.LibraryPreloadingService;
     @PropertySource("classpath:/domainapp/application/isis-non-changing.properties"),
     @PropertySource(IsisPresets.HsqlDbInMemory),
     @PropertySource(IsisPresets.NoTranslations),
+    @PropertySource(IsisPresets.SilenceWicket),
 })
 @Import({
     IsisBoot.class,
@@ -85,6 +90,11 @@ public class DemoAppManifest {
 
     @Bean @Singleton
     public WebAppConfigBean webAppConfigBean() {
+        
+        val logger = LoggerFactory.getLogger(PartialPageUpdate.class);
+        _Assert.assertFalse("", logger.isWarnEnabled());
+        
+        
         return WebAppConfigBean.builder()
                 .menubarsLayoutXml(new ClassPathResource("menubars.layout.xml", this.getClass()))
                 .brandLogoHeader("/images/gift_48.png")
diff --git a/examples/apps/demo/src/main/resources/log4j2-spring.xml b/examples/apps/demo/src/main/resources/log4j2-spring.xml
new file mode 100644
index 0000000..08a5edb
--- /dev/null
+++ b/examples/apps/demo/src/main/resources/log4j2-spring.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN">
+	<Properties>
+		<Property name="PID">????</Property>
+		<Property name="LOG_EXCEPTION_CONVERSION_WORD">%xwEx</Property>
+		<Property name="LOG_LEVEL_PATTERN">%5p</Property>
+		<Property name="LOG_DATEFORMAT_PATTERN">yyyy-MM-dd HH:mm:ss.SSS</Property>
+		<Property name="CONSOLE_LOG_PATTERN">%clr{%d{${LOG_DATEFORMAT_PATTERN}}}{faint} %clr{${LOG_LEVEL_PATTERN}} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
+		<Property name="FILE_LOG_PATTERN">%d{${LOG_DATEFORMAT_PATTERN}} ${LOG_LEVEL_PATTERN} ${sys:PID} --- [%t] %-40.40c{1.} : %m%n${sys:LOG_EXCEPTION_CONVERSION_WORD}</Property>
+	</Properties>
+	<Appenders>
+		<Console name="Console" target="SYSTEM_OUT" follow="true">
+			<PatternLayout pattern="${sys:CONSOLE_LOG_PATTERN}" />
+		</Console>
+	</Appenders>
+	<Loggers>
+	
+		<!-- silence Wicket -->
+		<Logger name="org.apache.wicket.page.PartialPageUpdate" level="error" />
+	
+		<Logger name="org.apache.catalina.startup.DigesterFactory" level="error" />
+		<Logger name="org.apache.catalina.util.LifecycleBase" level="error" />
+		<Logger name="org.apache.coyote.http11.Http11NioProtocol" level="warn" />
+		<logger name="org.apache.sshd.common.util.SecurityUtils" level="warn"/>
+		<Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="warn" />
+		<Logger name="org.eclipse.jetty.util.component.AbstractLifeCycle" level="error" />
+		<Logger name="org.hibernate.validator.internal.util.Version" level="warn" />
+		<logger name="org.springframework.boot.actuate.endpoint.jmx" level="warn"/>
+		
+		<logger name="org.apache.directory" level="warn"/>
+		<logger name="org.apache.directory.api.ldap.model.entry.Value" level="off"/>
+		
+		<logger name="DataNucleus.Persistence" level="info"/>
+		<logger name="DataNucleus.Transaction" level="info"/>
+		<logger name="DataNucleus.Datastore.Schema" level="info"/>
+		<logger name="DataNucleus.Datastore.Native" level="info"/>
+		
+		<Root level="info">
+			<AppenderRef ref="Console" />
+		</Root>
+	</Loggers>
+</Configuration>
diff --git a/examples/smoketests/src/test/java/org/apache/isis/testdomain/logging/LoggerSetupTest.java b/examples/smoketests/src/test/java/org/apache/isis/testdomain/logging/LoggerSetupTest.java
new file mode 100644
index 0000000..e70da5d
--- /dev/null
+++ b/examples/smoketests/src/test/java/org/apache/isis/testdomain/logging/LoggerSetupTest.java
@@ -0,0 +1,58 @@
+/*
+ *  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.isis.testdomain.logging;
+
+import org.apache.wicket.page.PartialPageUpdate;
+import org.junit.jupiter.api.Test;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.TestPropertySource;
+
+import org.apache.isis.config.IsisPresets;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+import lombok.val;
+
+@SpringBootTest(
+        classes = { 
+                LoggerSetupTest.Config.class, 
+        },
+        properties = {
+        })
+@TestPropertySource({
+    IsisPresets.SilenceWicket
+})
+public class LoggerSetupTest {
+
+    @Configuration
+    static class Config {
+        
+    }
+    
+    @Test
+    void slf4jLoggers_shouldBeBridgedToWorkWithLog4j2() {
+        
+        val logger = LoggerFactory.getLogger(PartialPageUpdate.class);
+        assertFalse(logger.isWarnEnabled());
+        
+    }
+    
+}