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 6661642ca TAP5-2786: don't override final method in subclass
6661642ca is described below

commit 6661642ca1d662bb084d5addb6dae082ae830898
Author: Thiago H. de Paula Figueiredo <thi...@arsmachina.com.br>
AuthorDate: Sat Aug 24 15:57:24 2024 -0300

    TAP5-2786: don't override final method in subclass
    
    when in multiple classloader mode
---
 .../internal/plastic/PlasticFieldImpl.java         |  2 +-
 .../plastic/MethodAlreadyExistsException.java      | 35 ++++++++++++++++
 .../tapestry5/internal/transform/CachedWorker.java | 14 ++++++-
 .../internal/transform/PropertyWorker.java         | 11 ++++-
 .../components/SubclassWithFinalCachedMethod.java  | 36 +++++++++++++++++
 .../SuperclassWithFinalCachedMethod.java           | 47 ++++++++++++++++++++++
 .../pages/SubclassWithFinalCachedMethodDemo.java   | 19 +++++++++
 .../components/SuperclassWithFinalCachedMethod.tml | 12 ++++++
 .../pages/SubclassWithFinalCachedMethodDemo.tml    | 10 +++++
 9 files changed, 183 insertions(+), 3 deletions(-)

diff --git 
a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticFieldImpl.java
 
