When you develop apps with GWT, these apps often involve RPC calls. The server functionality accessed through the RPC calls may require extensive server configuration, for instance, it may
require access to a data source. It is next to impossible to configure the built-in jetty server in these cases, and the solution is to use your own servlet container for handling the server requests.
In 1.6 is has become easier to use an external servlet container than in previous versions, because the GWT compiler places its output in a war directory that has identical structure as the
directories holding web application in tomcat and other servlet containers. This makes it easier to `copy' the project to an external servlet container.
These are the steps you must take to use an external tomcat instance that runs within eclipse instead of the GWT-built-in Jetty instance.
1. Create GWT project and host page., assuming it does not exist already. Look up the host page and put a landmark in there (some text or html) so that you can recognize it later on. The host page is located in the war directory of the project.
Compile the project by pressing the `compile/browse' button in the hosted mode browser. This will create a new subdirectory in the war directory of the project that holds your compiled code. The name of the subdirectory is identical to the project name in lowercase.
2. Create a `dynamic web project' in Eclipse. Instruct eclipse to use `war' as content folder, by changing the content folder form `WebContent' into `war'. (This can be done in the 2nd screen of the `create new web project' dialog.) It is smart to give this project a helpful name, such as YourGWTProjectName-ExternalServer.
3. Make a symbolic link to GWT war folder from the dynamic web project.
The war directories play an identical role in both projects.
(If you look at the directory form which a regular
tomcat runs its applications (e.g. $CATALINA_HOME/webapps/) you will see that all subdirectories have identical structure to the war directories in both projects.) They both hold the contents for the web application. Hence, we can plug the GWT-war folder into the dynamic web project.
First, note the file-system location of the `war' folder in the GWT project by looking at the properties of the folder in the project explorer. Then, delete the war folder in the dynamic web project. Create a new folder in the new project, called `war'. Press the `advanced' button, and have the new directory link to the war directory of the GWT project you noted earlier.
After this step, there will probably still be some errors in the project.
4. Remove errors. Add gwt-servlet.jar to the dynamic web project though the `configure build path' option in eclipse. This will get rid of some of the errors. Possibly there are more and you may need to include more jar's, either in the WEB-INF/lib directory of the dynamic web project, or in the lib directory of the tomcat home directory. (Usually called $CATALINA_HOME/lib .) Besides adding the JAR's, in my case, the order of the elements in the web.xml file was incorrect, so that gave a validation error. Changing the order fixed that. (I had to place the welcome-file-list element just before the closing tag.)
4. Deploy the `dynamic web project' you created in step 2 to the tomcat instance in your workspace. If you do not have a tomcat instance in your workspace yet, you must create one first through new | other | server etcetera.
5. Start the tomcat server. Easiest by pressing the `run' button in the servers tab in the JavaEE view, but there may be dozens of other ways to start tomcat from eclipse.
6. Look at your landmark page. Navigate your browser to your host page on the tomcat server. The url will be something like
http://localhost:8080/YourWebbProjectName/YourHostFileName
You should see host html page with the landmark you placed in it earlier.
7. Use external tomcat from GWT project. Instruct GWT hosted mode to use your tomcat server instead of the embedded Jetty server. This can be done by opening the run configuration for the GWT project (run | run configurations). Then, In the 'Main' tab, under the Embedded Server section, uncheck the "Run built-in server" checkbox.
Next, in the "GWT" tab, change the URL to point to the URL you used in the previous step.
8. Start the gwt app in hosted mode. You will see a reference to your tomcat server in the address bar.
9. Re-organize packages. Of course, your client code stays in the GWT project, so you can run it with the hosted mode, which enables debugging of the client code from within eclipse.
However, there is no need to have the server code in the GWT project anymore, so that can be moved to the dynamic web project project. (Move the packages into the src directory on the server project.)
The classes that are common to client and server can either be copied into both projects. This is the easy way: it works but it leads to code duplication. If you want to do it the neat way, the
classes can be placed in a separate `common' package in its own project. From there, you can create a GWT module for the common classes that can be inherited by your client module. for the
server, you can just add a project dependency in eclipse.
10. CONFIGURE TOMCAT. NOW THAT YOU ARE USING YOUR OWN TOMCAT INSTANCE, YOU CAN CONFIGURE THE TOMCAT INSTANCE ANY WAY YOU WANT, I.E. ADD DATA SOURCES TO IT.
Also, because the symbolic link in the file system exists, there is no need to explicitly copy the contents of the GWT-war folder to the tomcat server. (In a previous version of this blog post, this directory was copied manually, and this copy-step had to be repeated periodically.) However, you *should* re-compile the GWT project into javascript and press the refresh button (F5) on the dynamic web project now and then.
Abonneren op:
Reacties posten (Atom)
i managed to run it all in one project (just configured my dynamic web project to use 'war' instead of 'WebContent' dir and then added all the necessary GWT configurations to this project).
BeantwoordenVerwijderendon't know if this is 'neat', but it's sure very handy.
I too managed to run all in one project using the above solution, but can't run my GWT app in hosted mode any more. The hosted mode browser just shows me the loading page of my app while the following error appears in the GWT development shell window:
BeantwoordenVerwijderen[ERROR] Failure to load module 'gwtapp'
java.lang.NoSuchMethodError: org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding.genericType()Lorg/eclipse/jdt/internal/compiler/lookup/ReferenceBinding;
Accessing my app using a normal browser works fine though.
I was wondering if someone else has encountered the same problem and maybe has found a solution.
In a new version of this howto, a symbolic link is created from the DW projects' war folder to the GWT projects' war folder. This prevents any copying and works well for me!
BeantwoordenVerwijderen