Question

On the GWT overview page it reads:

The GWT developer plugin spans the gap between Java bytecode in the debugger and the browser's JavaScript.

Thanks to the GWT developer plugin, there's no compiling of code to JavaScript to view it in the browser. You can use the same edit-refresh-view cycle you're used to with JavaScript, while at the same time inspect variables, set breakpoints, and utilize all the other debugger tools available to you with Java. And because GWT's development mode is now in the browser itself, you can use tools like Firebug and Inspector as you code in Java.

And the another SO Question and Answer How GWT code runs in development code mentions the JS code is extracted and put into the browser to be evaluated and result is sent back to the java.

What's the exact protocol of this process? Any documentation (not the very high level ones)? Where are the locations in source code? How do you track this interface in the browser or in the java vm (firebug, or java debugger)?

Edit: Artem below answered how it looks like from the lowest layer on the Java side. What's the higher layers, if you know? What's on the browser side?

Was it helpful?

Solution

Everything's documented in the wiki actually: https://code.google.com/p/google-web-toolkit/wiki/DesignOOPHM

If you want to write a client replacement, you can use the C++ code from https://gwt.googlesource.com/gwt-plugins/+/master/common or in Java the BrowserChannelClient class. Note that there's also an unfinished wireshark packet dissector in https://gwt.googlesource.com/gwt-plugins/+/master/wireshark

OTHER TIPS

Very interesting question. I've just decided to debug and seems that it is really native protocol.

Call processing starts from com.google.gwt.dev.shell.BrowserChannel. This class extended by BrowserChannelClient and BrowserChannelServer.

And com.google.gwt.dev.shell.BrowserListener creates listener for new connections from browsers. Here is constructor from BrowserListener:

/**
 * Listens for new connections from browsers.
 * 
 * @param logger 
 * @param port 
 * @param handler 
 */
public BrowserListener(final TreeLogger logger, String bindAddress,
  int port, final SessionHandlerServer handler) {
  try {
    listenSocket = new ServerSocket();
    listenSocket.setReuseAddress(true);
    InetAddress address = InetAddress.getByName(bindAddress);
    listenSocket.bind(new InetSocketAddress(address, port));

    if (logger.isLoggable(TreeLogger.TRACE)) {
      logger.log(TreeLogger.TRACE, "Started code server on port "
          + listenSocket.getLocalPort(), null);
    }
    listenThread = new Thread() {
      @Override
      public void run() {
        while (true) {
          try {
            Socket sock = listenSocket.accept();
            TreeLogger branch = logger.branch(TreeLogger.TRACE,
                "Connection received from "
                    + sock.getInetAddress().getCanonicalHostName() + ":"
                    + sock.getPort());
            try {
              sock.setTcpNoDelay(true);
              sock.setKeepAlive(true);
            } catch (SocketException e) {
              // Ignore non-critical errors.
            }

            BrowserChannelServer server = new BrowserChannelServer(branch,
                sock, handler, ignoreRemoteDeath);
            /*
             * This object is special-cased by the SessionHandler, used for
             * methods needed by the client like hasMethod/hasProperty/etc.
             * handler is used for this object just to make sure it doesn't
             * conflict with some real object exposed to the client.
             */
            int id = server.getJavaObjectsExposedInBrowser().add(server);
            assert id == BrowserChannel.SPECIAL_SERVERMETHODS_OBJECT;
          } catch (IOException e) {
            logger.log(TreeLogger.ERROR, "Communications error", e);
          }
        }
      }
    };
    listenThread.setName("Code server listener");
    listenThread.setDaemon(true);
  } catch (BindException e) {
    logger.log(TreeLogger.ERROR, "Unable to bind socket on port " + port
        + " -- is another session active?", e);
  } catch (IOException e) {
    logger.log(TreeLogger.ERROR, "Communications error", e);
  }
}

A typical development mode session can be seen below: enter image description here

What's the exact protocol of this process? 

Development mode uses a special engine to run your app as a mix of both Java bytecode and native JavaScript.

The official docs itself very clear about what happens when you run the app.

When you starting running

Which means that you are interacting with your GWT application without it having been translated into JavaScript. Anytime you edit, run, and debug applications from a Java integrated development environment (IDE), you are working in development mode. When an application is running in development mode, the Java Virtual Machine (JVM) is actually executing the application code as compiled Java bytecode, using GWT plumbing to connect to a browser window. This means that the debugging facilities of your IDE are available to debug both your client-side GWT code and any server-side Java code as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top