GWT and Vaadin - variable is not a constructor stack - gwt

I have a strange error that I cannot make heads or tails of. A snippet of the error is below:
(TypeError): $wnd.EGeoXml is not a constructor stack: $jsInit([object Object],[object Object],null)
The actual lines of code is in GWT and looks like this:
private native void jsInit(JavaScriptObject map, String kmlFile) /*-{
var exml = new $wnd.EGeoXml("exml", map, kmlFile, {});
this.#com.example.client.EGeoXmlJava::ready(Lcom/google/gwt/core/client/JavaScriptObject;)(exml);
}-*/;
This code actually works when running as its own GWT project but when using this code with Vaadin, I get the constructor stack error. I'm positive the constructor exists. What I do not understand is why GWT thinks it's not a constructor? Thanks in advance.

You are calling it like new $wnd.EGeoXml(). The $wnd part looks bit weird to me. Is it necessary?
Anyway, if it is a problem only in Vaadin project, you might want check that the code resides in the right package. Remember that GWT wants the code to be in a package called .client. The server-side classes of Vaadin can be anywhere.

Related

GWT: JsArray and JavaScript object

Am facing an issue while trying to implement an example given over a website.
One of the methods in a class has a signature like this -
private void updateTable(JsArray prices) {....}
And am trying to invoke this method from another method as -
updateTable(JsonUtils.safeEval(response.getText()));
while doing this am seeing a compilation error as -
The method updateTable(JsArray) in the type StockWatcher is not applicable for the arguments (JavaScriptObject)
Though I have just used the exact code displayed in the website, am seeing this error. Not sure what needs to be done. Please help.
The problem has been fixed by making the following change -
updateTable((JsArray)JsonUtils.safeEval(response.getText()));
introduced a casting in the above statement.

Passing Java Array into JavaScript (via JSNI) and back out to Java results in null value

Scenario: I have a GWT web application running within a JavaFX WebView/WebEngine. I am able to pass Strings from GWT to JavaScript to JavaFX without any issues.
Problem: When passing an array of custom objects like Data[] in the same fashion, the result on the JavaFX side is null.
An example of what Data looks like:
public class Data extends Serializable
{
char[] name;
int code;
short bar;
}
Here's the code to send the data to JavaScript:
public static native void doNativeStuff(String id, Data[] data) /*-{
$wnd.javaInterface.doStuff(id, data);
}-*/;
I've verified in the debugger that the Java object being passed in is populated with data and looks good.
Now on the JavaFX side, I have the following code to add the javaInterface to the page:
JSObject win = (JSObject) engine.executeScript("window");
win.setMember("javaInterface", new JavaInterface());
I know that this works because I'm using it for other methods that pass only Strings and they work great.
public void doStuff(String id, Data[] data)
{
// Right here, id == "validId" and data == null
if (data != null)
{
... do what is needed ...
}
}
Note that the Data object is defined and accessible on both sides.
From the GWT documentation:
Incoming Java type How it appears to JavaScript code
Java array opaque value that can only be passed back into Java code
I'm not touching it in JavaScript at all and I'm only passing it through from Java->JavaScript->Java, but the final step appears to be what is failing.
I've spent the last few hours scouring Stack Overflow, Google, GWT groups, gwtproject.org, etc. But most all of the examples only show a single argument being passed through and almost none of them show a Java Array being used.
I'd much rather just pass the object through rather than going to->from JSON, but I did give that a try out of desperation. I tried to use GSON but it doesn't work on the GWT client side. I tried to use the GWT AutoBean Framework but my Data object isn't a valid bean (I think because of no default constructor) and I cannot change that at this time.
I'm not using any Long or long values.
I've seen examples like this:
#com.google.gwt.examples.JSNIExample::staticFoo(Ljava/lang/String;)(s);
But from what I can tell that's just for going from JavaScript to GWT over JSNI. I'm trying to go the other way. I also couldn't find an example of this for multiple arguments.
I'm sure that there is just a minor tweak here that I'm missing, but I haven't been able to figure it out just yet. Please let me know if you see something that I'm missing here.
opaque value that can only be passed back into Java code
I think this means you cannot pass Java array into JavaScript code.
Agree with jat. I used to provide support for the similar needs and I had to serialize the objects myself.
And you can pass multiple arguments like this (types of arguments are given just for example):
private native void doJSAction(MyClass handler)/*-{
// do smth in JS
// then call external non-static method
handler.#com.myclient.helper.MyClass::doMyAction(Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;Lcom/myclient/helper/MyClass;II)(jsNativeSmth, myString, handler, intA, intB);
}-*/;
where doMyAction is something like the following:
void doMyAction(JavaScriptObject jsObject, String s, MyClass instance, int a, int b)
I haven't played with JavaFX, but since it runs in a different VM and knows nothing about the GWT DevMode protocol (for example, a Java object is wrapped in a JS object that basically makes RPC calls to manipulate it), I am pretty sure you are going to have to serialize everything between GWT and JavaFX as Strings and primitives.

create and return gwt widget from java code

