Showing posts with label Tomcat. Show all posts
Showing posts with label Tomcat. Show all posts

Sunday, January 28, 2007

Using Apache as a Proxy for Tomcat Applications

I spent the day trying some configurations to make the integration between Apache HTTP Server and Tomcat.

The configuration that worked best for me basically was to setup a VirtualHost in Apache as a proxy with the same name as the application in Tomcat engine. As a resume, below tou will find some of the steps I went through and what I changed in the configuration files (I am using Apache 2.2 and Tomcat 5.5).

In Apache it is necessary to enable the mod_proxy Module and setup a NameVirtualHost. The httpd.conf (found in %APACHE_HOME%/conf) configuration file should be changed as below.

#Uncomment or add the lines below into the general session of your httpd.conf file.
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

# Add the Virtual Host for your application at the end of the file
NameVirtualHost *

<VirtualHost *>
  ServerAdmin serveradmin@domain.com
  DocumentRoot "C:/java/Tomcat5.5/webapps/"
  ServerName myapplication.domain.com
  ServerAlias *.myapplication.domain.com

  ProxyPass /foo-app http://localhost:8080/foo-app
  ProxyPassReverse /foo-app http://localhost:8080/foo-app
</VirtualHost>

After setting this file in your apache server, restart it and proceed to configuring the Tomcat Server, by editing the server.xml file (found in %CATALINA_HOME%/conf). Simply add the lines below at the end of the file, but inside the <server> tag.

<Service name="Tomcat-Apache">
    
    <Engine name="Apache" defaultHost="myapplication.domain.com" debug="0">
    <Host name="myapplication.domain.com" debug="0"
            appBase="c:/java/Tomcat5.5/webapps/foo-app" 
            unpackWARs="true" autoDeploy="true">

        <Context path="/foo-app" docBase="c:/java/Tomcat5.5/webapps/foo-app" debug="1" reloadable="true"/>
    </Host>

    </Engine>

  </Service>  

Now, open your browser and type the URL http://myapplication.domain.com/foo-app and you should be redirected to your application after passing by Apache and Tomcat.

Tomcat RMI Unmarshalling Exception

This is one of those posts that shows how frustrating sometimes the developer job can be! :)

I had a WAR component that was delivered successfully and worked fine in Jetty 6.0 rc2, but the same WAR file would not work under Tomcat 5.5. This application uses some session beans that are available in my JBoss Server. When I tried to execute the lookup() command in my client application running in Tomcat I had an exception thrown:


java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is: java.net.MalformedURLException: no protocol:


Then I asked: Why? Why does it work in Jetty like a charm? Reading ahead at the message of the exception I noticed the MalformedURL message included this: "5.5/temp/0-fisio-web-1.0-SNAPSHOT/WEB-INF/classes/" which made me realize that this was just part of the full URL where my Tomcat Server was running. Searching through the net I found this post, which led me to this other post (and there is also this other post on this subject).

For my surprise this is a known bug since JDK 1.2, marked as WON´T FIX by SUN! Is it unbelievable or not??

There is a workaround suggested by Sun that says that one should use

file.toURI().toURL()

instead of

file.toURL()

but many times, this is not in our hands, as is my case because Tomcat is taking care of this for me, so unless me (or some other generous soul) change and test (and do a backward compatibility test which seems to be what is frightening SUN into not changing this behavior) this way of implementing the RMI communication, the best thing to avoid this problem is to install all your applications in a path that does not include white spaces or illegal characters.

Saturday, January 27, 2007

Using Maven to deploy application to Apache Tomcat Server

For those who are not familiar with Maven, it is (as stated in the project site) a "software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information."

Based on the concept of "convention over configuration" developers may use Maven to compile, build, test, deploy, generate reports and use a whole bunch of other features to manage their software development project. In another oppportunity I will post an article about Maven, for now I will write about my most immediate need: deploy a war file to a tomcat server.

As I am using maven to manage my project from test to build, all I need is to configure the Cargo plugin. Cargo is able to download, install and start Tomcat, but this is not our focus right now, so I will assume you have Tomcat installed and running with no problems.

Using Maven´s Cargo plugin it is possible to install an application into Tomcat in two ways:

  1. Use the Tomcat Manager application, which is deployed by default with Tomcat 5.x and is nothing more than a web interface to manage your server. It has the ability to install a WAR into the server from a remote location.
  2. Copy the WAR File of your application directly into the File System where Tomcat is expecting applications to be, normally %CATALINE_HOME%/webapps.
As one can find strong and weak points in each of these options, I will tell a little bit about the first one.

Using the Tomcat Manager

Now we will deploy an application to Tomcat while it is still running. This is called Hot Deploying.

You should add some comands to your pom file, and they should look like the excerpt of code below. Actually it should be positioned between the tags:
<build>
<plugins>
...
</plugins>
</build>

<plugin>
<groupid>org.codehaus.cargo</groupid>
<artifactid>cargo-maven2-plugin</artifactid>

<configuration>

<!-- Container configuration -->
<container>
<containerid>tomcat5x</containerid>
<type>remote</type>
</container>

<!-- Configuration to use with the Container -->
<configuration>
<type>runtime</type>
<properties>
<cargo.tomcat.manager.url>http://localhost:8080/manager</cargo.tomcat.manager.url>
<cargo.remote.username>admin</cargo.remote.username>
<cargo.remote.password>admin</cargo.remote.password>
</properties>
</configuration>

<!-- Deployer configuration -->
<deployer>
<type>remote</type>
<deployables>
<deployable>
<groupid>com.company</groupid>
<artifactid>web-component</artifactid>
<type>war</type>
</deployable>
</deployables>
</deployer>

</configuration>

</plugin>
You should need to change only the values in the and tags with the values that describe your component WAR file you wanto to install to Tomcat.

Having this in your pom file, you need to issue the following command:

mvn cargo:deploy
If you already have the application running in tomcat it is necessary that you undeploy it before deploying. So, issue the command below and you should be ok:

mvn cargo:undeploy

You also have the option to execute a command that will do an undeploy before attempting to deploy:

mvn cargo:deployer-redeploy
That should be enough to get the application running in Tomcat, deploying from a remote server.

I would just like to add that the configuration for the tags
and are values that must match the ones in the tomcat-users.xml file with the role "manager". Check this before trying to do the deploy.