Your code should work. The class cast exception indicates a bug (probably in ScriptablePropertyPointer). You should be able to pass _any_ Java or JavaScript object to sendPageAndWait(). I don't have time to look into this right now but my first guess would be to do remove the unwrap-ing code below. Rhino wraps normal Java objects with a Scriptable wrapper which JXPath associates with the ScriptablePropertyPointer, so I don't think it's correct to unwrap it.

ScriptablePropertyPointer.java:

public Object getImmediateNode() {
Object value;
if (index == WHOLE_COLLECTION) {
value = getBaseValue();
}
else {
value = getBaseValue();
if (value instanceof Scriptable) {
Object property =
ScriptableObject.getProperty((Scriptable)value, index);
if (property != ScriptableObject.NOT_FOUND) {
value = property; // hack?
}
} else {
return super.getImmediateNode();
}
}
if (value instanceof Wrapper) { <<- Delete this code
value = ((Wrapper)value).unwrap();
}
return value;
}


Per-Olof Noren wrote:

Hi Flowers,

for the impatient: actual questions at the bottom)
We're currently migrating from 2.1-dev from august last year to 2.1.2.
During this migration I ran into a ClassCastException.

In the pre-release code we use a snippet of javascript code that looks
like this:

function showConfirm(message){
var map = new Packages.java.util.HashMap();
map.put("msg", message);
sendPageAndWait("gemensam/showConfirm.view", map); }


We're using an Hashmap as a data container that is sent to the view,
which is an XSP-page (.view is an aggregating pipeline that puts menu
data into the view)

This causes the following Exception when this function is called:

Original Exception: java.lang.ClassCastException: java.util.HashMap
       at
org.apache.cocoon.components.flow.javascript.ScriptablePropertyHandler.getProperty(ScriptablePropertyHandler.java:61)
       at
org.apache.commons.jxpath.ri.model.dynamic.DynamicPropertyPointer.getBaseValue(DynamicPropertyPointer.java:199)
       at
org.apache.cocoon.components.flow.javascript.ScriptablePropertyPointer.isCollection(ScriptablePropertyPointer.java:163)
       at
org.apache.commons.jxpath.ri.axes.SimplePathInterpreter.doStepNoPredicatesPropertyOwner(SimplePathInterpreter.java:248)
       at
org.apache.commons.jxpath.ri.axes.SimplePathInterpreter.doStep(SimplePathInterpreter.java:187)
       at
org.apache.commons.jxpath.ri.axes.SimplePathInterpreter.interpretSimpleLocationPath(SimplePathInterpreter.java:122)
       at
org.apache.commons.jxpath.ri.compiler.Path.getSingleNodePointerForSteps(Path.java:186)
       at
org.apache.commons.jxpath.ri.compiler.LocationPath.computeValue(LocationPath.java:128)
       at
org.apache.commons.jxpath.ri.JXPathContextReferenceImpl.getValue(JXPathContextReferenceImpl.java:293)
       at
org.apache.commons.jxpath.ri.JXPathCompiledExpression.getValue(JXPathCompiledExpression.java:101)
       at
org.apache.cocoon.www.prisma.khs.artikel.artikel_show_xsp.generate(org.apache.cocoon.www.prisma.khs.artikel.artikel_show_xsp:507)
       at
org.apache.cocoon.generation.ServerPagesGenerator.generate(ServerPagesGenerator.java:260)
       at
org.apache.cocoon.components.pipeline.AbstractProcessingPipeline.processXMLPipeline(AbstractProcessingPipeline.java:532)
       at
org.apache.cocoon.components.pipeline.impl.AbstractCachingProcessingPipeline.processXMLPipeline(AbstractCachingProcessingPipeline.java:196)
       at
org.apache.cocoon.components.pipeline.AbstractProcessingPipeline.process(AbstractProcessingPipeline.java:683)
       at
org.apache.cocoon.components.source.impl.SitemapSource.toSAX(SitemapSource.java:467)
       at
org.apache.cocoon.components.source.SourceUtil.parse(SourceUtil.java:224)
       at
org.apache.cocoon.sitemap.ContentAggregator.generate(ContentAggregator.java:159)
       at
org.apache.cocoon.components.pipeline.AbstractProcessingPipeline.processXMLPipeline(AbstractProcessingPipeline.java:548)
       at
org.apache.cocoon.components.pipeline.impl.AbstractCachingProcessingPipeline.processXMLPipeline(AbstractCachingProcessingPipeline.java:196)
       at
