[英]How does gwt hosted mode observe changes?
I am running gwt hosted mode through a proxy; 我通过代理运行gwt托管模式; debugging works, but it doesn't pick up changes to client code made in my IDE. 调试工作,但它没有获取在我的IDE中生成的客户端代码的更改。
I am using the maven plugin to start hosted mode; 我正在使用maven插件启动托管模式; 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; Web应用程序代码位于/ web中的原因是该应用程序基于dropwizard,它不能从根服务器中提供Web资产; thus I have src/main/webapp/web/* as my web assets. 因此我有src / main / webapp / web / *作为我的网络资产。
So what's wrong with this maven config? 那么这个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>
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. 当在开发模式下调试GWT应用程序时,该页面启动hosted.html
文件,该文件连接到浏览器插件,然后该插件尝试读取(默认情况下)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: dev模式使用自定义类加载器'CompilingClassLoader'来完成所需的其他工作:
At startup, all JavaScriptObject
classes need to be found and merged into one giant type, JavaScriptObject$
, so that you can freely cast from one JSO to another, and invoke any JSO method on any other JSO. 在启动时,需要找到所有JavaScriptObject
类并将其合并为一个巨型类型JavaScriptObject$
,以便您可以从一个JSO自由地转换到另一个JSO,并在任何其他JSO上调用任何JSO方法。 This JavaScriptObject$
type is synthesized at module start up. 此JavaScriptObject$
类型在模块启动时合成。
When any class is requested, this custom class loader picks up classes as needed from the filesystem or from any jar. 当请求任何类时,这个自定义类加载器根据需要从文件系统或任何jar中获取类。 It compiles them on the fly from the .java
file, hence the name. 它从.java
文件中动态编译它们,因此得名。 This is done both to get a new instance of the class with un-initialized static fields, but also to find all JSNI methods and correctly wire them up to call into the browser and back again. 这样做既可以获得具有未初始化静态字段的类的新实例,也可以查找所有JSNI方法并正确连接它们以调用浏览器并再次返回。 This wiring is why you can make changes to any file and simply refresh the browser - Dev Mode will always try to load the file from the filesystem fresh and create the actual Java class as needed. 这种连接是您可以对任何文件进行更改并简单刷新浏览器的原因 - 开发模式将始终尝试从文件系统中加载文件,并根据需要创建实际的Java类。
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. 假设你正在开发一个war
项目而不是lib
,那么这条线就不需要了。
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. 此行不仅将.class
文件复制到target/classes
目录,还复制GWT库在其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. 在dev模式类路径中, target/classes
是第一个条目,后跟源目录,然后是类路径上的每个jar。
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. 无论是在启动项目还是要求maven编译它时,都会运行此gwt:resources
目标,并移动所有源。 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. 然后,当您从IDE编辑文件时,IDE自己的编译器会更新target/classes
的.class文件,但不知道gwt:resources
的用途,因此不会重新运行它。 This means that while target/classes
has the latest .class
files, it has out of date .java
files. 这意味着虽然target/classes
具有最新的.class
文件,但它具有过时的.java
文件。
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. 如果您需要将源文件实际放在target/classes
,请确保gwt:resources
运行IDE中的每个资源更改,或者将源直接复制到target/classes
目录的另一种方法是设置<resource>
进入你的pom。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.