gwtgwt-hosted-mode

How does gwt hosted mode observe changes?


I am running gwt hosted mode through a proxy; debugging works, but it doesn't pick up changes to client code made in my IDE.

I am using the maven plugin to start hosted mode; configuration is as follows. The reason that webapp code is in /web is that the app is based on dropwizard, which can't server web assets out of root; thus I have src/main/webapp/web/* as my web assets.

So what's wrong with this maven config?

    <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>gwt-maven-plugin</artifactId>
            <version>2.5.1</version>
            <configuration>
                <webappDirectory>${project.build.outputDirectory}/web</webappDirectory>
                <hostedWebapp>${project.build.outputDirectory}/web</hostedWebapp>
                <!--<copyWebapp>true</copyWebapp>-->
                <module>com.flavor8.todo</module>
                <runTarget>index.htm</runTarget>
                <persistentunitcache>false</persistentunitcache>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>test</goal>
                        <goal>resources</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>com.google.gwt</groupId>
                    <artifactId>gwt-user</artifactId>
                    <version>2.5.1</version>
                    <scope>provided</scope>
                </dependency>
                <dependency>
                    <groupId>com.google.gwt</groupId>
                    <artifactId>gwt-dev</artifactId>
                    <version>2.5.1</version>
                    <scope>provided</scope>
                </dependency>
                <dependency>
                    <groupId>com.google.gwt</groupId>
                    <artifactId>gwt-servlet</artifactId>
                    <version>2.5.1</version>
                    <scope>provided</scope>
                </dependency>
            </dependencies>
        </plugin>

Solution

  • Multi-step answer, starting with the answer to the title, then explaining why your app isn't behaving:

    When a GWT app is being debugged in Dev Mode, the page starts up the hosted.html file, which connects to the browser plugin, which then tries to read the code server running at (by default) localhost:9997. When that connection is made, dev mode finds the module file, and gets things going. A custom classloader, 'CompilingClassLoader' is used by dev mode to do the other work that is required:

    The compiling classloader reads from your classpath - of course if it can't find a file, then that class cannot be used, and likewise if there is more than one copy of a file, then only the first copy found will be used...


    The problem is the line

    <goal>resources</goal>
    

    Assuming you are working on a war project and not lib, this line doesn't need to be there.

    This line copies not only the .class files to your target/classes directory, but also any other resources that a GWT library would need to have in its jar. Since you aren't writing a library but an application, this isn't necessary to do here, and in fact it is causing problems. On the dev mode classpath, target/classes is the first entry, followed by your source directories, then each jar on your classpath.

    Either when you start the project or when you ask maven to compile it, this gwt:resources goal is run, and all sources are moved. Then later when you edit a file from your IDE, the IDE's own compiler updates the .class file in target/classes, but doesn't know what gwt:resources is for, so doesn't re-run it. This means that while target/classes has the latest .class files, it has out of date .java files.

    If you need your source files to actually be in target/classes, either make sure that gwt:resources runs with every resource change in your IDE, or another way to copy sources directly to the target/classes directory is to set up a <resource> entry in your pom.