Статьи

GWT: Сервер разработки – Tomcat Lite

Оболочка GWT использует урезанную и несколько настроенную версию контейнера сервлета Apache Tomcat в качестве сервера режима разработки. Хотя это экземпляр Tomcat, GWT настраивает все по-другому, чтобы автоматизировать определенные элементы и облегчить быстрое и простое использование и тестирование в режиме разработки.

Развертывание приложений GWT в локальном Tomcat может быть несколько запутанным. Сказать, что GWT использует Tomcat, все равно, что сказать, что ваш любимый гонщик гоняет Camaro в гонках NASCAR. Это может выглядеть как Camaro, люди могут даже назвать его Camaro, но вождение это не то же самое, что вождение Camaro, которое продаст вам ваш местный дилер GM. Tomcat GWT имеет собственный дескриптор развертывания, web.xml, который включает в себя конфигурацию для специального GWTShellServlet. Этот сервлет используется в размещенном режиме только для автоматической отправки записей сервлета из файла вашего модуля в соответствующие классы.

[Img_assist | нидь = 3421 | название = | убывание = | ссылка = URL | URL = HTTP: //www.manning.com/affiliate/idevaffiliate.php идентификатор | ALIGN = право | ширина = 208 | Высота = 388] В Кроме того, Tomcat GWT не учитывает никакой информации о конфигурации контекста Tomcat (context.xml), хранящейся в вашем приложении. Вместо этого экземпляр GWT Tomcat использует web.xml (его собственный вариант context.xml) и набор домашних каталогов псевдо-Tomcat. Это может быть ограничивающим и разочаровывающим для разработчиков, которые хотят включить дополнительную конфигурацию уровня контейнера или приложения для использования внутри Tomcat Lite. Первое, что вы, вероятно, захотите изменить по своему вкусу, — это web.xml.

Файл web.xml

Сервер разработки Tomcat Lite по умолчанию не учитывает локальный дескриптор развертывания web.xml вашего приложения, поэтому обычно это первое, с чем вам приходится иметь дело при настройке параметров, связанных с приложением, которые вам нужны в размещенном режиме. Чтобы включить такие ресурсы, как фильтры или пользовательские ограничения безопасности, в вашем приложении в размещенном режиме, вы можете настроить файл сборки вашего проекта или изменить соответствующую структуру [PROJECT_HOME] / tomcat. Каталог [PROJECT_HOME] / tomcat, в котором по умолчанию установлен сервер Tomcat Lite в режиме разработки оболочки GWT, имеет следующую структуру по умолчанию:

  • [PROJECT_HOME] / кот

    • конф

      • web.xml (см. листинг 1)
      • GWT

        • локальный
    • WebApps

      • ROOT

        • WEB-INF
        • web.xml (см. листинг 2)

With that structure in mind, we’ll take a look at the files themselves to understand where to make modifications, should the need arise. The first web.xml file, shown in listing 1, is the one global to the whole server. By default, GWT sets this file up as a stripped-down version of the Tomcat base web.xml file that just includes some common MIME-type mappings. While the purist might argue that any MIME types you’re going to use in your application should be included in your custom web.xml file, many people don’t do this consistently.

Listing 1 The structure of the default server web.xml file

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!-- A tweaked version of the default Tomcat web.xml file
to remove everything except the stuff we want to use -->
<web-app version="2.4">
<mime-mapping>
<extension>abs</extension>
<mime-type>audio/x-mpeg</mime-type>
</mime-mapping>

<!-- stuff omitted... -->

<mime-mapping>
<extension>zip</extension>
<mime-type>application/zip</mime-type>
</mime-mapping>
</web-app>

The second web.xml file, displayed in listing 2, is the GWT-generated mapping for servlets specified in the module’s gwt.xml file through the previously noted special servlet, GWTShellServlet. This effectively proxies servlet mappings for use in hosted mode. (This servlet should never be deployed with your application — it’s only useful for hosted mode.)

Listing 2 The special GWTShellServlet mapping web.xml file

<?xml version="1.0" encoding="ISO-8859-1" ?>
<web-app version="2.4">
<servlet>
<servlet-name>shell</servlet-name>
<servlet-class>
com.google.gwt.dev.shell.GWTShellServlet
</servlet-class>

</servlet>
<servlet-mapping>
<servlet-name>shell</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

Working with these GWT-specific files and having your own web.xml configuration ignored in a development context is, of course, limiting in a number of ways. GWT won’t honor your security parameters or filter chains. Nor will GWT inject resource references into your JNDI tree. Synchronizing the servlet entries in both your GWT module file and a separate deployment descriptor that will later be included with your deployed application is also a pain, and prone to «fat-finger» errors.

The solution is to somehow modify the Tomcat Lite web.xml files to include your application’s local configuration information when you launch GWTShell. You can do this by hand, but it’s much more convenient to have a build process that inspects a local web.xml file (one that’s included in the source for your project, intended to be used outside of the hosted mode when you deploy) and includes your configuration information in the GWT files automatically.

Because you don’t want to define servlet elements in two places, and you ultimately want to have a web.xml file that’s deployed with your application that also matters to the GWT development server, you have a two-sided problem. That is, you may have GWT servlet elements defined in your module, and you may also have other application resources, such as security realm information, defined in your application’s web.xml. Yet you need configuration information from both sources to be available in both places (in hosted mode for Tomcat Lite, and outside of hosted mode in standard container format when deployed). To accomplish this, you can inject your configuration into the Tomcat Lite web.xml for hosted mode use, and you can copy the

elements from your module file into your web.xml for standard deployment.

In order to make this happen, you can add some intelligence to your build process to create a new web.xml file for hosted mode use. You can then use this new file to replace the GWT default webapps/ROOT/web.xml file. The important thing to keep in mind here is that, regardless of how you do it, you can modify the Tomcat Lite web.xml file for hosted mode configuration. You can also modify the Tomcat context.xml context descriptor in the same manner.

The context.xml file

If you want to include configuration resources at the Tomcat context level when working with the embedded Tomcat instance, and also have those resources available in hosted mode, you again have to manipulate the GWT Tomcat files. As an example, we’ll deal with a common problem: defining JNDI DataSource entries at the context level. We provide a sample method for getting around the overall issue.

First off, let’s talk about dependencies. GWTShell’s Tomcat instance does not include the libraries needed to load DataSource implementations into the JNDI tree on its own. If you want to use Tomcat’s DataSource handling, you need to include (from the Jakarta Commons project, http://jakarta.apache.com) the commons-dbcp and commons-pool JAR files in the startup classpath for your project. You also need to include the appropriate JDBC driver for your particular database.

Once you have the dependencies in place, you have to start GWTShell once to get it to write out a [PROJECT_HOME]/tomcat directory tree. This is effectively what you’d expect from $CATALINA_HOME in a regular Tomcat installation. Once this has happened, you can create or modify the main Tomcat Lite context file, which is renamed ROOT.xml in GWT. This file can be used to define your DataSources: [PROJECT_HOME]/tomcat/conf/gwt/localhost/ROOT.xml

You can add your DataSource information to the ROOT.xml location, or copy a custom META-INF/context.xml from your project into that location and rename it. The configuration shown in listing 3 can be used as a reference.

Listing 3 Example DataSource configuration for Tomcat 5.0.x context.xml

<Resource name="jdbc/demogwt" auth="Container" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/demogwt">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>com.mysql.jdbc.Driver</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:mysql://localhost:3306/myDatabase</value>
</parameter>
</ResourceParams>
</Resource>

When you do this, of course, you’re duplicating your context information and once again manipulating the Tomcat Lite files, rather than resources local to your project as you might normally expect. This is ugly, but it does get around the issue of including context resources and still makes development mode resources available as they would be in production, because they will be present once things are deployed. (This example is based on Tomcat 5.0.x. If you deploy to a newer version or a different platform, you’ll have to deal with configuration differences.)

NOTE

GWT will also let you specify a base Tomcat directory using the catalina.base system property. You can use this behavior to specify an alternative internal Tomcat location, which gives you many options with regard to creating and maintaining the internal Tomcat structure.

As an alternative to configuring the GWT-embedded Tomcat server, you can also use the hosted mode browser in standalone mode with an external servlet container by passing the -noserver switch to GWTShell on the command line.

This article is excerpted from Chapter 1 of GWT in Practice, by Robert Cooper and Charlie Collins, and published in May 2008 by Manning Publications.