You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by "Ben Weidig (Jira)" <ji...@apache.org> on 2021/03/22 07:41:00 UTC

[jira] [Assigned] (TAP5-2630) java.lang.IllegalAccessError for non-static final fields in Plastic classes

     [ https://issues.apache.org/jira/browse/TAP5-2630?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Ben Weidig reassigned TAP5-2630:
--------------------------------

    Assignee: Ben Weidig

> 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: Ben Weidig
>            Assignee: Ben Weidig
>            Priority: Minor
>
> 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)