Is it possbile to do something with that ?
Is it possbile to avoid check-cast generation if the generic is used with @JsType type ?
Thanks
--
You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsub...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.
@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public abstract class ArrayBuffer { ... }
Try to annotate it withHope that helps
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
On Fri, Aug 18, 2017 at 5:01 PM, Kirill Prazdnikov <pki...@gmail.com> wrote:
Hi, I`m always getting ClassCastException if I use @JsType(isNative = true) object as a generic template argument.
Is it possbile to do something with that ?
Is it possbile to avoid check-cast generation if the generic is used with @JsType type ?
Thanks
--
You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscribe@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.
--Vassilis Virvilis
My, understanding, because I have noticed the same many times in the past few weeks.
@JsType
may (and that is a very weak may) work for a native type as long as you do not use it as you do not use it as a generic type argument. As soon as you do, for example, adding it to List<SomeType>
, , cast checking kicks in and you end up with a class cast exception if SomeType
is only annotated with @JsType
. There is another case when it kicks in also. I have noticed also a couple times that code with just @JsType
worked fine in superdev mode when not used in a generic context, but failed with a class cast exception, once compiled for release. As Vassillis mentioned, I am now conditioned to always specify the type name and package when isNative=true
. Object
is most commonly the name, but it could be different. However, Object will always be correct. The casting code in GWT is in Cast.java and the failure typically happens in the jsintanceof
method, called from castToNative
, with one of the parameters being null because the type name specified in the @JsType
annotation is incorrect or missing. In your case since ArrayBuffer
is an instance of Object
, either Object
or ArrayBuffer
should work for the type name.
You can disable cast checking, but only when compiling for production, and not in superdev mode, by using the -XdisableCastChecking
flag. For most applications that get data from the network and display it on the page, this will have no noticeable effect whatsoever, so it is best avoided. There is also the @UnecheckedCast annotation, which can be applied to selected methods in the critical path of performance sensitive code, and again, only takes effect in code compile for release, not superdev mode.
You would not want to disable cast checking in superdev mode anyways. I just finished porting an AngularJS/TypeScript application to GWT, and found a number of silent bugs in the old typescript (bugs that doe generate any output in the dev console) thanks to GWT cast checking. Typescript gives the illusion of types, but there is no runtime type checking when you cast something, GWT really does check, and that is a major advantage you would not want to lose.
Customizes the name of the type in generated JavaScript. If not provided, the simple Java name will be used.
@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public abstract class ArrayBuffer { ... }
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "ArrayBuffer")
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
--
You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsub...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.
@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public abstract class ArrayBuffer { ... }
@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "ArrayBuffer")
--
You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsub...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.
What else can it be if not ArrayBuffer (hence the need of generic)? An ArrayBuffer extension?
These ought to work.
public abstract class ArrayBuffer { ... }
@JsType(isNative = true, namespace = JsPackage.GLOBAL)
GWT,log
the result. .Let's see if it really is an ArrayBuffer.(I would note the FileReader result is sometimes a String and sometimes an ArrayBuffer).private native String getType(Object x)/*-{
return Object.prototype.toString.call(x);
}-*/
--You received this message because you are subscribed to a topic in the Google Groups "GWT Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/google-web-toolkit/jiHnLPfUQhc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to google-web-toolkit+unsub...@googlegroups.com.
private native String getType(Object x) /*-{
return Object.prototype.toString.call(x);
}-*/;
private native String typeOf(Object x) /*-{
return typeof x;
}-*/;
I looked but I didn't find in the thread the description of the java caller that throws the exception.
--
You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsub...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.
public abstract class FileDropHandler<FileT> extends InputClientAdapter {
// here we have some common UI logic and constuctor
// and the following methods are platform specific:
protected abstract int length(FileT arrayBuffer);
protected abstract Async<String> doUpload(FileT arrayBuffer);
protected abstract void processFile(DropEvent<?> dropEvent, MouseEvent mouseEvent);
protected abstract ObjectFactory[] loadObjects(String file, FileT arrayBuffer);
}
So in case of web, FileT is ArrayBuffer which I get form dropEvent.file, which is a web File type used in drag events.
public class FileDropHandlerGwt extends FileDropHandler<ArrayBuffer> { ... };
For JVM version I have regular files so I use java.io.File for the template argument.
public class FileDropHandlerJvm extends FileDropHandler<File> { ... };
And this does not work for me.
As a workaround I currently have a class container for ArrayBuffer like
static class ArrayBufferContainer { public final ArrayBuffer buffer; };which I use for template argument currently.I think that there is a way to use ArrayBuffer directly, But I have not found a way to do that.In order to understand GWT and understand JS-interop I`m asking this here.Thanks-Kirill
Could it possibly be that the ArrayBuffer is coming from another browsing context? (iframe)
public abstract class FileDropHandler<FileT> extends InputClientAdapter {
protected abstract int getLength(FileT buffer);
protected void handleJetFile(final String file, final FileT buffer) {
Logger.log("Handle jet file. length = " + getLength(buffer));
....
public class FileDropHandlerGwt extends FileDropHandler<ArrayBuffer> {
...
@Override
protected int getLength(ArrayBuffer buffer) {
return buffer.getByteLength();
}
}
How that can be fixed ?
FileList
object returned as a result of a user selecting files using the <input>
element, from a drag and drop operation's DataTransfer
object, or from the mozGetAsFile()
API on an HTMLCanvasElement
.Is the FileReader "instanceof $wnd.FileReader"? (Walk up the chain)
--
You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsub...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.
Is the FileReader "instanceof $wnd.FileReader"? (Walk up the chain)
public static native FileReader newFileReader() /*-{
return new FileReader();
}-*/;
isInstanceOfFileReader(fileReader) = true
isInstanceOfFileReader(fileReader2) = false
If isInstanceOfArrayBuffer is false, then this is likely the root issue
ArrayBuffer arrayBuffer = fileReader2.resultArrayBuffer();
Logger.log("instanceOfArrayBuffer for file = " + isInstanceOfArrayBuffer(arrayBuffer));ArrayBuffer good = new ArrayBuffer(arrayBuffer.getByteLength());
new Int8Array(good).set(new Int8Array(arrayBuffer));Logger.log("instanceOfArrayBuffer for good copy = " + isInstanceOfArrayBuffer(good));handleJetFile(name, arrayBuffer);
instanceOfArrayBuffer for file = falseinstanceOfArrayBuffer for good copy = true
ArrayBuffer arrayBuffer = fileReader2.resultArrayBuffer();
Logger.log("instanceOfArrayBuffer for file = " + isInstanceOfArrayBuffer(arrayBuffer));ArrayBuffer good = new ArrayBuffer(arrayBuffer.getByteLength());
new Int8Array(good).set(new Int8Array(arrayBuffer));Logger.log("instanceOfArrayBuffer for good copy = " + isInstanceOfArrayBuffer(good));handleJetFile(name, arrayBuffer);
handleJetFile(name, good);
instanceOfArrayBuffer for file = false
instanceOfArrayBuffer for good copy = trueUncaught Error: java.lang.ClassCastException
- your GWT script? If which option did you use ScriptInjector. If yes - did you setWindow?
public static native FileReader newFileReader() /*-{
return new $wnd.FileReader();
}-*/;
--
Is the FileReader "instanceof $wnd.FileReader"? (Walk up the chain)What is interesting, FileReader created with JSNI is not isInstanceOfFileReader,public static native FileReader newFileReader() /*-{
return new FileReader();
}-*/;but FileReader created with jsType and jsConstructor is isInstanceOfFileReader@JsType(isNative = true) public class FileReader { public FileReader() {} };isInstanceOfFileReader(fileReader) = true
isInstanceOfFileReader(fileReader2) = falseThe same for ArrayBuffer, one created with JSNI not a buffer passing isInstanceOfArrayBuffer, but one created with "new ArrayBuffer(10)" form java is passing isInstanceOfArrayBuffer.Both FileReaders can read files and both ArrayBuffer returned form reading IS NOT passing isInstanceOfArrayBuffer.
public static native FileReader newFileReader() /*-{
return new $wnd.FileReader();
}-*/;
instanceOfArrayBuffer for file = falseinstanceOfArrayBuffer for good copy = trueUncaught Error: java.lang.ClassCastExceptionI think that it is a problem for generics.GWT will fail its checkcast for any instance of system type (like array buffer or whatever) for any class created other in any context other then $wnd.JS "new ArrayBuffer(10)" and "new $wnd.ArrayBuffer(10)" has different type from GWT point of view.
Then my next question:if GWT generates checkckast as "yze_g$(fileBuffer_0_g$, $wnd.ArrayBuffer)", where "$wnd.ArrayBuffer" is a typehow can I ask GWT to generate checkckast to ArrayBuffer, not to $wnd.ArrayBuffer ?
Then my next question:if GWT generates checkckast as "yze_g$(fileBuffer_0_g$, $wnd.ArrayBuffer)", where "$wnd.ArrayBuffer" is a typehow can I ask GWT to generate checkckast to ArrayBuffer, not to $wnd.ArrayBuffer ?In case you really need to reference a type in GWT's hidden iframe, then you can use namespace="<window>" instead of namespace=GLOBAL;
but this is undocumented behavior that could possibly change or break at any time.Better fix you JSNI to use $wnd, or use JsInterop all the way down, with namespace=GLOBAL.