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

thiagohp pushed a commit to branch TAP5-2779
in repository https://gitbox.apache.org/repos/asf/tapestry-5.git

commit 3e675d6bbf967b4b8ce50e773fc54163b5b40360
Author: Thiago H. de Paula Figueiredo <[email protected]>
AuthorDate: Tue Jul 9 23:34:11 2024 -0300

    TAP5-2779: avoiding an infinite method call recursion bug
---
 .../internal/services/ComponentModelSourceImpl.java     |  9 ++++++---
 .../tapestry5/internal/services/PageSourceImpl.java     | 17 +++++++++++++++--
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentModelSourceImpl.java
 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentModelSourceImpl.java
index 918d05e87..dcbfbc47e 100644
--- 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentModelSourceImpl.java
+++ 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentModelSourceImpl.java
@@ -65,10 +65,13 @@ public class ComponentModelSourceImpl implements 
ComponentModelSource
                     {
                         
pageSource.getPage(resolver.getLogicalName(componentClassName));
                     }
-                    catch (Exception e)
+                    catch (IllegalStateException e)
                     {
-                        e.printStackTrace();
-                        //ignore
+                        // This can be thrown in PageSourceImpl in case an
+                        // infinite method call recursion is detected. In
+                        // that case, the page instance is already created,
+                        // so the objective of the line above is already
+                        // fulfilled and we can safely ignore the exception
                     }
                 }
             }
diff --git 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
index bc29a45af..38ab835fd 100644
--- 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
+++ 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
@@ -110,6 +110,9 @@ public class PageSourceImpl implements PageSource
     private final Map<CachedPageKey, Object> pageCache = 
CollectionFactory.newConcurrentMap();
     
     private final Map<String, Boolean> abstractClassInfoCache = 
CollectionFactory.newConcurrentMap();
+    
+    private final static ThreadLocal<String> CURRENT_PAGE = 
+            ThreadLocal.withInitial(() -> null);
 
     public PageSourceImpl(PageLoader pageLoader, 
ComponentRequestSelectorAnalyzer selectorAnalyzer,
             ComponentDependencyRegistry componentDependencyRegistry,
@@ -178,6 +181,15 @@ public class PageSourceImpl implements PageSource
             final String className = 
componentClassResolver.resolvePageNameToClassName(canonicalPageName);
             if (multipleClassLoaders)
             {
+                
+                if (canonicalPageName.equals(CURRENT_PAGE.get()))
+                {
+                    throw new IllegalStateException("Infinite method loop 
detected. Bailing out.");
+                }
+                else
+                {
+                    CURRENT_PAGE.set(canonicalPageName);
+                }
             
                 // Avoiding problems in PlasticClassPool.createTransformation()
                 // when the class being loaded has a page superclass
@@ -197,7 +209,7 @@ public class PageSourceImpl implements PageSource
                         final String resolvedDependencyPageClass = 
componentClassResolver.resolvePageNameToClassName(dependencyPageName);
                         if (!canonicalPageName.equals(dependencyPageName)
                                 && 
!className.equals(resolvedDependencyPageClass)
-                                && !isAbstract(className))
+                                && !isAbstract(dependencyClassName))
                         {
                             page = getPage(dependencyPageName, 
                                     invalidateUnknownContext, 
alreadyProcessed);
@@ -358,8 +370,9 @@ public class PageSourceImpl implements PageSource
     
     private boolean isAbstract(final String className)
     {
-        return abstractClassInfoCache.computeIfAbsent(className, 
+        final Boolean computeIfAbsent = 
abstractClassInfoCache.computeIfAbsent(className, 
                 (s) -> 
Modifier.isAbstract(ThrowawayClassLoader.load(className).getModifiers()));
+        return computeIfAbsent;
     }
     
 }

Reply via email to