Has anybody done anything similar? Can someone shed some light on how
to configure so that GWTShell can host and debug the client-side while
sending RPC requests out to my external Tomcat container?
Alternatively, if there is a way to configure the internal shell's
tomcat to host a fully configured additional web application that needs
its own initialization, that would be helpful.
If anybody thinks they can help but needs further details, please let
me know.
Thanks!
Seems strange. You'd think the google guys would have bigger web apps
with server side code that they would need to make available during
debugging as well. I just want to know how they have their dev
environment set up.
The key here was understanding how to "trick" the shell using the fact
that it makes the request for gwt-hosted.html.
First, let me explain my scenario. I have a seperate project which
produces a JAR file containing business logic for a variety of web
applications. Each new web application needs to put this JAR file into
its WEB-INF/lib folder so that it has access to this business logic. I
wanted to expose some of this business logic through GWT RPC services
so that I can write rich client apps as opposed to the standard
server-side access of these services (previously done through a Struts
architecture requiring new browser requests to actions that invoke the
services and return a new page to the browser). In order to do this, I
wanted the build of the business logic JAR file to also produce a JAR
file containing the client-side interfaces. Note that since these
interfaces are code that must be translated by the GWT Compiler, this
secondary product of the business logic project must contain Java
source (*.java and *.gwt.xml) instead of the compiled class files.
So, my source tree for the business logic project looks something like
this:
src/com/mycompany/services/*.java
src/com/mycompany/gwtrpc/BizLogic.gwt.xml
src/com/mycompany/gwtrpc/client/MyService.java
src/com/mycompany/gwtrpc/client/MyServiceAsync.java
src/com/mycompany/gwtrpc/server/MyServiceImpl.java
The BizLogic.gwt.xml file contains an empty <modlue> tag since the
"client" package is assumed for source, and I don't need any <inherits>
or <entry-point> definitions (at least at this point).
When I build the business logic project, I produce 2 jar files. The
first is named BizLogic.jar and contains all of the compiled classes
and the second is called BizLogicGWTClientLib.jar and it contains:
src/com/mycompany/gwtrpc/BizLogic.gwt.xml
src/com/mycompany/gwtrpc/client/MyService.java
src/com/mycompany/gwtrpc/client/MyServiceAsync.java
Now, for my GWT based web application (which is a seperate project), I
put the BizLogic.jar into the WEB-INF/lib folder and also add the
javax.* stripped version of gwt-user.jar, which I have named
gwt-user-stripped.jar. This application has a source tree that looks
something like this:
src/com/mycompany/gwt/MyModule.gwt.xml
src/com/mycompany/gwt/client/MyModule.java
src/com/mycompany/gwt/public/default.html
MyModule.gwt.xml:
<module>
<!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/>
<!-- Inherit the BizLogic GWT Interfaces. -->
<inherits name="com.mycompany.gwtrpc.BizLogic"/>
<!-- Specify the app entry point class. -->
<entry-point class='com.mycompany.gwt.client.MyModule'/>
<!-- Specify the service RPC mappings. -->
<servlet path="/myService"
class="com.mycompany.gwtrpc.server.MyServiceImpl"/>
</module>
MyModule.java contains:
import com.mycompany.gwtrpc.client.MyService;
import com.mycompany.gwtrpc.client.MyServiceAsync;
...
MyServiceAsync myService = (MyServiceAsync)GWT.create(MyService.class);
ServiceDefTarget target = (ServiceDefTarget)myService;
target.setServiceEntryPoint(GWT.getModuleBaseURL() + "/myService");
myService.doSomething(...
Now, when I build the web application, I run the GWTCompiler with a
class path that includes the webapp's source directory (to find
MyModule), the BizLogicGWTClientLib.jar (to find the BizLogic module),
and the GWT Jar files. This produces a directory named
com.mycompany.gwt.MyModule containing the default.html, gwt.js, etc.
However, I did not want this in my webapp under a subdirectory, so I
copy all of these generated files directly into the root of my target
web application base directory (in other words, default.html is
accessible from http://localhost:8080/MyWebApp/default.html).
I also put a copy of Luca Masini's gwt-hosted.jsp into my WEB-INF
directory.
Now, my web.xml looks something like this:
?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>MyService</servlet-name>
<servlet-class>com.mycompany.gwtrpc.server.MyServiceImpl</servlet-class>
</servlet>
<servlet>
<servlet-name>gwt-hosted</servlet-name>
<jsp-file>/WEB-INF/gwt-hosted.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>MyService</servlet-name>
<url-pattern>/myService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MyService</servlet-name>
<url-pattern>/com.mycompany.gwt.MyModule/myService</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>gwt-hosted</servlet-name>
<url-pattern>/gwt-hosted.html</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/default.html</welcome-file>
</welcome-file-list>
</web-app>
Note that the MyService servlet is mapped to both "/myService" (used in
normal situation) and "/com.mycompany.gwt.MyModule/myService" (when
running in hosted mode).
I run this web application in a seperate Tomcat server, and I can
access it through http://localhost:8080/MyWebApp. I can run the
GWTShell in debugger and use this same URL and the shell will hit
/gwt-hosted.html and be tricked as previously discussed. The code in
MyModule.java that sets the service entry point for my service will use
"/MyWebApp/myService" when running in normal browser and
"/MyWebApp/com.mycompany.gwt.MyModule/myService" when running in hosted
mode. Both map to the service in my external Tomcat server.
I can debug the client-side Java code for the application and I can run
the web app normally with no modifications.
Hope this helps!
I guess that since my services rely on other back-end services that I
can't easily host inside the "hosted-mode" tomcat, I can never really
hope to host the RPC Service by itself in "hosted-mode" and will never
be able to run the hosted-mode tomcat anyway (I'll always specify
-noserver).
Unless someone knows of some other reason the <servlet> tag needs to be
inside the module definition file (other than to configure the
hosted-mode tomcat server), I don't see any way I can use it.
This includes the gwt.js and history.html files.
Hope that helps. Let me know.
-- Bruce