Embedding a Web Application in Eclipse and Tomcat
Christopher L Merrill
Private Message cm68669 on EclipseZone
©2006 Web Performance, Inc
January 30, 2006
v1.0
Introduction
Both Eclipse and it's RCP brethren have a webserver embedded within
them: a re-packaged Apache Tomcat server. It is included as a part of
the Eclipse help system. Is it possible to deploy a web-application to
that embedded server and make it available to the application and/or an
external browser? (hint: yes)
First, you might ask: Why would you want to do this?
After all, if I'm building a
rich-client application using the Eclipse RCP, then why would I want to
deploy a web application and access it through the browser? The point
of the building the application as a rich client was to get away from
web apps, right? I've heard a number of reasons why one would want to
do this. Our motiviation was simple: reporting. Our application
performs a number of detailed analyses and generates reports
summarizing the results. We could certainly present this information in
a rich-client GUI. The problem occurs when the users demand output to
pass on to other parts of their business, either electronically or in
print. If we implemented the reports with a GUI, we would need to
duplicate the effort to get the reports into a paper or electronic
format.
Instead, we can use a web-based reporting tool and generate the reports
in HTML, accessible via an embedded browser within the application.
Then the report can be easily output in HTML for sending electronically
or exported to PDF or other formats, depending on the choice of
reporting tools.
This article assumes that the reader already knows how to write, package and deploy Eclipse plug-ins and JEE web applications.
It should be noted that this
example
uses internal, undocumented Eclipse 3.1 APIs. There is no
guarantee it
will work in future Eclipse releases. Hopefully, the Eclipse team has
recognized the value of these APIs to developers and will make them
public and supported.
The Goal
The goal appears to be relatively simple:
- Deploy a web application in Eclipse's embedded Tomcat server
- Allow that web application to pull data from an Eclipse
plug-in and display it in an embedded browser in an Eclipse view or
editor
The first goal implies a few sub-goals. The Tomcat instance does not
appear to be started when Eclipse is started. This evidenced by the
long startup time when the Help system is first activated. It will be
necessary to be able to start the Tomcat instance when necessary.
Additionally, the port and path of the deployed web-application will be
needed in order to direct a browser to the web-application. If those
are not specified as part of the web-application deployment, then they
will need to be discovered dynamically.
The Plan
This
plug-in works in a somewhat circular fashion: A user action in our
plug-in causes an embedded browser to be pushed to a URL that
corresponds to a servlet in our embedded web-app. The servlet then
queries the plug-in for the data to display and formats it as a web
page. The page is then returned back to the embedded browser where it
is displayed in our plug-in.
Here is a picture of our working plug-in:

In the plug-in shown above, the view consists of a text field where the user has entered some text. After pushing the browse button, the resulting web page is displayed in the embedded browser.
How To Do It?
To accomplish our goal we will need learn how to:
- register our web application
- start the Tomcat instance
- find where the Tomcat instance is running to determine what URL will access our Servlet
- when the browse button in the view is pushed, send the browser to this URL
- access our plug-in from within the servlet to get access to the input entered in the view
Register the web application
This part actually turns out to
be pretty easy. As you might expect, the web-application is deployed in
a directory structure identical to what you would deploy in a
standalone Tomcat installation. The only difference is that the
application folders appear within the Eclipse plugin that we are
building:

As you can see, we have a WEB-INF folder with a classes folder below it. In the WEB-INF folder is a typical
web.xml file that maps our servlet to a path that we will use in constructing a URL. The servlet, named
PluggedIn, is mapped to the
/pluggedin pattern within our web application - as shown below:
<web-app> <servlet> <servlet-name>PluggedIn</servlet-name> <servlet-class>example.webapp.PluggedInServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>PluggedIn</servlet-name> <url-pattern>/pluggedin/*</url-pattern> </servlet-mapping> </web-app>
|
The only additional step is to register an extension with an Eclipse extension point in our plug-ins descriptor file (plugin.xml).
<extension point="org.eclipse.help.base.webapp"> <webapp default="true"> </webapp> </extension>
|
Start the Tomcat instance
Starting up Tomcat is actually quite simple. But it requires the use of
an internal class whose documentation is not included in the
distributed javadocs. Fortunately, the code includes Javadocs, so once
you know where to look, using it is quite straightforward - a single
line of code, plus whatever exception handling you deem fit for your
particular application. This method will start our web-application on
the Tomcat instance. If Tomcat has not yet been started (for example,
by the help system), it will be started.
WebappManager.start(context, plugin_id, path);
|
This method takes three parameters:
- context path for the web application - all paths mapped in your web application will be relative to this
- ID of the plugin owning the web application - this allows the WebappManager to find the application files
- path of the web application folder, relative to the plugin folder
The result is a method on our plug-in class:
public static boolean ensureWebappRunning() { if (!_started) { WebappManager.start("example", "example.webapp.plugin", Path.EMPTY); _started = true; } }
|
This method could be called by our plugin at start time or on demand
when needed. As seen later, we will start it on-demand - when the
button is pushed in the GUI.
Find where the Tomcat instance is running
Now that the application is running, we want to send the browser to
it...but we don't know what port it is running on. Fortunately this is
easy, using the
WebappManager we discovered above:
You can also determine what host address the server is running on,
since there could be multiple IPs on a given machine. Together with the
context we registered with the web application and the context of our
servlet within the web application, we can determine the entire URL
with this method of our plug-in class:
public String getExampleServletURL(String servlet_path) { return "http://" + WebappManager.getHost() + ":" + WebappManager.getPort() + "/example/" + servlet_path; }
|
Send the browser to the URL
When the browse button in our GUI is pressed, we perform the following:
public void widgetSelected(SelectionEvent e) { ExampleWebappPlugin.ensureWebappRunning(); String url = ExampleWebappPlugin.getInstance().getExampleServletURL(servlet_path); _browser.setUrl(url); }
|
Get input from the view into the servlet
This part is very simple because the classes within our web application
have full access to the classes of the plug-in they belong to. In the
GUI, as text is typed in the input field, the value is saved in the
plug-in class. The servlet can simply access the plug-in class and ask
for the text that was entered by the user. The view could have been
queried directly, of course, but this approach makes for a simpler
example. This part of the servlet looks like:
out.println("<p>"); out.println("You typed: " + ExampleWebappPlugin.getInstance().getTextEntry()); out.println("</p>");
|
Downloads & Feedback
The entire source for this example is available
here. You can unzip this file into your Eclipse
plugins folder, restart Eclipse and then open the
Example Webapp view from the
Other category (
Window->Show View->Other...).
If you would like to discuss this report, please post your questions
at the EclipseZone page for this article. Or you can send me a private message (username
cm68669) at EclipseZone
Version History
v1.0 - 1st public release (30 jan 06)