This is an automated email from the ASF dual-hosted git repository.
thiagohp pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tapestry-5.git
The following commit(s) were added to refs/heads/master by this push:
new 5c719e3f0 TAP5-2772: ClassCastException sometimes when in production
mode
5c719e3f0 is described below
commit 5c719e3f05dc3a206516658d4ad6781902b3aa98
Author: Thiago H. de Paula Figueiredo <[email protected]>
AuthorDate: Sun Mar 24 23:22:18 2024 -0300
TAP5-2772: ClassCastException sometimes when in production mode
---
.../services/ComponentDependencyRegistryImpl.java | 13 ++++---
.../services/ComponentInstantiatorSourceImpl.java | 3 +-
.../apache/tapestry5/modules/PageLoadModule.java | 14 ++++++++
.../PageClassLoaderContextManagerImpl.java | 40 ++++++++++++++--------
4 files changed, 50 insertions(+), 20 deletions(-)
diff --git
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistryImpl.java
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistryImpl.java
index 7f794f6ea..594cb72ef 100644
---
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistryImpl.java
+++
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentDependencyRegistryImpl.java
@@ -587,13 +587,16 @@ public class ComponentDependencyRegistryImpl implements
ComponentDependencyRegis
Objects.requireNonNull(dependency, "Parameter type cannot be null");
synchronized (map)
{
- Set<Dependency> dependents = map.get(dependency);
- if (dependents == null)
+ if (!component.equals(dependency))
{
- dependents = new HashSet<>();
- map.put(dependency, dependents);
+ Set<Dependency> dependents = map.get(dependency);
+ if (dependents == null)
+ {
+ dependents = new HashSet<>();
+ map.put(dependency, dependents);
+ }
+ dependents.add(new Dependency(component, type));
}
- dependents.add(new Dependency(component, type));
}
}
diff --git
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
index 1faeecf23..3573b474b 100644
---
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
+++
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
@@ -321,7 +321,8 @@ public final class ComponentInstantiatorSourceImpl
implements ComponentInstantia
if (rootPageClassloaderContext == null)
{
- logger.info("Initializing page pool. Multiple classloaders " +
(!productionMode && multipleClassLoaders ? "enabled" : "disabled") + ".");
+ logger.info("Initializing page pool. Production mode " +
(productionMode ? "enabled" : "disabled") +
+ ". Multiple classloaders " + (!productionMode &&
multipleClassLoaders ? "enabled" : "disabled") + ".");
pageClassLoaderContextManager.clear();
diff --git
a/tapestry-core/src/main/java/org/apache/tapestry5/modules/PageLoadModule.java
b/tapestry-core/src/main/java/org/apache/tapestry5/modules/PageLoadModule.java
index 5ca2f3715..ae6e76a77 100644
---
a/tapestry-core/src/main/java/org/apache/tapestry5/modules/PageLoadModule.java
+++
b/tapestry-core/src/main/java/org/apache/tapestry5/modules/PageLoadModule.java
@@ -31,6 +31,7 @@ import org.apache.tapestry5.internal.services.TemplateParser;
import org.apache.tapestry5.internal.services.assets.ResourceChangeTracker;
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.annotations.Marker;
+import org.apache.tapestry5.ioc.annotations.Order;
import org.apache.tapestry5.ioc.annotations.Startup;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.ioc.services.ChainBuilder;
@@ -87,6 +88,7 @@ public class PageLoadModule
}
@Startup
+ @Order("before:*")
public void preloadPageClassLoaderContexts(
PageClassLoaderContextManager pageClassLoaderContextManager,
ComponentDependencyRegistry componentDependencyRegistry,
@@ -104,6 +106,18 @@ public class PageLoadModule
}
}
}
+ // Preload the dependency information for all pages
+ // when in production mode. Without that, exceptions during
+ // page assembly will occurr. This should add just a few
+ // seconds to page initialization. If it takes too long,
+ // we can create a version of preload() that accepts a boolean
+ // parameter defining whether templates should be parsed or not
+ // (the exception occurrs when a superclass isn't loaded
+ // and transformed before a subclass)
+ else if (productionMode)
+ {
+ pageClassLoaderContextManager.preload();
+ }
}
public static PageCachingReferenceTypeService
buildPageCachingReferenceTypeService(
diff --git
a/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContextManagerImpl.java
b/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContextManagerImpl.java
index 5a9b52e39..dd437a3cf 100644
---
a/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContextManagerImpl.java
+++
b/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContextManagerImpl.java
@@ -58,6 +58,8 @@ public class PageClassLoaderContextManagerImpl implements
PageClassLoaderContext
private final boolean multipleClassLoaders;
+ private final boolean productionMode;
+
private final static ThreadLocal<Integer> NESTED_MERGE_COUNT =
ThreadLocal.withInitial(() -> 0);
private final static ThreadLocal<Boolean> INVALIDATING_CONTEXT =
ThreadLocal.withInitial(() -> false);
@@ -73,6 +75,7 @@ public class PageClassLoaderContextManagerImpl implements
PageClassLoaderContext
final ComponentClassResolver componentClassResolver,
final InternalComponentInvalidationEventHub invalidationHub,
final @ComponentClasses InvalidationEventHub
componentClassesInvalidationEventHub,
+ final @Symbol(SymbolConstants.PRODUCTION_MODE) boolean
productionMode,
final @Symbol(SymbolConstants.MULTIPLE_CLASSLOADERS) boolean
multipleClassLoaders)
{
super();
@@ -81,6 +84,7 @@ public class PageClassLoaderContextManagerImpl implements
PageClassLoaderContext
this.invalidationHub = invalidationHub;
this.componentClassesInvalidationEventHub =
componentClassesInvalidationEventHub;
this.multipleClassLoaders = multipleClassLoaders;
+ this.productionMode = productionMode;
invalidationHub.addInvalidationCallback(this::listen);
NESTED_MERGE_COUNT.set(0);
}
@@ -114,14 +118,11 @@ public class PageClassLoaderContextManagerImpl implements
PageClassLoaderContext
Objects.requireNonNull(plasticProxyFactoryProvider);
this.root = root;
this.plasticProxyFactoryProvider = plasticProxyFactoryProvider;
- if (multipleClassLoaders)
- {
- LOGGER.debug("Root context: {}", root);
- }
+ LOGGER.info("Root context: {}", root);
}
@Override
- public PageClassLoaderContext get(final String className)
+ public synchronized PageClassLoaderContext get(final String className)
{
PageClassLoaderContext context;
@@ -226,12 +227,9 @@ public class PageClassLoaderContextManagerImpl implements
PageClassLoaderContext
{
context = root;
} else {
- if (
+ if (!productionMode && (
!componentDependencyRegistry.contains(className) ||
- !multipleClassLoaders
- // TODO: review this
-// &&
componentDependencyRegistry.getDependents(className).isEmpty()
- )
+ !multipleClassLoaders))
{
context = unknownContextProvider.get();
}
@@ -273,7 +271,11 @@ public class PageClassLoaderContextManagerImpl implements
PageClassLoaderContext
}
}
- if (contextDependencies.size() == 0)
+ if (!multipleClassLoaders)
+ {
+ context = root;
+ }
+ else if (contextDependencies.size() == 0)
{
context = new PageClassLoaderContext(
getContextName(className),
@@ -300,8 +302,11 @@ public class PageClassLoaderContextManagerImpl implements
PageClassLoaderContext
plasticProxyFactoryProvider.apply(parentContext.getClassLoader()),
this::get);
}
-
- context.getParent().addChild(context);
+
+ if (multipleClassLoaders)
+ {
+ context.getParent().addChild(context);
+ }
// Ensure non-page class is initialized in the correct
context and classloader.
// Pages get their own context and classloader, so this
initialization
@@ -312,7 +317,10 @@ public class PageClassLoaderContextManagerImpl implements
PageClassLoaderContext
loadClass(className, context);
}
- LOGGER.debug("New context: {}", context);
+ if (multipleClassLoaders)
+ {
+ LOGGER.debug("New context: {}", context);
+ }
}
}
@@ -651,6 +659,10 @@ public class PageClassLoaderContextManagerImpl implements
PageClassLoaderContext
{
throw new RuntimeException(e);
}
+ catch (Exception e)
+ {
+ LOGGER.warn("Exception while preloading page " + page, e);
+ }
}
long finish = System.currentTimeMillis();