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 <[email protected]>
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>