b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticFieldImpl.java
index d490750d6..8b1fe9310 100644
--- 
a/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticFieldImpl.java
+++ 
b/plastic/src/main/java/org/apache/tapestry5/internal/plastic/PlasticFieldImpl.java
@@ -360,7 +360,7 @@ class PlasticFieldImpl extends PlasticMember implements 
PlasticField, Comparable
 
         if (plasticClass.inheritanceData.isImplemented(name, desc))
         {
-            throw new IllegalArgumentException(String.format(
+            throw new MethodAlreadyExistsException(String.format(
                     "Unable to create new accessor method %s on class %s as 
the method is already implemented.",
                     description.toString(), plasticClass.className));
         }
diff --git 
a/plastic/src/main/java/org/apache/tapestry5/plastic/MethodAlreadyExistsException.java
 
b/plastic/src/main/java/org/apache/tapestry5/plastic/MethodAlreadyExistsException.java
new file mode 100644
index 000000000..4f434ac8f
--- /dev/null
+++ 
b/plastic/src/main/java/org/apache/tapestry5/plastic/MethodAlreadyExistsException.java
@@ -0,0 +1,35 @@
+// Copyright 2024 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.plastic;
+
+/** 
+ * Exception raised when there's an attempt to create a method which
+ * already exists in a class.
+ * 
+ * This extends {@linkplain IllegalArgumentException} for backward 
compatibility.
+ * 
+ * @since 5.9.0
+ */
+public class MethodAlreadyExistsException extends IllegalArgumentException
+{
+
+    private static final long serialVersionUID = 1L;
+
+    public MethodAlreadyExistsException(String message) 
+    {
+        super(message);
+    }
+    
+}
diff --git 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/CachedWorker.java
 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/CachedWorker.java
index e5848dcd3..045188d09 100644
--- 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/CachedWorker.java
+++ 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/CachedWorker.java
@@ -36,6 +36,7 @@ import org.apache.tapestry5.services.TransformConstants;
 import org.apache.tapestry5.services.transform.ComponentClassTransformWorker2;
 import org.apache.tapestry5.services.transform.TransformationSupport;
 
+import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -219,7 +220,11 @@ public class CachedWorker implements 
ComponentClassTransformWorker2
         for (int i = 0; i < array.size(); i++)
         {
             final JSONObject jsonObject = array.getJSONObject(i);
-            methods.add(toPlasticMethod(jsonObject, plasticClass, 
extraMethodCachedWatchMap));
+            final PlasticMethod plasticMethod = toPlasticMethod(jsonObject, 
plasticClass, extraMethodCachedWatchMap);
+            if (plasticMethod != null)
+            {
+                methods.add(plasticMethod);
+            }
         }
         return methods;
     }
@@ -229,6 +234,13 @@ public class CachedWorker implements 
ComponentClassTransformWorker2
             Map<String, String> extraMethodCachedWatchMap) 
     {
         final int modifiers = jsonObject.getInt(MODIFIERS);
+        
+        // We cannot override final methods
+        if (Modifier.isFinal(modifiers)) 
+        {
+            return null;
+        }
+        
         final String returnType = jsonObject.getString(RETURN_TYPE);
         final String methodName = jsonObject.getString(NAME);
         final String genericSignature = 
jsonObject.getStringOrDefault(GENERIC_SIGNATURE, null);
diff --git 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PropertyWorker.java
 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PropertyWorker.java
index bc95f6f4b..05677467c 100644
--- 
a/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PropertyWorker.java
+++ 
b/tapestry-core/src/main/java/org/apache/tapestry5/internal/transform/PropertyWorker.java
@@ -16,6 +16,7 @@ package org.apache.tapestry5.internal.transform;
 
 import org.apache.tapestry5.annotations.Property;
 import org.apache.tapestry5.model.MutableComponentModel;
+import org.apache.tapestry5.plastic.MethodAlreadyExistsException;
 import org.apache.tapestry5.plastic.PlasticClass;
 import org.apache.tapestry5.plastic.PlasticField;
 import org.apache.tapestry5.plastic.PropertyAccessType;
@@ -36,7 +37,15 @@ public class PropertyWorker implements 
ComponentClassTransformWorker2
     {
         for (PlasticField field : 
plasticClass.getFieldsWithAnnotation(Property.class))
         {
-            createAccessorsForField(field);
+            try
+            {
+                createAccessorsForField(field);
+            }
+            catch (MethodAlreadyExistsException e)
+            {
+                // Method was already created somewhere else, so
+                // nothing to do here
+            }
         }
     }
 
diff --git 
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SubclassWithFinalCachedMethod.java
 
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SubclassWithFinalCachedMethod.java
new file mode 100644
index 000000000..e556d17f1
--- /dev/null
+++ 
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SubclassWithFinalCachedMethod.java
@@ -0,0 +1,36 @@
+// Copyright 2024 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.integration.app1.components;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.tapestry5.annotations.Property;
+
+public class SubclassWithFinalCachedMethod extends 
SuperclassWithFinalCachedMethod
+{
+    
+    @Property
+    private int clientId = 2;
+    
+    private int counter = 10;
+    
+    @Override
+    protected List<?> createList() 
+    {
+        return Arrays.asList("subclass", String.valueOf(counter++));
+    }
+    
+}
diff --git 
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SuperclassWithFinalCachedMethod.java
 
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SuperclassWithFinalCachedMethod.java
new file mode 100644
index 000000000..fbe026c8f
--- /dev/null
+++ 
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/components/SuperclassWithFinalCachedMethod.java
@@ -0,0 +1,47 @@
+// Copyright 2024 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.integration.app1.components;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.tapestry5.annotations.Cached;
+import org.apache.tapestry5.annotations.Property;
+
+public class SuperclassWithFinalCachedMethod
+{
+    
+    @Property
+    private int clientId = 1;
+    
+    private int counter = 0;
+    
+    @Cached(watch = "clientId")
+    protected final List<?> getList() 
+    {
+        return createList();
+    }
+
+    protected List<?> createList() 
+    {
+        return Arrays.asList("superclass", String.valueOf(counter++));
+    }
+    
+    public final List<?> getListPublic() 
+    {
+        return getList();
+    }
+    
+}
diff --git 
a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/SubclassWithFinalCachedMethodDemo.java
 
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/SubclassWithFinalCachedMethodDemo.java
new file mode 100644
index 000000000..64f64bd43
--- /dev/null
+++ 
b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/SubclassWithFinalCachedMethodDemo.java
@@ -0,0 +1,19 @@
+// Copyright 2024 The Apache Software Foundation
+//
+// Licensed 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.tapestry5.integration.app1.pages;
+
+public class SubclassWithFinalCachedMethodDemo
+{
+}
diff --git 
a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/SuperclassWithFinalCachedMethod.tml
 
b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/SuperclassWithFinalCachedMethod.tml
new file mode 100644
index 000000000..80c393ab1
--- /dev/null
+++ 
b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/components/SuperclassWithFinalCachedMethod.tml
@@ -0,0 +1,12 @@
+<t:container
+        xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";>
+       <p>
+               Client id: ${clientId}.
+       </p>
+       <p>
+               List: ${listPublic}.
+       </p>
+       <p>
+               List: ${listPublic}.
+       </p>
+</t:container>
\ No newline at end of file
diff --git 
a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/SubclassWithFinalCachedMethodDemo.tml
 
b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/SubclassWithFinalCachedMethodDemo.tml
new file mode 100644
index 000000000..bd1c273fd
--- /dev/null
+++ 
b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/SubclassWithFinalCachedMethodDemo.tml
@@ -0,0 +1,10 @@
+<html t:type="Border" 
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd";>
+    <h1>Trigger Demo</h1>
+
+       <h3>Superclass:</h3>    
+    <t:superclassWithFinalCachedMethod/>
+
+       <h3>Subclass:</h3>    
+    <t:subclassWithFinalCachedMethod/>
+    
+</html>

Reply via email to