My web page has a frameset and I'm getting a ClassCastException when
passing a Java object from a GWT widget in one from to a GWT widget in
another frame via JSNI.
Here is what I do:
1. I create two widgets (called "Sender" and "Receiver"), each in a
separate frame in the frameset.
2. The Receiver widget creates a native javascript function (called
"receive") and attaches it to "top".
3. The Sender method instantiates a MyObject object [MyObject is a
dumb little class that holds an int]
4. The Sender passes the MyObject object to the native receive
function via JSNI
5. The receive function then passes the MyObject object to the
Receiver widget
6. The Receiver widget prints out a message saying it's received the
object
When I try this I get this exception:
java.lang.ClassCastException
at java.lang.Class.cast(Class.java:2951)
at com.google.gwt.dev.shell.JsValueGlue.get(JsValueGlue.java:
122)
at
com.google.gwt.dev.shell.ie.SwtOleGlue.convertVariantsToObjects(SwtOleGlue.java:
57)
at
com.google.gwt.dev.shell.ie.IDispatchImpl.callMethod(IDispatchImpl.java:
119)
at
com.google.gwt.dev.shell.ie.IDispatchProxy.invoke(IDispatchProxy.java:
155)
at
com.google.gwt.dev.shell.ie.IDispatchImpl.Invoke(IDispatchImpl.java:
294)
at
com.google.gwt.dev.shell.ie.IDispatchImpl.method6(IDispatchImpl.java:
194)
at
org.eclipse.swt.internal.ole.win32.COMObject.callback6(COMObject.java:
117)
at org.eclipse.swt.internal.ole.win32.COM.VtblCall(Native
Method)
at
org.eclipse.swt.internal.ole.win32.IDispatch.Invoke(IDispatch.java:64)
at
org.eclipse.swt.ole.win32.OleAutomation.invoke(OleAutomation.java:493)
at
org.eclipse.swt.ole.win32.OleAutomation.invoke(OleAutomation.java:417)
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.doInvokeOnWindow(ModuleSpaceIE6.java:
67)
at
com.google.gwt.dev.shell.ie.ModuleSpaceIE6.doInvoke(ModuleSpaceIE6.java:
152)
at
com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:
447)
at
com.google.gwt.dev.shell.ModuleSpace.invokeNativeVoid(ModuleSpace.java:
248)
at
com.google.gwt.dev.shell.JavaScriptHost.invokeNativeVoid(JavaScriptHost.java:
107)
at test.frames.client.Sender.sendNative(Sender.java)
at test.frames.client.Sender.send(Sender.java:24)
at test.frames.client.Sender.access$0(Sender.java:22)
at test.frames.client.Sender$1.onClick(Sender.java:16)
...
Notes:
1. This only happens in hosted mode. In web mode everything works
fine.
2. If I pass a Date or Integer or some other object whose class I
didn't define, everything works in both hosted mode and web mode.
2. When the Sender and Receiver live in the same html body (i.e. not
in different frames) everything works in both hosted mode and web
mode.
3. I am using GWT 1.5.2.
4. This stack trace looks very similar to that in
http://code.google.com/p/google-web-toolkit/issues/detail?id=2841, but
from the description it doesn't appear (to me) to be the same issue.
Below are my classes and html pages. Thanks for you help.
Wyatt
-------------------------------------
My EntryPoint class creates the appropriate Widget depending on which
frame it's in:
package test.frames.client;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.RootPanel;
public class FramesEntryPoint implements EntryPoint {
public void onModuleLoad() {
if (RootPanel.get("LeftFrame") != null) {
// This executes on the left side of Frames.html:
Sender sender = new Sender();
RootPanel.get().add(sender);
} else if (RootPanel.get("RightFrame") != null) {
// This executes on the right side of Frames.html:
Receiver receiver = new Receiver();
RootPanel.get().add(receiver);
} else if (RootPanel.get("Both") != null) {
// This only executes if you hit Both.html instead of
Frames.html:
Sender sender = new Sender();
Receiver receiver = new Receiver();
HorizontalPanel hp = new HorizontalPanel();
hp.add(sender);
hp.add(receiver);
RootPanel.get().add(hp);
}
}
-------------------------------------
This is the object that is passed from one frame to another:
package test.frames.client;
public class MyObject {
private int number;
public MyObject(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
}
-------------------------------------
The Sender creates a MyObject and sends it to the other frame:
package test.frames.client;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
public class Sender extends VerticalPanel {
private int messageNumber = 0;
public Sender() {
Button sendButton = new Button("Send");
sendButton.addClickListener(new ClickListener() {
public void onClick(Widget arg0) {
send();
}
});
add(sendButton);
}
private void send() {
MyObject myObject = new MyObject(messageNumber++);
sendNative(myObject);
}
private native void sendNative(MyObject myObject) /*-{
if (top.receive != null) {
top.receive(myObject);
}
}-*/;
}
-------------------------------------
The Receiver lives in the second frame and receives the MyObject:
package test.frames.client;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
class Receiver extends SimplePanel {
public Receiver() {
registerNativeFunction(this);
}
private native void registerNativeFunction(Receiver receiver) /*-{
top.receive = function (myObject) {
[EMAIL PROTECTED]::display(Ltest/
frames/client/MyObject;)(myObject);
};
}-*/;
private void display(MyObject myObject) {
setWidget(new Label("Message: "+myObject.getNumber()));
}
}
-------------------------------------
Frames.html: this is what you point the GWT shell at:
<html>
<head>
<title>GwtFrames</title>
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8">
</head>
<frameset cols="50%,50%">
<frame id="TheLeftFrame" src="Left.html"></frame>
<frame id="TheRightFrame" src="Right.html"></frame>
</frameset>
</html>
-------------------------------------
Left.html:
<html>
<head>
<meta name='gwt:module'
content='test.frames.FramesTest=test.frames.FramesTest'>
</head>
<body>
<script language="javascript" src="test.frames.FramesTest/
test.frames.FramesTest.nocache.js"></script>
<div id="LeftFrame"/>
</body>
</html>
-------------------------------------
Right.html:
<html>
<head>
<meta name='gwt:module'
content='test.frames.FramesTest=test.frames.FramesTest'>
</head>
<body>
<script language="javascript" src="test.frames.FramesTest/
test.frames.FramesTest.nocache.js"></script>
<div id="RightFrame"/>
</body>
</html>
-------------------------------------
Both.html: if you point the GWT shell at this (instead of at
Frames.html), both Sender and Receiver live in the same html body and
you don't see the error:
<html>
<head>
<meta name='gwt:module'
content='org.gwtsandbox.frames.Frames=org.gwtsandbox.frames.Frames'>
</head>
<body>
<script language="javascript"
src="org.gwtsandbox.frames.Frames/
org.gwtsandbox.frames.Frames.nocache.js"></script>
<div id="Both"/>
</body>
</html>
-------------------------------------
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Google Web Toolkit" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/Google-Web-Toolkit?hl=en
-~----------~----~----~----~------~----~------~--~---