Weird type error in lambdas with generics, with JsInterop

51 weergaven
Naar het eerste ongelezen bericht

Thomas

ongelezen,
10 sep 2020, 08:54:4810-09-2020
aan GWT Users
Hi all,

I'm trying to migrate some of my JSNI code to JsInterop. In particular HTML File System API which I'm using with Cordova and in the browser for testing.
There are some full-on Callback interfaces which uses generics and lambdas in the code. I'm not 100% certain if it's JsInterop or Lambda related (I'm running GWT 2.8.2).

In various places I'm now getting errors like this:

SEVERE: Uncaught Exception on client: (TypeError) : Cannot read property '<REDACTED>' of undefined
com.google.gwt.core.client.JavaScriptException: (TypeError) : Cannot read property 'inspectivity' of undefined
at Unknown.onSuccess_321_g$(FileStorageImpl.java:475)
at Unknown.getRootDataDirectory_0_g$(BrowserFileSystemPlatform.java:100)
at Unknown.clear_99_g$(FileStorageImpl.java:473)
....

There is no property '<REDACTED>" anywhere - it's the application name. And the error is on line 475 which is the "onSuccess" method method definition.

I have been trying various approaches all afternoon and it seems to get better when I rewrite parts of the code to avoid generics.

Has anyone else run into similar problems?

Cheers,
Thomas




Jens

ongelezen,
10 sep 2020, 11:52:3510-09-2020
aan GWT Users
Well generally it is a NullPointerException in your onSuccess method in FileStorageImpl. Somewhere in your code "null/undefined.inspectivity" is called. If your final JavaScript that produces the above exception contains literally the code "null.inspectivity" instead of "someVariableThatIsNull.inspectivity" then you likely have a JsInterop issue, either wrong definition of JsInterop classes/interfaces or it is a GWT compiler bug. 

So you have to share more code (FileStorageImpl.onSuccess, class that contains inspectivity field).

-- J.


Thomas Buckel

ongelezen,
10 sep 2020, 19:28:3810-09-2020
aan google-we...@googlegroups.com
Thanks Jens. The NullPointerException was my first line of investigation. But there are no fields, object or method called 'inspectivity' - it's part of the package names. When debugging in Chrome DevTools, the exception occurred while it was executing the "method declaration line", AFAIK the GWT boilerplate code before it executes the actual method.

Unfortunately I can't share the full code, but I think I've pinned it down to invoking callbacks based with generics from JsInterop (similar code is working with JSNI callbacks):

public interface FileCallback<S, E> {
         public void onSuccess(S entry);
         public void onFailure(E error);
}

public abstract class DelegatingFileCallback<S> implements FileCallback<S, FileError> {
    private static final Logger log = Logger.getLogger(DelegatingFileCallback.class.getName());
    private final FileCallback<?, FileError> delegate;
    private final String operation;
    protected DelegatingFileCallback(FileCallback<?, FileError> delegate, String operation) {
        this.delegate = delegate;
        this.operation = operation;
    }
    @Override
    public final void onFailure(FileError error) {
        log.warning(error.buildErrorMessage(operation, ""));
        delegate.onFailure(error);
    }
}

I'm gradually replacing these callbacks by specific ones and it seems to be working.

Thanks,
Thomas

Thomas Buckel

ongelezen,
10 sep 2020, 21:52:1410-09-2020
aan google-we...@googlegroups.com
Actually, I was able to pin-point to a small piece of code. 
My feeling is that it fails every time where the callback is a method reference which involved generic types.

JsInterop method called:
@JsType(isNative = true, name = "window", namespace = "<global>")
public class CordovaFileSystemGlobal {
    public static native void resolveLocalFileSystemURL(String url, FileSystemEntryCallback success, FileErrorCallback error);
}

In another, class Invocation:
public void resolveLocalFileSystemURL(String url, FileCallback<FileSystemEntry, com.inspectivity.go.client.filesystem.webkit.FileError> callback) {
    CordovaFileSystemGlobal.resolveLocalFileSystemURL(url, callback::onSuccess, callback::onFailure);
}

File Callback:
public interface FileCallback<S, E> {
         public void onSuccess(S entry);
         public void onFailure(E error);
}

/Thomas
Allen beantwoorden
Auteur beantwoorden
Doorsturen
0 nieuwe berichten