Skip to content

Commit

Permalink
TAP5-2786: don't override final method in subclass
Browse files Browse the repository at this point in the history
when in multiple classloader mode
  • Loading branch information
thiagohp committed Aug 24, 2024
1 parent 2ae8c39 commit 6661642
Show file tree
Hide file tree
Showing 9 changed files with 183 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ private void introduceAccessorMethod(String returnType, String name, String[] pa

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));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
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;
Expand Down Expand Up @@ -219,7 +220,11 @@ private Collection<PlasticMethod> toPlasticMethodList(String meta, PlasticClass
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;
}
Expand All @@ -229,6 +234,13 @@ private static PlasticMethod toPlasticMethod(JSONObject jsonObject, PlasticClass
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

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;
Expand All @@ -36,7 +37,15 @@ public void transform(PlasticClass plasticClass, TransformationSupport support,
{
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
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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++));
}

}
Original file line number Diff line number Diff line change
@@ -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();
}

}
Original file line number Diff line number Diff line change
@@ -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
{
}
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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>

0 comments on commit 6661642

Please sign in to comment.