ClassCastException in some browser, but not others (

188 views
Skip to first unread message

Shawn

unread,
Oct 5, 2019, 9:36:26 AM10/5/19
to GWT Users
Hi,

I get a ClassCastException under Safari, Safari on IOS and Chrome on IOS but not in Chrome.  Is there any way to get around this?

I am using GWT HEAD and accesses indexeddb via elemental2-indexeddb-1.0.0

                IDBFactory idbf = IndexedDbGlobal.indexedDB;

IDBOpenDBRequest idbr = idbf.open(INDEXEDDB_NAME);


idbr.onsuccess= new OnsuccessFn() {


@Override

public Object.onInvoke(elemental2.dom.Event p0) {

IDBDatabase idb = (IDBDatabase) idbr.result;

return idb;

}




(-:-) 2019-10-05 22:09:12,968 [ERROR] Casting err: 
java.lang.ClassCastException
    at Unknown.Throwable_1(Throwable.java:69)
    at Unknown.Exception_1(Exception.java:29)
    at Unknown.RuntimeException_1(RuntimeException.java:29)
    at Unknown.ClassCastException_0(ClassCastException.java:27)
    at Unknown.checkCriticalType(InternalPreconditions.java:154)
    at Unknown.checkType_0(InternalPreconditions.java:138)
    at Unknown.checkType(InternalPreconditions.java:133)
    at Unknown.castToNative(Cast.java:155)
    at Unknown.onInvoke(MyApp.java:1319)
    at Unknown.anonymous(Runtime.java:166)


Shawn

unread,
Oct 5, 2019, 9:46:44 AM10/5/19
to GWT Users
Meant to add that I am sure indexeddb is supported in all the browsers I am using.

Here is the code again ... sorry about the previous formatting.

IDBFactory idbf = IndexedDbGlobal.indexedDB;

IDBOpenDBRequest idbr = idbf.open(INDEXEDDB_NAME);

 

idbr.onsuccess = new OnsuccessFn() {


@Override

public Object onInvoke(elemental2.dom.Event p0) {

 

                                        //error is next

idb = (IDBDatabase)  idbr.result;


DOMStringList dsl = idb.objectStoreNames;


dsl.asList().forEach(s -> {

Log.error("FOUND DB " + s);

});

 

return idbr.result;

}

};


On Chrome desktop, I find the indexeddb I created in handwritten js code.  I don't get why there is a ClassCastException in some browsers.  Is elemental2-indexeddb or gxt 2.9 (HEAD) not supported everywhere?

Shawn Asamoto-Brown

unread,
Oct 6, 2019, 12:01:05 AM10/6/19
to google-we...@googlegroups.com
OK, this works --> IDBDatabase idb = Js.<IDBDatabase> uncheckedCast(idbr.result);

		@SuppressWarnings({ "unchecked" })
	public static void initIndexedDb() {

		IDBFactory idbf = IndexedDbGlobal.indexedDB;
		IDBOpenDBRequest idbr = idbf.open(INDEXEDDB_NAME);
		
		idbr.onsuccess = new OnsuccessFn() {

			@Override
			public Object onInvoke(elemental2.dom.Event p0) {

				// fails w java.lang.ClassCastException
				// IDBDatabase idb = (IDBDatabase) idbr.result;
				// IDBDatabase idb = Js.<IDBDatabase> cast(db);

				//this works
				IDBDatabase idb = Js.<IDBDatabase> uncheckedCast(idbr.result);

				DOMStringList dsl = idb.objectStoreNames;

				dsl.asList().forEach(s -> {
					Log.info("FOUND DB " + s);
				});

				return idbr.result;
			}
		};

		idbr.onerror = new OnerrorFn() {

			@Override
			public Object onInvoke(elemental2.dom.Event p0) {
				Log.error("OnerrorFn " + p0.type);
				return null;
			}
		};
	}

--
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-tool...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit/cbc724a1-5b8b-4478-8119-02af3d279c2b%40googlegroups.com.

Vassilis Virvilis

unread,
Oct 6, 2019, 1:12:18 AM10/6/19
to google-we...@googlegroups.com, Shawn Asamoto-Brown
Probably

--> IDBDatabase idb = Js.uncheckedCast(idbr.result);

would work too.

The point is is uncheckedCast is (AFAIU) considered dangerous.

There are two other casts that perform run-time checks but they have a 1) performance penalty and 2) some times throw exceptions not due to a bug but because the casting is invalid based on the type definitions GWT compiler knows about.

