Accessing a public field of a non-component object inside component code can 
result in a TransfomationException  if the accessed field matches a field of 
the component
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

                 Key: TAP5-1222
                 URL: https://issues.apache.org/jira/browse/TAP5-1222
             Project: Tapestry 5
          Issue Type: Bug
          Components: tapestry-core
    Affects Versions: 5.2.0
            Reporter: Howard M. Lewis Ship




java.lang.ClassNotFoundException
caught an exception while obtaining a class file for 
com.example.pages.category.CategoryIndex
exception
org.apache.tapestry5.ioc.internal.OperationException: 
javassist.CannotCompileException: [source error] _$get_category() not found in 
com.example.data.CategoryTreeNode
org.apache.tapestry5.ioc.internal.OperationException
javassist.CannotCompileException: [source error] _$get_category() not found in 
com.example.data.CategoryTreeNode
trace
Constructing instance of page class com.example.pages.category.CategoryIndex
Creating ComponentAssembler for com.example.pages.category.CategoryIndex
Transforming component class com.example.pages.category.CategoryIndex
org.apache.tapestry5.internal.services.TransformationException
javassist.CannotCompileException: [source error] _$get_category() not found in 
com.example.data.CategoryTreeNode

Checking field read category in method _$advised$getSubNodesForCurrentNode(): 
replacing with $_ = $0._$get_category();

        @Cached(watch = "currentNode")
        public List<CategoryTreeNode> getSubNodesForCurrentNode() {
                if (currentNode.category == null)
                        return Collections.emptyList();

                return buildNodesForCategory(currentNode.category);
        }



Because the CategoryIndex page has a field named "category", the transformation 
attempted to find it's replaced read access method, _$get_category(), in the 
non-component class (CategoryTreeNode).

The fault is in here:

 ExprEditor editor = new ExprEditor()
        {
            private final Set<CtBehavior> addedMethods = 
CollectionFactory.newSet();

            {
                for (TransformMethodImpl tmi : methods.values())
                {
                    if (tmi.added)
                        addedMethods.add(tmi.method);
                }
            }

            public void edit(FieldAccess access) throws CannotCompileException
            {
                CtBehavior where = access.where();

                if (where instanceof CtConstructor)
                    return;

                boolean isRead = access.isReader();
                String fieldName = access.getFieldName();
                CtMethod method = (CtMethod) where;

                formatter.format("Checking field %s %s in method %s(): ", 
isRead ? "read" : "write", fieldName,
                        method.getName());

                // Ignore any methods to were added as part of the 
transformation.
                // If we reference the field there, we really mean the field.

                if (addedMethods.contains(where))
                {
                    formatter.format("added method\n");
                    return;
                }

                Map<String, String> transformMap = isRead ? fieldReadTransforms 
: fieldWriteTransforms;

                String body = transformMap.get(fieldName);
                if (body == null)
                {
                    formatter.format("field not transformed\n");
                    return;
                }

                formatter.format("replacing with %s\n", body);

                access.replace(body);
            }
        };

Have to ensure that the field access is for a field of the component itself.  

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to