History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: OGNL-11
Type: Bug Bug
Status: Reopened Reopened
Priority: Major Major
Assignee: Jesse Kuhnert
Reporter: Jesse Kuhnert
Votes: 2
Watchers: 3
Operations

If you were logged in you would be able to see more operations.
OGNL

ClassCastException in ASTChain

Created: 08/Mar/07 02:29 PM   Updated: 24/Nov/08 05:50 AM
Component/s: ExpressionCompiler
Affects Version/s: 2.7
Fix Version/s: 2.7

Environment: tapestry runtime


 Description  « Hide
The error expression was "value.section" on ImportPresentations page within the already compiled ASTChain expression....So this happend succesfully once but whatever class was being cast to didn't work for another value. (possible generics issue? )

 All   Comments   Change History      Sort Order:
Jesse Kuhnert - [11/Mar/07 04:52 PM ]
You provided insufficient data to re-produce. (shame on you)

Damien Uern - [10/Jul/07 01:47 AM ]
I have just updated from Tapestry 4.0 to 4.1.2 with OGNL 2.7 and I am having this same class cast exception on an ASTChain generated class, stack trace is here:

Caused by: java.lang.ClassCastException: com.jigsawpublications.common.tapestry.menu.ActionLinkNode
        at $ASTChain_113aed5c33f.get($ASTChain_113aed5c33f.java)
        at org.apache.tapestry.services.impl.ExpressionEvaluatorImpl.read(ExpressionEvaluatorImpl.java:142)

What we have in the component template looks like this:

<span jwcid="actionLink@Block">
<li>
<a jwcid="@DirectLink" listener="listener:callParentAction"
parameters="ognl:getNodeIter().getAction()"
href="#" title="ognl:nodeIter.title">
<span jwcid="@Insert" value="ognl:nodeIter.title" />
</a>
</li>
</span>

The nodeIter property on the component class is declared as follows:

public IMenuNode getNodeIter() { ....}

So what we have here is a list of objects all implementing this interface IMenuNode, and getNodeIter() returns the current iteration as set by the tapestry @For component. The class cast exception was on an ActionLinkNode which implements that interface. Other classes are PageLinkNode, RootNode and MenuNode. The *only* one that causes a problem seems to be the above @Block component, as another block:

<span jwcid="pageLink@Block">
<li>
<a jwcid="@PageLink" href="#" title="ognl:nodeIter.title"
page="ognl:nodeIter.page">
<span jwcid="@Insert" value="ognl:nodeIter.title" />
</a>
</li>
</span>

renders fine without any issue (these other blocks occur earlier in the page than the ActionLinkBlock). If I change the actionLink block to be the following (i.e. change the offending ognl expressions):

<span jwcid="actionLink@Block">
<li>
<a jwcid="@DirectLink" listener="listener:callParentAction"
parameters="ognl:'action'"
href="#" title="ognl:'title'">
<span jwcid="@Insert" value="ognl:'title'" />
</a>
</li>
</span>

Then I do not get an exception during the page render. This worked fine with the previous version of ognl we were using (2.6.7).

Please let me know if you require more information.


Peter Davison - [13/Sep/07 02:40 PM ]
I'm also experiencing the same ClassCastException but in a slightly different situation.

We have two different components on a page that share a common bean. This bean implements two different interfaces. Here's a code snippet:

@Component(type="Intelliware:MessagingRecipients", bindings={"value=ognl:emailMessage", "displayName=message:to"})
public abstract MessagingRecipients getMessagingRecipients();

@Component(type="Intelliware:MessagingAttachments", bindings={"value=ognl:emailMessage", "displayName=message:attachments"})
public abstract MessagingAttachments getMessagingAttachments();
...
@Persist()
public abstract EmailMessage getEmailMessage();
public abstract void setEmailMessage(EmailMessage emailMessage);


The class EmailMessage implements IMessagingRecipients and IMessagingAttachments. These two interfaces are mutually exclusive in the methods that they define.

The ClassCastException occurs on the second component definition:

Here's the stack trace:
An exception has occurred.

You may continue by restarting the session.
[ +/- ] Exception: Unable to read OGNL expression '<parsed OGNL expression>' of $MessagingAttachments_93@b40e4541[secure/messaging/ComposeSecureMessage/messagingAttachments]: ca.intelliware.bean.EmailMessage
org.apache.tapestry.BindingException
Unable to read OGNL expression '<parsed OGNL expression>' of $MessagingAttachments_93@b40e4541[secure/messaging/ComposeSecureMessage/messagingAttachments]: ca.intelliware.bean.EmailMessage
binding: ExpressionBinding[secure/messaging/ComposeSecureMessage/messagingAttachments attachmentsVO.existingAttachments]
location: Annotation @org.apache.tapestry.annotations.Component(inheritInformalParameters=false, type=For, bindings=[source=attachmentsVO.existingAttachments, value=currentExistingAttachment, converter=blobConverter], id=, copyOf=) of public abstract org.apache.tapestry.components.ForBean ca.intelliware.tapestry.component.messaging.MessagingAttachments.getExistingAttachmentFor()
 