org.apache.cocoon.components.pipeline.AbstractProcessingPipeline.process(AbstractProcessingPipeline.java:492)
       at
org.apache.cocoon.components.treeprocessor.sitemap.SerializeNode.invoke(SerializeNode.java:147)
       at
org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNode.invokeNodes(AbstractParentProcessingNode.java:84)
       at
org.apache.cocoon.components.treeprocessor.sitemap.PreparableMatchNode.invoke(PreparableMatchNode.java:164)
       at
org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNode.invokeNodes(AbstractParentProcessingNode.java:108)
       at
org.apache.cocoon.components.treeprocessor.sitemap.PipelineNode.invoke(PipelineNode.java:163)
       at
org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNode.invokeNodes(AbstractParentProcessingNode.java:108)
       at
org.apache.cocoon.components.treeprocessor.sitemap.PipelinesNode.invoke(PipelinesNode.java:161)
       at
org.apache.cocoon.components.treeprocessor.TreeProcessor.process(TreeProcessor.java:351)
       at
org.apache.cocoon.components.treeprocessor.TreeProcessor.handleCocoonRedirect(TreeProcessor.java:408)
       at
org.apache.cocoon.components.treeprocessor.TreeProcessor.process(TreeProcessor.java:360)
       at
org.apache.cocoon.components.treeprocessor.TreeProcessor.process(TreeProcessor.java:304)
       at
org.apache.cocoon.components.treeprocessor.sitemap.MountNode.invoke(MountNode.java:130)
       at
org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNode.invokeNodes(AbstractParentProcessingNode.java:84)
       at
org.apache.cocoon.components.treeprocessor.sitemap.PreparableMatchNode.invoke(PreparableMatchNode.java:164)
       at
org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNode.invokeNodes(AbstractParentProcessingNode.java:108)
       at
org.apache.cocoon.components.treeprocessor.sitemap.PipelineNode.invoke(PipelineNode.java:163)
       at
org.apache.cocoon.components.treeprocessor.AbstractParentProcessingNode.invokeNodes(AbstractParentProcessingNode.java:108)
       at
org.apache.cocoon.components.treeprocessor.sitemap.PipelinesNode.invoke(PipelinesNode.java:161)
       at
org.apache.cocoon.components.treeprocessor.TreeProcessor.process(TreeProcessor.java:351)
       at
org.apache.cocoon.components.treeprocessor.TreeProcessor.process(TreeProcessor.java:304)
       at org.apache.cocoon.Cocoon.process(Cocoon.java:640)
       at
org.apache.cocoon.servlet.CocoonServlet.service(CocoonServlet.java:1104)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
       at
org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:360)
       at
org.mortbay.jetty.servlet.WebApplicationHandler.dispatch(WebApplicationHandler.java:294)
       at
org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:558)
       at org.mortbay.http.HttpContext.handle(HttpContext.java:1714)
       at
org.mortbay.jetty.servlet.WebApplicationContext.handle(WebApplicationContext.java:507)
       at org.mortbay.http.HttpContext.handle(HttpContext.java:1664)
       at org.mortbay.http.HttpServer.service(HttpServer.java:863)
       at
org.mortbay.http.HttpConnection.service(HttpConnection.java:775)
       at
org.mortbay.http.HttpConnection.handleNext(HttpConnection.java:939)
       at
org.mortbay.http.HttpConnection.handle(HttpConnection.java:792)
       at
org.mortbay.http.SocketListener.handleConnection(SocketListener.java:201)
       at
org.mortbay.util.ThreadedServer.handle(ThreadedServer.java:289)
       at
org.mortbay.util.ThreadPool$PoolThread.run(ThreadPool.java:455)


I looked into the sources and found out that the code there assumes that the object sent in as an instance of ScriptableObject, which it isn't in this case.

public Object getProperty(Object obj, String propertyName) {
       Context cx = null;
       try {
           cx = Context.enter();
           Scriptable s = (Scriptable) obj;
       ....
}

I have unsuccessfully scanned maillists and wiki in the hunt for info
about whether this is a design or a miss-use from our side.

So, to the questions:

1. Is it supposed to be strict use of ScriptableObject as top-level
containers for data sent to the view?
2. If it is, can we agree on this behaviour and include it into to the
docs?
3. If isn't, should I submit a patch(assuming I'll be able to fix it:-)
) to HEAD?


Thanx in advance,


Per-Olof Nor�n
Curalia AB








Reply via email to