Here is the first type:
a) Java cast --> MyObject x = (MyObject) yourObject;
b) Js checked cast --> MyObject x = Js.cast(yourObject);
and of course
c) Js unchecked cast --> MyObject x = Js.uncheckedCast(yourObject);

I think (not sure) that a) and b) are the same at least on development mode. Not so sure what they are doing in production mode.

My 2 cents of limited understanding...

Vassilis



On 10/6/19 7:00 AM, Shawn Asamoto-Brown wrote:
> OK, this works --> IDBDatabase idb = Js.<IDBDatabase> uncheckedCast(idbr.result);
>
> @SuppressWarnings({ "unchecked" })
> public static void initIndexedDb(){
>
> IDBFactory idbf= IndexedDbGlobal.indexedDB;
> IDBOpenDBRequest idbr= idbf.open(INDEXEDDB_NAME);
>
> idbr.onsuccess= new OnsuccessFn() {
>
> @Override
> public Object onInvoke(elemental2.dom.Event p0) {
>
> // fails w java.lang.ClassCastException
> // IDBDatabase idb = (IDBDatabase) idbr.result;
> // IDBDatabase idb = Js.<IDBDatabase> cast(db);
>
> //this works
> IDBDatabase idb= Js.<IDBDatabase > uncheckedCast(idbr.result);
>
> DOMStringList dsl= idb.objectStoreNames;
>
> dsl.asList().forEach(s-> {
> Log.info("FOUND DB " + s);
> });
>
> return idbr.result;
> }
> };
>
> idbr.onerror= new OnerrorFn() {
>
> @Override
> public Object onInvoke(elemental2.dom.Event p0) {
> Log.error("OnerrorFn " + p0.type);
> return null;
> }
> };
> }
>
>
> On Sat, Oct 5, 2019 at 10:47 PM Shawn <sh...@koyuru.com <mailto:sh...@koyuru.com>> wrote:
>
> Meant to add that I am sure indexeddb is supported in all the browsers I am using.
>
> Here is the code again ... sorry about the previous formatting.
>
> IDBFactory idbf = IndexedDbGlobal./indexedDB/;
>
> IDBOpenDBRequest idbr = idbf.open(*/INDEXEDDB_NAME/*);
>
> idbr*.*onsuccess = new OnsuccessFn() {
>
>
> /@Override/
>
> public Object onInvoke(elemental2.dom.Event p0) {
>
>                                         //error is next
>
> idb = (IDBDatabase)idbr.result;
>
>
> DOMStringList dsl = idb.objectStoreNames;
>
>
> dsl.asList().forEach(s -> {
>
> Log./error/("FOUND DB " + s);
>
> });
>
> return idbr.result;
>
> }
>
> };
>
>
> On Chrome desktop, I find the indexeddb I created in handwritten js code.  I don't get why there is a ClassCastException in some browsers.  Is elemental2-indexeddb or gxt 2.9 (HEAD) not supported everywhere?
>
> --
> 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-tool...@googlegroups.com <mailto:google-web-tool...@googlegroups.com>.
> To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit/cbc724a1-5b8b-4478-8119-02af3d279c2b%40googlegroups.com <https://groups.google.com/d/msgid/google-web-toolkit/cbc724a1-5b8b-4478-8119-02af3d279c2b%40googlegroups.com?utm_medium=email&utm_source=footer>.
>
> --
> 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-tool...@googlegroups.com <mailto:google-web-tool...@googlegroups.com>.
> To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit/CAEQ-_W11k9ze2bQnnB9K_fiGhna1f8AkmO25pLKYqmbA9vy1OQ%40mail.gmail.com <https://groups.google.com/d/msgid/google-web-toolkit/CAEQ-_W11k9ze2bQnnB9K_fiGhna1f8AkmO25pLKYqmbA9vy1OQ%40mail.gmail.com?utm_medium=email&utm_source=footer>.

Shawn Asamoto-Brown

unread,
Oct 6, 2019, 1:38:21 AM10/6/19
to Vassilis Virvilis, google-we...@googlegroups.com
Hi,
Probably

  --> IDBDatabase idb = Js.uncheckedCast(idbr.result);

would work too.

Yes, it does. 

The point is is uncheckedCast is (AFAIU) considered dangerous.

It's the only way I can get it to work though. 

There are two other casts that perform run-time checks but they have a 1) performance penalty and 2) some times throw exceptions not due to a bug but because the casting is invalid based on the type definitions GWT compiler knows about.

Here is the first type:
    a) Java cast         --> MyObject x = (MyObject) yourObject;
    b) Js checked cast   --> MyObject x = Js.cast(yourObject);
and of course
    c) Js unchecked cast --> MyObject x = Js.uncheckedCast(yourObject);

I think (not sure) that a) and b) are the same at least on development mode. Not so sure what they are doing in production mode.

Both a) and b) fail in production (on Safari and Chrome in ios) but work in Chrome desktop on OSX.

My 2 cents of limited understanding...

Thanks. 

    Vassilis


Thomas Broyer

unread,
Oct 6, 2019, 5:30:17 AM10/6/19
to GWT Users


On Saturday, October 5, 2019 at 3:36:26 PM UTC+2, Shawn wrote:
Hi,

I get a ClassCastException under Safari, Safari on IOS and Chrome on IOS but not in Chrome.


Just a small note: all browsers on iOS are forced to use Safari's engine (except IIRC they don't have access to some JS engine's optimizations that Safari has), so it's absolutely not surprising that things work the same on Safari iOS and Chrome iOS; and differently between Chrome iOS and Chrome anywhere-else.

Wrt the cast error, it might be that the object in 'result' is not "instanceof $wnd.IDBDatabase". This would be a bug in Safari; and uncheckedCast is indeed the workaround.

Peter Donald

unread,
Oct 6, 2019, 7:03:51 AM10/6/19
to GWT Mailing List
On Sun, Oct 6, 2019 at 8:30 PM Thomas Broyer <t.br...@gmail.com> wrote:
Wrt the cast error, it might be that the object in 'result' is not "instanceof $wnd.IDBDatabase". This would be a bug in Safari; and uncheckedCast is indeed the workaround.

Actually I believe it is a bug in closures externs from which elemental2 is generated. Without checking my guess is that IDBDatabase is annotated with a @constructor tag rather than a @interface which is incorrect as the spec defines it as an interface [1]. Unfortunately, this is a common problem with some of the closure compiler externs. It does not impact people using closure compiler. Unfortunately, the jsinterop-generator will generate incorrect code if the extern is incorrectly annotated.


--
Cheers,

Peter Donald

Jens

unread,
Oct 6, 2019, 7:55:39 AM10/6/19
to GWT Users

Actually I believe it is a bug in closures externs from which elemental2 is generated. Without checking my guess is that IDBDatabase is annotated with a @constructor tag rather than a @interface which is incorrect as the spec defines it as an interface [1]. Unfortunately, this is a common problem with some of the closure compiler externs. It does not impact people using closure compiler. Unfortunately, the jsinterop-generator will generate incorrect code if the extern is incorrectly annotated.

But they do accept fixes for these kind of things?

Peter Donald

unread,
Oct 6, 2019, 5:54:21 PM10/6/19
to GWT Mailing List
On Sun, 6 Oct 2019 at 22:56, Jens <jens.ne...@gmail.com> wrote:

Actually I believe it is a bug in closures externs from which elemental2 is generated. Without checking my guess is that IDBDatabase is annotated with a @constructor tag rather than a @interface which is incorrect as the spec defines it as an interface [1]. Unfortunately, this is a common problem with some of the closure compiler externs. It does not impact people using closure compiler. Unfortunately, the jsinterop-generator will generate incorrect code if the extern is incorrectly annotated.

But they do accept fixes for these kind of things?

I believe that they would. My limited experience is that they will almost always accept changes that improve the correctness unless it requires massive reworks of internal apps. Even then I have got through some compromise changes to externs that achieve the same thing. Sometimes the occasional ping is required to get the ball rolling but other than that a relatively smooth experience to get changes in.


Reply all
Reply to author
Forward
0 new messages