Uploaded image for project: 'Tapestry 5'
  1. Tapestry 5
  2. TAP5-2630

java.lang.IllegalAccessError for non-static final fields in Plastic classes

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Minor
    • Resolution: Unresolved
    • 5.5.0
    • None
    • plastic
    • None

    Description

      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.

       

      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;
              }
          }
      }
      

       

      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.

      Attachments

        Activity

          People

            ben-ng Ben Weidig
            ben-ng Ben Weidig
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: