Upgraded from GWT 2.6 to 2.8 - now Chrome Extension API doesn't work...

305 views
Skip to first unread message

TimOnGmail

unread,
Apr 27, 2017, 5:38:00 PM4/27/17
to GWT Contributors
Hello all...

I'm a developer on a project that uses GWT.  We had been using GWT 2.6 for a long time, and finally moved to GWT 2.8 w/Java 1.8.

Part of this project is a Chrome extension, where our web app needs to communicate with the extension.  This was working fine until we upgraded out project.

Now, there may be other code-related things going on that is causing this, but I thought I'd check here to see if anyone knows of GWT 2.8 possibly breaking Chrome extension APIs, specifically the Chrome "Message Passing" API:


The web app attempts to connect to the extension using chrome.runtime.connect(appId).  This worked fine in the past, but has now stopped working (in prior versions of our code, the extension receives the connection attempt; in current code, the connect method returns a valid "port" object, but the extension never receives the connection).

Anyone know of any conflicts between GWT 2.8/JsInterop/etc. and Chrome's proprietary APIs?

- Tim

TimOnGmail

unread,
May 1, 2017, 6:02:09 PM5/1/17
to GWT Contributors
So it appears that this is caused by JSNI methods somehow being morphed when the GWT app is compiled.  I don't know how, but I do know that calls to Chrome proprietary APIs aren't working correctly.  I modified my code to do the following:

Java method calls JSNI method
JSNI method calls raw JavaScript method in base app loading page (a JSP page)

... and it now works.  So the GWT compiler is doing something funny to JSNI methods that cause the Chrome API calls not to work as expected.

Anyone know what's happened there?

- Tim

Colin Alworth

unread,
May 1, 2017, 7:11:29 PM5/1/17
to GWT Contributors
What had been the care previously? Were you calling the chrome methods in some way other than through JSNI? Java methods can't call raw JavaScript without JSNI (or JsInterop, which didn't exist in GWT 2.6).
Otherwise I'm not sure what you changed it _from_ to get to the psuedocode in your post.

I'm not aware of breaking changes that should have happened (though it has been three years between the releases). It is possible that you were using JSNI in a way that probably shouldn't have worked previously, and since then it has been "fixed"?

TimOnGmail

unread,
May 2, 2017, 9:00:50 PM5/2/17
to GWT Contributors
No no, I had been calling Java -> JSNI -> Chrome ; that worked in GWT 2.6

Now, in GWT 2.8, the above does NOT work.

I modified the code to do: Java -> JSNI -> JavaScript that's not wrapped in a JSNI method (it's in the app's main JSP file) -> Chrome, and it works again.

So, JSNI methods calling Chrome APIs directly appear to no longer be working.

Does that explain it better?

- Tim

Goktug Gokdogan

unread,
May 2, 2017, 10:10:12 PM5/2/17
to GWT Contributors
This might be related to linker changes but not sure that in which version that was changed.

Pls provide the code snippet that was working before and no longer working.

TimOnGmail

unread,
May 3, 2017, 3:57:58 PM5/3/17
to GWT Contributors
Ok... here's the client app side - I haven't tried running this as-is, since it was culled from a much bigger piece of code.  But this is the gist of it:

package com.example;

public class ChromeAPIExample {

    private static final String CHROME_APP_ID = "..."; // Replace with actual Chrome app id

    public ChromeAPIExample() {
        initChromeListener();
    }

    private native void initChromeListener() /*-{
                                             
        try {
            
            $wnd.example = new Object();
                                             
            $wnd.example.isChrome = function() {
                                             
                var isChromeBrowser = false;
                                                 
                try {
                    isChromeBrowser = (typeof chrome !== 'undefined');
                } catch (e) {
                    console.log('isChrome: cannot determine if using chrome: ' + e);
                }

                return isChromeBrowser;
            };

            if (!$wnd.example.isChrome()) {
                console.log('initChromeListener: not using chrome; returning');
                return;
            }

            if ($wnd.example.chromePort && ($wnd.example.chromePort != null)) {
                console.log"initChromeListener: chromePort still exists, returning");
                return;
            }

            console.log('initChromeListener: this is chrome');

            var thisInstance = this;
            var chromeAppId = @com.example.ChromeAPIExample::CHROME_APP_ID;

            try {

                // Check if the app is installed and enabled by opening a messaging port
                var port = chrome.runtime.connect(chromeAppId);

                if (port) {

                    $wnd.example.chromePort = port;

                    console.log('initChromeListener: got port: ' + port);

                    port.onMessage.addListener(function(msg) {
                        console.log('chrome listener: msg: ' + msg);

                    });

                }

            } catch (e) {
                console.log('initChromeListener: Inner Error: ' + e);
            }
        } catch (e2) {
            alert('initChromeListener: Outer Error: ' + e2);
            }

    }-*/;

}



... and here's a snippet of code from the Chrome app.  If the above code was run in GWT 2.6, the Chrome app would log the connection attempt from the app.  In GWT 2.8, we get a port object back from the Chrome connection attempt, but the Chrome app doesn't see the connection attempt:

...

initialize();

function initialize() {
    chrome.runtime.onConnectExternal.addListener(onConnectExternal);
}

function onConnectExternal(port) {

  logMsg('onConnectExternal: port=' + port);

    port.onDisconnect.addListener(function() {
        logMsg('Port disconnected');
    });
}


- Tim

Goktug Gokdogan

unread,
May 3, 2017, 4:08:14 PM5/3/17
to google-web-toolkit-contributors
Maybe related to $wnd, but here we are basically shooting in the dark. You should debug your code and tell us where it behaves unexpectedly otherwise we cannot help much...

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/87a97383-b3a1-436a-832f-79594a4b1b3b%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

TimOnGmail

unread,
May 3, 2017, 4:22:27 PM5/3/17
to GWT Contributors
On Wednesday, May 3, 2017 at 1:08:14 PM UTC-7, Goktug Gokdogan wrote:
Maybe related to $wnd, but here we are basically shooting in the dark. You should debug your code and tell us where it behaves unexpectedly otherwise we cannot help much...

I have indeed debugged the code, and wasn't able to figure out what was going on, which is why I posted this here. :-)

What level of debugging are you hoping for?  The Chrome JavaScript APIs are a bit obtuse to debug.

The above example is pretty simple - I can send you a working example if you like, a complete Eclipse project plus an example Chrome app to demonstrate the issue.

- Tim

Colin Alworth

unread,
May 3, 2017, 4:32:16 PM5/3/17
to GWT Contributors
If it is the linker, going back to your 2.6 code and changing to the current xsiframe linker might show the bug - if so, you know it is related to the default linker change. If not, debugging your JSNI to see what the value of chrome is before and after the GWT version change will be helpful, or whatever the different wiring is (chrome.runtime.connect perhaps).

My guess (which is what Goktug is pointing to I think) is that you really should have all usages of chrome prefixed with "$wnd." so that there is no ambiguity about which object is being used, and which frame it is from.

If the above code is simple enough to demonstrate the issue, can you put a minimal project together so that we can reproduce the issue, including build instructions? Aside from that and the above suggestions (which is just rehashing of http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSNI.html and the earlier emails), we don't really have anything to go on...
Reply all
Reply to author
Forward
0 new messages