You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by "Benjamin Weidig (Jira)" <ji...@apache.org> on 2020/06/20 12:05:00 UTC
[jira] [Created] (TAP5-2630) java.lang.IllegalAccessError for
non-static final fields in Plastic classes
Benjamin Weidig created TAP5-2630:
-------------------------------------
Summary: java.lang.IllegalAccessError for non-static final fields in Plastic classes
Key: TAP5-2630
URL: https://issues.apache.org/jira/browse/TAP5-2630
Project: Tapestry 5
Issue Type: Bug
Components: plastic
Affects Versions: 5.5.0
Reporter: Benjamin Weidig
Plastic replaces the original constructor and moves the original instruction to the "initializeInstance" method in the new constructor. If any final field is present in the class, a "java.lang.IllegalAccessError" will be thrown.
Due to [JDK-8157181|[https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8157181]], it was possible to set final fields outside of "<init>", which is not allowed in the Java Language Specification
The problems originates from org.apache.tapestry5.internal.plastic.PlasticClassImpl.convertOriginalConstructorToMethod() in line 746.
To fix the problem, the "putfield" opcodes for final field should not be in the initializeInstance method, and should be called directly in "<init>" by the constructorBuilder.
I came up with the following code. Even though without a working project setup, it's hard to get it right.
{code:java}
private void stripOutPutfieldInstructions(MethodNode cons) {
InsnList ins = cons.instructions;
ListIterator li = ins.iterator();
while (li.hasNext()) {
AbstractInsnNode node = (AbstractInsnNode) li.next();
if (node.getOpcode() == Opcodes.PUTFIELD) {
FieldInsnNode fieldNode = (FieldInsnNode) node;
constructorBuilder.loadThis().putField(className, fieldNode.name, ???);
// Remove the PUTFIELD
li.remove();
break;
}
}
}
{code}
This would fix the field access problem but could introduce subtle bugs due to manipualting the call order of the original constructor instructions.
Instead, *ALL* remaining instructions need to be added to the constructorBuilder, and not moved to "initializeInstance".
I'm not that "fluent" in Plastic, or how it *exactly* creates classes/instances, so all of this might not work as I think it could. But hopefully, it helps to better understand the problem.
Most likely older versions of Tapestry are affected, too, because the JDK bug was backported to older versions.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)