1

我正在通过代理运行 gwt 托管模式;调试工作,但它不会获取在我的 IDE 中对客户端代码所做的更改。

我正在使用 maven 插件来启动托管模式;配置如下。webapp 代码在 /web 中的原因是该应用基于 dropwizard,无法从 root 中提供 web 资源;因此我有 src/main/webapp/web/* 作为我的网络资产。

那么这个 Maven 配置有什么问题呢?

    <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>
4

1 回答 1

3

多步骤答案,从标题的答案开始,然后解释您的应用程序不正常运行的原因:

当在开发模式下调试 GWT 应用程序时,页面会启动hosted.html文件,该文件连接到浏览器插件,然后尝试读取运行在(默认情况下)localhost:9997 的代码服务器。建立连接后,开发模式会找到模块文件,然后开始工作。开发模式使用自定义类加载器“CompilingClassLoader”来完成所需的其他工作:

  • 在启动时,JavaScriptObject需要找到所有类并将其合并为一个巨型类型,JavaScriptObject$以便您可以自由地从一个 JSO 转换到另一个,并在任何其他 JSO 上调用任何 JSO 方法。这种JavaScriptObject$类型是在模块启动时合成的。

  • 当请求任何类时,此自定义类加载器会根据需要从文件系统或任何 jar 中选择类。它从.java文件中即时编译它们,因此得名。这样做既是为了获得具有未初始化静态字段的类的新实例,也是为了找到所有 JSNI 方法并正确连接它们以调用浏览器并再次返回。这就是为什么您可以更改任何文件并简单地刷新浏览器的原因 - 开发模式将始终尝试从文件系统中重新加载文件并根据需要创建实际的 Java 类。

编译类加载器从您的类路径中读取 - 当然,如果它找不到文件,则无法使用该类,同样,如果文件有多个副本,则只会使用找到的第一个副本。 .


问题是线路

<goal>resources</goal>

假设您正在处理一个war项目而不是lib,则不需要此行。

这一行不仅将.class文件复制到您的target/classes目录,还复制了 GWT 库需要在其 jar 中具有的任何其他资源。由于您不是在编写库而是在编写应用程序,因此这里没有必要这样做,实际上它会导致问题。在开发模式类路径中,target/classes是第一个条目,然后是源目录,然后是类路径中的每个 jar。

无论是启动项目还是要求 maven 编译它时,gwt:resources都会运行此目标,并移动所有源代码。然后稍后当您从 IDE 编辑文件时,IDE 自己的编译器会更新 .class 文件target/classes,但不知道gwt:resources它的用途,因此不会重新运行它。这意味着虽然target/classes有最新的.class文件,但它有过时的.java文件。

如果您需要您的源文件实际位于target/classes,请确保gwt:resources在 IDE 中的每次资源更改时运行,或者将源文件直接复制到target/classes目录的另一种方法是在您的 pom.xml 中设置一个<resource>条目。

于 2013-12-16T08:29:02.640 回答