I am new to GWT and I need to reslove this problem. I need to create a widget with gwt-links. To make it happened, I need to fetch some data from an ontology, and then based on the result, create the graph. The problem is that, when I mix java code with gwt code it doesn't want to compile.
The question is, how do I create a widged explained above that will be placed in a http page?
The code looks like this now :
public class Example1 {
#Override
public void draw() {
// Create the elements
String ontology = Ontology.get(1);
Widget labelHello = new BoxLabel(ontology);
controller.addWidget(labelHello,25,115);
// Add DnD logic
PickupDragController dragController = new PickupDragController(controller.getView(), true);
dragController.makeDraggable(labelHello);
}
public Widget asWidget() {
return controller.getView();
}
}
the Ontology.get() doesn't want to compile.
GWT can't compile just any java code.
These are the packages that are emulated by GWT: pls read
The code that can't be translated to javascript, (the stuff that is not emulated) you must handle on the server side.
GWT projects uses three packages (by default)
com.myapp.client
com.myapp.shared
com.myapp.server
By default everything within the shared and client package will be compiled to JavaScript.
Every Class, which is imported into a Class, which is inside the shared and client package must be:
emulated by GWT
Compilable to GWT (and inside the client or shared package)
Compilable to GWT (and the package must be whitelists in *.gwt.xml)
Uf you code ISolver can be compiled to JavaScript you will have to create a module.gwt.xml and inheritt your project from this module. This may enable the GWT-compiler to compile ISolver (and its implementation) to JavaScript.
If your code can't be compiled to GWT you will have to write a remote-service to make the calculation.
I don't really want to compile the code to javascript. All i want to do is to create a GWT widget ( which is a graph).
To create the widget, I need to do some calculations and repository fetch. I dont want to translate it( repository fetching), I just need to use it in order to create the model of the graph.
Basically, this is something I want to do:
String l = Repository.getLabel(); // Some advanced calculations that use many JavaSE classes;
GWTWidget widget = new GWTWidget(l); // widget, that will be displayed on a page.
but when I put something in method onModuleLoad it doesn't compile.
This is probably a simple question, but I'm not really related with GWT and I'm forced to remake someone's work.
public void onModuleLoad() {
System.out.println("tes");
VerticalPanel mainPanel = new VerticalPanel();
RootPanel.get().add(mainPanel);
//
ISolver solver = null;
System.out.println("TEST2");
}
ERROR: Line 53: No source code is available for type pr.ISolver; did you forget to inherit a required module?
ERROR: Unable to find type 'client.Link'
ERROR: Hint: Previous compiler errors may have made this type unavailable
and other lines sthat start with " No source code..".
ISolver is an interface, but I dont want to translate it. I want to use it for calculations.

GWT Deferred binding failed for custom class: No class matching "..." in urn:import:

I am developing a couple of custom widgets that I would like to be able to use with UiBinder. Unfortunately I keep wasting my life away with chasing down the following error:
No class matching "..." in urn:import:...
This seems to be the catch-all exception that is thrown any time there is any error in the class that prevents the GWT compiler from processing it. This includes anything in the class's entire dependency tree.
To save myself and anyone of you who is running into the same issue some time and pain, let's compile a list here of the most unexpected and hard to find causes for this. I'll start with my latest one, which has made me decide to post this here.
I was using a CellList thusly:
private static RelationshipViewerUiBinder uiBinder = GWT.create(RelationshipViewerUiBinder.class);
#UiField(provided=true)
CellList<String> prioritisedDisplay;
public RelationshipViewer() {
prioritisedDisplay = new CellList<>(new TextCell());
initWidget(uiBinder.createAndBindUi(this));
}
note the Java 7 style <> on the CellList. Despite my IDE's protestations to the contrary, it turns out you DO need to explicitly say CellList< String> in that new call, or it wont compile and all you get is the above mentioned error. Thanks by the way, the existance of this question prompted me to scrutinise my code and probably saved me a couple of hours! This fixed it:
private static RelationshipViewerUiBinder uiBinder = GWT.create(RelationshipViewerUiBinder.class);
#UiField(provided=true)
CellList<String> prioritisedDisplay;
public RelationshipViewer() {
prioritisedDisplay = new CellList<String>(new TextCell());
initWidget(uiBinder.createAndBindUi(this));
}
I had written a component that used the GWT JSON functionality, but hadn't imported com.google.gwt.json.JSON into the module.
Thanks to your message here, this was only 2 hours down the drain...
I wrote a helper-class that this widget uses somewhere deep inside its dependency tree.
For this helper-class, I told Eclipse to auto-generate the hashCode() and equals(...) functions. The class contained a field of type double, for which Eclipse generates code that uses Double.doubleToLongBits().
Turns out GWT does not implement this method on its version of Double. But of course, neither does Eclipse detect this as a possible compile-error, nor does it cause any issues in Dev Mode if I use the widget inside the GWT-App's Java code rather than inside UiBinder.
3 hours down the drain... Great... Yay for helpful error messages.
UPDATE:
As of GWT 2.5.0 (RC1) GWT now supports Double.doubleToLongBits() rendering this particular error obsolete, but the general error mechanism of a missing JRE emulation remains and will probably manifest itself in a similarly unhelpful way.
I was trying to use a GwtQuery DragAndDropCellTree in a UiBinder .ui.xml, which was impossible as DragAndDropCellTree has no zero-arg constructor.
See more details

How do you handle instantiation of Messages classes in GWT?

I have a question on how you usually instantiate GWT Messages. I usually do this:
private static final GenericMessages GENERIC_MESSAGES = GWT.create(GenericMessages.class);
I usually do this in every class that uses the GenericMessages Interface, is this a nice thing to do, or should I create a MessagesSingleton that instantiates all my Messages interface and I just access it from there?
Thanks in advance.
You don't have to worry about it. The GWT compiler will replace all your GENERIC_MASSAGES inside the code.
Example:
If you have in your propert file:
applicationName=My Application
and in your java class like this:
label.setText(GENERIC_MESSAGES.applicationName());
in compilation time the gwt compiler will replace to
label.setText("My Application");
and will remove your variable.