[ +/- ] Exception: Unable to read OGNL expression '<parsed OGNL expression>' of $MessagingAttachments_93@b40e4541[secure/messaging/ComposeSecureMessage/messagingAttachments]: ca.intelliware.bean.EmailMessage
org.apache.hivemind.ApplicationRuntimeException
Unable to read OGNL expression '<parsed OGNL expression>' of $MessagingAttachments_93@b40e4541[secure/messaging/ComposeSecureMessage/messagingAttachments]: ca.intelliware.bean.EmailMessage
component: $MessagingAttachments_93@b40e4541[secure/messaging/ComposeSecureMessage/messagingAttachments]
location: Annotation @org.apache.tapestry.annotations.Component(inheritInformalParameters=false, type=Intelliware:MessagingAttachments, bindings=[value=emailMessage, displayName=message:attachments], id=, copyOf=) of public abstract ca.intelliware.tapestry.component.messaging.MessagingAttachments ca.intelliware.page.secure.messaging.ComposeSecureMessage.getMessagingAttachments()
 
[ +/- ] Exception: ca.intelliware.bean.EmailMessage
java.lang.ClassCastException
ca.intelliware.bean.EmailMessage
Stack Trace:

    * $ASTChain_114feb2716f.get($ASTChain_114feb2716f.java)
    * org.apache.tapestry.services.impl.ExpressionEvaluatorImpl.read(ExpressionEvaluatorImpl.java:142)
    * $ExpressionEvaluator_114feb26df8.read($ExpressionEvaluator_114feb26df8.java)
    * org.apache.tapestry.binding.ExpressionBinding.resolveExpression(ExpressionBinding.java:139)
    * org.apache.tapestry.binding.ExpressionBinding.getObject(ExpressionBinding.java:125)
    * org.apache.tapestry.components.ForBean.evaluateSourceIterator(ForBean.java:693)
    * org.apache.tapestry.components.ForBean.storeSourceData(ForBean.java:409)
    * org.apache.tapestry.components.ForBean.getData(ForBean.java:333)
    * org.apache.tapestry.components.ForBean.renderComponent(ForBean.java:130)
    * org.apache.tapestry.AbstractComponent.render(AbstractComponent.java:725)
    * org.apache.tapestry.services.impl.DefaultResponseBuilder.render(DefaultResponseBuilder.java:180)
    * org.apache.tapestry.BaseComponent.renderComponent(BaseComponent.java:107)
    * org.apache.tapestry.AbstractComponent.render(AbstractComponent.java:725)
    * org.apache.tapestry.services.impl.DefaultResponseBuilder.render(DefaultResponseBuilder.java:180)
    * org.apache.tapestry.AbstractComponent.renderBody(AbstractComponent.java:539)
    * org.apache.tapestry.form.FormSupportImpl.render(FormSupportImpl.java:502)
    * org.apache.tapestry.form.Form.renderComponent(Form.java:217)
    * org.apache.tapestry.AbstractComponent.render(AbstractComponent.java:725)
    * org.apache.tapestry.services.impl.DefaultResponseBuilder.render(DefaultResponseBuilder.java:180)
    * org.apache.tapestry.AbstractComponent.renderBody(AbstractComponent.java:539)
    * org.apache.tapestry.components.Block.renderForComponent(Block.java:65)
    * org.apache.tapestry.components.RenderBlock.renderComponent(RenderBlock.java:65)
    * org.apache.tapestry.AbstractComponent.render(AbstractComponent.java:725)
    * org.apache.tapestry.services.impl.DefaultResponseBuilder.render(DefaultResponseBuilder.java:180)
    * org.apache.tapestry.BaseComponent.renderComponent(BaseComponent.java:107)
    * org.apache.tapestry.AbstractComponent.render(AbstractComponent.java:725)
    * org.apache.tapestry.services.impl.DefaultResponseBuilder.render(DefaultResponseBuilder.java:180)
    * org.apache.tapestry.AbstractComponent.renderBody(AbstractComponent.java:539)
....

This probably doesn't provide enough information but I considering the similar symptoms but different conditions I thought that it might be useful.

Peter Davison - [17/Sep/07 11:13 AM ]
More on this...

Turns out the problem wasn't related to two components sharing the same bean after all.
The real problem was this:

We had two separate Tapestry pages that used the same component: MessageAttachments. This component uses a bean that implements a particular interface. In this case the interface was something like this:
public interface Foo {
  public void setUploads(List<File> uploads);
  public List<File> getAttachments();
  public List<File> getExistingAttachments();
}

We had two different beans that implemented this interface. One used in one of the pages and one in the other.
First of all the problem was difficult to find because it depended on which page was viewed first. In one case it would cause a ClassCastException and in the other it would work fine. The problem was related to how the beans were defined.
In one case, the bean that implemented the interface did so through inheritance rather than by directly implementing the required methods itself. If the page that used this bean was loaded first then the other page was viewed, the latter page would blow up with the ClassCastException.

The fix was to remove the class inheritance in the bean and have it implement the interface explicitly.

Hope this helps a bit.

Pete.

Karol Kraśkiewicz - [24/Nov/08 05:50 AM ]
I'm using tapestry 4.1.6 and ognl 2.7.3 and I had very similar problem. One component was used on several pages. this component used beans. Beans are different in every page, but have some common interfaces. Both beans have the same method, but this method was not declared in any interfaces.

When I opened one of pages, everything works well. when I opened second I had ClassCastException.

I solve this problem when I make interface, declare there the common method, and implement this interface by both beans' classes.
But I have got a feeling that is should work in different, simpler way.