=== Step-by-step ===
For concreteness, these instructions are in terms of Eclipse/Windows
and assume that you created your project using GWT's projectCreator and
applicationCreator. As always, there's more than one way to do it --
but hopefully this will get you started.
1) Change your build output directory from "MyProject/bin" to
"MyProject/WEB-INF/classes".
2) Create the file MyProject/WEB-INF/web.xml such that it loads your
RPC servlet:
<web-app>
<servlet>
<servlet-name>myservice</servlet-name>
<servlet-class>
org.example.extserver.server.MyServiceImpl
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myservice</servlet-name>
<url-pattern>/myservice</url-pattern>
</servlet-mapping>
</web-app>
3) Create a Tomcat context file that will cause Tomcat to map your
project as a webapp
C:\Program Files\Apache ...\Tomcat
5.5\conf\Catalina\localhost\myproject.xml
whose contents look something like this:
<Context path="/myproject" docBase="C:\source\MyProject"/>
4) Test that your project is found by running Tomcat and browsing to a
known file, such as http://localhost:8080/myproject/.project (the
Eclipse project file).
5) Make sure that your client-side code references the right service
entrypoint using ServiceDefTarget. In this case, it would be something
like serviceDefTarget.setServiceEntryPoint("/myproject/myservice").
6) Create the directory MyProject/hosted. Copy all the public files
you care about on your public path (that is, files in public packages
that normally get copied into your GWT compile output directory). This
should include at least gwt.js and history.html. If you are using a
static HTML host page, you can copy it here, too. (By the way, the
directory need not be named "hosted" -- it could be anything.)
7) From gwt-user.jar, extract the file
"com/google/gwt/core/public/gwt-hosted.html" into MyProject/hosted
(don't include the package directories -- it should be an immediate
child of the directory).
8) Launch Tomcat.
9) Launch the GWT development shell with the "-noserver" option.
10) In the hosted browser, browse to the host page on your Tomcat
server. For example,
http://localhost:8080/myproject/hosted/MyApp.html.
At this point, you should be able to continue the normal edit/debug
cycle for your client-side code as normal in Eclipse. And if you use a
Tomcat launcher that is integrated into Eclipse, such as
<http://www.sysdeo.com/eclipse/tomcatplugin>, you can actually debug
the server side as well. Instead of having a single JVM process, you
have two: one for the GWT development shell and one for the Tomcat
process.
-- Bruce
There are a couple of things in this setup that bother me and I'd
prefer to do a different way. For example, I do not want to have to
put a project name into my source code as is shown in your
setServiceEntryPoint("/myproject/myservice") code. It is generally bad
practice to have something that is deployment specific (the name of the
web application context) be hard coded within the source code. So, it
would be nice to be able to determine this programatically. I suppose
that a way to do this is to call GWT.getModuleBaseURL() and also call
GWT.getModuleName() and assume that the context name for the web app is
the difference between these two like: moduleBaseURL.substring(0,
moduleBaseURL.indexOf(moduleName)) - however this is a bit clunky. I'd
like to be able to easily determine the context root of my web app from
within my client-side code so that I can use it to initialize the RPC
target address.
It would be nice if there was more flexibility in the tools in order to
support various project structures. I do not like the idea of having a
server using my source project directory as the root of a web app
context. Instead, I prefer to build a project and produce a seperate
directory entirely for the running web-app context. And I want to be
able to generate the client side source in directories that make sense
with respect to the URLs needed to access these resources (I don't want
a URL like
http://someserver/someapp/com.mycompany.mypackage.MyModule/somepage.html
when what really makes sense is
http://someserver/someapp/somepage.html)
I've gleaned a bunch of information from your step-by-step instructions
that will help me set my complex build process up a bit more simply so
that I can still test under hosted mode using my RPC services. So,
thanks a ton for providing this information! I'm looking forward to
seeing where GWT goes from here.
I hope that there are no problems with doing this move/copy... for
example, if more than one module is being compiled, will there be any
name collisions if you flatten the output to the same directory? I'd
love to get an answer to that from someone at Google.
I suggested "hosted" because I was thinking of an earlier (unreleased)
implementation of the compiler that always cleaned the output directory
before a compile, which would've blown away gwt-hosted.html, etc.
The GWT Compiler does not clean the output directory first, so it would
indeed be safe to manually copy files there. And it also simplifies
development because the compilation process already pulls in all the
files on your public path.
-- Bruce
In general, it is safe to "smash" a bunch of GWT output directories
together in the same folder as long as your own files don't cause name
conflicts. All of the compiled code goes into hashed filenames which
are extremely unlikely to conflict, and the script selection files are
fully qualified.
Scott
Hi imbrue,
One of the main motivations for using the module name for the leaf
output directory was to keep hosted mode simple. In a single debugging
session, you might access many different modules (for example, as you
go from page to page or by attaching multiple modules to the same
page). When you press the "Compile/Browse" button, each module needs a
unique output directory. If the GWT compiler used the "-out" argument
verbatim as the final output directory, then the compiler output for
different modules would get tangled up. So, instead, you specify
"-out" once and all module output gets placed under it in a predictable
way.
We wanted to make hosted mode as easy as possible, with the assumption
that when you're building for deployment you're already using something
like ant or make, so it wouldn't be a big deal to copy things around.
Keep reading below for a couple of alternatives.
>
> I hope that there are no problems with doing this move/copy... for
> example, if more than one module is being compiled, will there be any
> name collisions if you flatten the output to the same directory? I'd
> love to get an answer to that from someone at Google.
You definitely *can* copy all of the files from the compiler output
directory wherever you want them. There are no external dependencies
in deployment unless you're using RPC, in which case you need the
servlet stuff.
As for name collisions, you'll be fine mixing files from different
output directories together as long as you don't have actual naming
conflicts among your static files. In fact, this scenario is one of
the reasons that compiled output gets funky MD5 names. (The other
reason is that you can get perfect -- and really fast -- caching
behavior, which we haven't really explained well yet.)
Finally, let me mention the "=" syntax, which isn't yet documented. In
your <meta> to include your module, you can specify the module base
path, which need not be the fully-qualified module name. For example,
supposed you want your entry point URL to be
http://myserver/yogurt/cups.html
In cups.html, your <meta> tag should look like this:
<meta name='gwt:module'
content='/yogurt=com.example.yogurt.YogurtModule'>
And all your compiled output would need to be accessible in /yogurt.
A really easy way to get the same effect on Linuxes is to use symbolic
links -- in which case, you can directly build into the compiler's
natural output directory and still get the pretty URLs you want. You
can find out programatically where a module is "mounted" using
GWT.getModuleBaseURL(). That's how you can easily find static
resources and servlet entry points in your code without having to
hard-code strings in your client-side source.
-- Bruce
I'd really like to hear what you have to say about serialization.
http://groups.google.com/group/Google-Web-Toolkit/browse_frm/thread/a7dc1efbe707a6ba/#
Posts sort of get buried in this group. It might be nice to create
some subgroups for different categories of questions.
Thanks! That's kind of what I figured because I saw the hash values in
the filenames. Good to know that it is safe to build the way I am.
I'm going to tweak my setup based on the fact that the module meta tag
allows the "=" for base path. Should make my organization much better.
- Mark (imbrue)