Question

I'm trying to get my feet wet with GWT to see if migrating will work out. I usually try the more difficult parts first to make sure I can finish the project. The most difficult part of my project(s) is referencing 3rd party JS libs. In this example I'm trying to use PubNub as much of our platform uses it.

What I'd like to do is create a reusable object that can be used in other GWT projects in need of PubNub. I've got a simple little test running successfully (ie, I've got the basics of JNSI working), but my question is -> where do I put the reference to the 3rd party script in order to create the library/module properly?

Right now I just put the reference to the external scripts in the HTML page in the project, but I'm pretty sure this is incorrect from a reusability perspective, as this lib would be used in other projects, each of which would have their own base HTML page.

I tried putting the reference in the gwt.xml file, but this seems to lose the references (ie my test project no longer works as it did when the scripts were in the HTML page)

Do you have any tips on how to include 3rd party libraries in a reusable GWT library/widget?

Was it helpful?

Solution

Here you have an example using client bundles and script injector, you can use either synchronous loading or asynchronous.

When using sync the external js content will be embedded in the application, otherwise it will be include in a different fragment which will be got with an ajax request.

You can put your api in any server and load it with the ScriptInjector.

public class Example {

  public static interface MyApiJs extends ClientBundle {
    MyApiJs INSTANCE = GWT.create(MyApiJs.class);

    @Source("my_api.js")
    TextResource sync();

    @Source("my_api.js") // Should be in the same domain or configure CORS
    ExternalTextResource async();
  }

  public void loadSync() {
    String js = MyApiJs.INSTANCE.sync().getText();
    ScriptInjector.fromString(js).inject();
  }

  public void loadAsync() throws ResourceException {
    MyApiJs.INSTANCE.async().getText(new ResourceCallback<TextResource>() {
      public void onSuccess(TextResource r) {
        String js = r.getText();
        ScriptInjector.fromString(js).inject();
      }
      public void onError(ResourceException e) {
      }
    });
  }

  public void loadFromExternalUrl() {
    ScriptInjector.fromUrl("http://.../my_api.js").inject();
  }
} 

[EDITED]

A better approach is to use a new feature in gwtquery 1.4.0 named JsniBundle. We introduced this feature during the GWT.create conferences at San Francisco and Frankfurt.

With this approach you can insert any external javascript (placed in your source tree or hosted in an external host) as a JSNI block. It has many benefits:

  • Take advantage of GWT jsni validators, obfuscators and optimizers.
  • Get rid of any jsni java method when the application does not use it.

The syntax is actually easy:

public interface JQueryBundle extends JsniBundle {
  @LibrarySource("http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js")
  public void initJQuery();
} 

JQueryBundle jQuery = GWT.create(JQueryBundle.class);
jQuery.initJQuery();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top