M2Eclipse Automatic Tomcat Deployment in Eclipse

Today we’ll be looking at how to deploy to maven web project to a Tomcat server instance from within Eclipse.

Tools

  • Mac OS X Lion
  • Apache Maven 3.0.3 (pre-installed with Lion)
  • Apache Tomcat 7.0.21
  • Eclipse Indigo 3.7 (Eclipse IDE for Java Developers 1.4.1)
  • m2e – Maven Integration for Eclipse 1.0.1
  • Maven Integration for WTP 0.14

This post assumes that you have Maven, Tomcat, and Eclipse installed and working.

You will now need to add Maven support to Eclipse by installing the m2e – Maven Integration for Eclipse plugin. Instructions for doing this can be found here (http://www.eclipse.org/m2e/).

Once this plugin is installed, you can create a Dynamic Web Project within Eclipse and enabled the Maven project facet for it (this can be done via the context menu for the project Configure->Convert to Maven Project).

Now that we have Maven support from within Eclipse, we need to install the Maven Integration for WTP plugin so that we can deploy to a Tomcat server instance from within Eclipse via Maven.  This plugin is available via the m2e Marketplace.

Open the Eclipse preferences, go to Maven->Discovery->Open Catalog and select the m2e-wtp item and click Finish. This is documented here (http://stackoverflow.com/questions/6356421/maven-tomcat-projects-in-eclipse-indigo-3-7). It should be noted some users (including myself) experienced an issue that made it so that the web project would not properly deploy until you delete the web project from Eclipse and import it again. Once this plugin is installed and working, you can deploy the web project to a Tomcat server instance, like normal, and the plugin takes care of pointing it at the appropriate maven package (WAR).

Enjoy!

Maven to Tomcat Deployment

Today we are going to talk about getting up and running with a web project for Maven. Sure, you can just run the “mvn package” statement from the command line and then go copy the generated WAR file into Tomcat’s webapps directory. That is certainly the simplest way. However, you can get Maven to deploy your web project automatically to Tomcat for you.

Tools

I am using the following for this exercise. Results may vary if your versions/tools do.

  • Mac OS X Lion
  • Apache Tomcat 7.0.21
  • Apache Maven 3.0.3 (pre-installed with Lion)

For this exercise, I’m assuming you have Tomcat, Eclipse, and Maven installed and working.

Installing the Mojo Codehaus Tomcat-Maven Plugin

The key to automatic deployment to Tomcat via Maven is by using the the Mojo tomcat-maven plugin. We need to add this to our existing project’s POM file.

<build>
<plugins>
...
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>tomcat-maven-plugin</artifactId>
    <version>1.0-beta-1</version>
    <configuration>
    <url>http://localhost:8080/manager/text</url>
        <port>8080</port>
        <path>/my-webapp-path</path>
        <warFile>${project.basedir}/target/${project.build.finalName}.war</warFile>
        <server>myserver</server>
    </configuration>
</plugin>
...
</plugins>
</build>

The <url> element value needs to be set appropriately for the version of Tomcat that you are running. You can get further details on this here (http://mojo.codehaus.org/tomcat-maven-plugin/configuration.html).

The <path> element value should be the context to use when your application is deployed. The one with the settings up above would be located via: http://localhost:8080/my-webapp-path

The <server>element is being used to associate this server with a set of authentication credentials that are stored in your Maven repository’s settings file. Let’s deal with these credentials next.

When you install Tomcat, start it up, and navigate to it’s management console (/manager), you will be prompted to login. The Mojo plugin has to login, as well, before it can deploy. Therefore, we need to setup credentials under Tomcat that have access to the management console, and then tell Maven about these.

Add Management Console User Privileges to Tomcat

To setup the proper credentials under Tomcat, add the following to your tomcat-users.xmlfile ($tomcat_directory/conf/tomcat-users.xml):

<tomcat-users>
...    
   <user username="admin" password="admin" roles="manager-gui, manager-script" />
...
</tomcat-users>

For more information on tomcat user privileges read the manual here (http://tomcat.apache.org/tomcat-7.0-doc/manager-howto.html#Configuring_Manager_Application_Access). Now we need to make maven aware of these credentials by putting them in the settings file ($user_home_directory/.m2/settings.xml).

<servers>
    <server>
        <id>myserver</id>
        <username>admin</username>
        <password>admin</password>
    </server>
</servers>

You’ll note the <id> element value matches the <server>element value from our Mojo plugin reference in our POM from above. Now when you run the following command from the command line, your WAR will be deployed to Tomcat automatically:

mvn tomcat:deploy

First RESTful Web Service Using Apache CXF

OK, so like a lot of folks out there, I was all eager to start building RESTful web services for my product. Only one problem… there is still a bit of mystery involved in getting a setup working with everything ready to rock and roll.  Here are my notes in the hopes that it will help you break thru the entry barrier (this is one of several different approaches to the problem).

Tools

  • Mac OS X Lion
  • Apache Tomcat 7.0.21
  • Apache Maven 3.0.3 (pre-installed with Lion)
  • Eclipse Indigo (Eclipse IDE for Java Developers 1.4.1)
  • M2Eclipse Plugin 0.12.1
  • Spring 3.0.1
  • Apache CXF 2.5.0

Make sure these tools are installed before moving forward (plenty of info on the web about these tools and installing them that doesn’t need repeating here).

By using maven’s quickstart archetype, we can save some time setting up our initial project. If you aren’t familiar with Maven, the following should get you up to speed:

  • Maven in 5 Minutes (http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html)

So essentially,

  • navigate to your workspace directory ($workspace)
  • Execute the command to create a new project
    • mvn archetype:generate -DgroupId=com.dnascimb -DartifactId=cxf-demo-first -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false
  • This creates a directory $workspace/cxf-demo-first where the project will exist

Let’s open up Eclipse and bring in this new project, so that we can see the directory contents and work with the files a bit easier.

Project Directory Structure

Now we can see the directory structure maven created for us.

Let’s enable the M2Eclipse plugin to manage dependencies on this project so that we can get compilation working.

Now we can see that under the Maven Dependencies folder, maven has automatically brought in the required JUnit library (this was added to the POM file by maven).

Let’s take a look at the POM file and add additional dependencies which we’ll need.

As soon as we save the file, there are even more libraries Maven brings into the project based on the new information we put into the POM.

Let’s ensure that the Java version is 6 so that we can compile (since we’ll need features features present in version 5+).  This is done by adding the following to the plugin section of the POM file.

Let’s start creating some classes. But first, let’s define a source directory for our Java packages/classes to live in.

Then a new package for our classes.

Now let’s create our first class (our service). Let’s call it FooBarService.

Let’s put some functionality into this class.

Here we’ve added an @Service annotation to indicate that this class is a service and it is to be named “fooBarService”. We’ve also added an @Path annotation to indicate that it is accessible via the path “/foo” in our webapplication (URL: http://localhost:8080/<app>/foo)

We’ve created a method getFooBarMessage() that returns a String and has some annotations, as well. The @GET annotation indicates that it interacts via the GET HTTP method. The @Produces annotation indicates that it will return or produce content of type “text/plain”.

Now, let’s go ahead and configure the web descriptor (web.xml) to be aware of the Spring Context Listener and the CXF Servlet (these will help wire everything together so that annotations work and the classes can be loaded by the application properly).

Next step is the Spring configuration. Let’s create a new file beans.xml and modify its contents to tell it about the CXF configuration file, as well as where to start scanning to find our service classes. We will also define our JAX-RS container and the services it should be aware of.

Now all we need to do for a simple test is to compile/package all of it and deploy the WAR to Tomcat’s webapps directory.

If Tomcat is not running, start it and go to the following URL:

http://localhost:8080/cxf-demo-first/foo

You should see the string returned to the browser from our FooBarService.getFooBarMessage() method.

All for now.

Removing GXP from Struts2

Recently, I needed to upgrade to the latest distro of Struts 2 (2.2.3.1). Once I got all the libraries I needed moved into “WEB-INF\lib” of my project, I deployed to my server and started it up.

FAIL:

Caused by: java.lang.ClassNotFoundException: org.apache.struts2.views.gxp.inject.InjectedObjectContainer

Hrm, what’s this about? Turns out the “Essential Lib” download for Struts includes non-essential libs. Quite deceiving, in my opinion. If you aren’t going to use GXP (see this for more info on GXP), then you’ll want to remove GXP related JARs from your lib folder and get on with your day.

Removing GXP from Struts2

  • Remove “google-gxp-0.2.4-beta.jar”
  • Remove “struts2-gxp-plugin-2.2.3.1.jar”
  • Recompile/Redeploy/Restart server

Distributed Staffing: Effective Communication

In today’s IT industry, it is fairly common to be a part of a team that is distributed around the world. I have personally worked in such a fashion for over a decade, so I am all too familiar with the ups and downs of this staffing strategy. During this time, I have seen several occasions when people adapted their work and communication practices, and were able to reap the benefits of distributed staffing. I have also seen situations where people were unwilling to adapt, and therefore fail.

If you want to be in the winner’s circle of this game, you have to play by the rules:

  • exercise patience… miscommunication naturally occurs when there is a difference in culture, language, and abilities
  • use email for detailed communication, however, make sure to be concise and highlight important points
  • make use of instant messaging where possible, and enable logging for persistency
  • stage overlap time as needed (every other day? for an hour?) so that direct communication can take place
  • use Webex or GoToMeeting to enable all parties to view the same content in real-time when reviewing code or discussing design or as applicable
  • use desktop capturing tools (CamStudio – Windows, ScreenFlow – Mac) to record repeatable processes, try to limit them to digestible chunks (5 min duration)
  • stage “quick” status meetings with the entire team (similar to standup meetings in Scrum) to communicate important information to the entire team (across abilities and roles), as this helps make everyone feel like part of the team
  • video conferencing when available (the eyes and body communicate things that words alone cannot)
  • use a wiki + bug tracker (centralized/persistant knowledge sharing)

One of the most important things to remember is to treat everyone with the same respect you wish to be treated with. This is something that is easily overlooked when deadlines are tight and the pressure is on, but it is an integral part of forming a cohesive bond between everyone on the team and making them feel invested in the success of the work.

Winner’s Curse

Example Scenario:

You’re asked to take part in an estimate for this contract that the company really wants. If your firm gets this contract, the revenue reports will be all sunshine for the next several quarters. During the estimate process, you’re encouraged to not over-think the solution in an effort to keep the costs down.

Everything goes great, you get the project because you were the lowest bidder and promised that it could be done in half the time of the competition.  

Flash forward six months, management is giving you all sorts of grief, because it turns out the solution to the requirements wasn’t as straightforward as initially assumed, and you and your team are working weekends/nights in an effort to meet the crazy deadlines and expected profit reports.

Sound familiar?

Turns out that when management tells their teams “you’re not good at estimating”,

A)   It may not be as simple as that

B)   You’re not alone

C)   It could be due to the nature of the current process

There is a concept known as the “Winner’s Curse”, which says that those bidding on a project can have a tendency to be over-optimistic in their estimates, to the point of negatively impacting overall profit margin, in an effort to win the bid. This means that you end up getting the project, but you underestimate the work involved, so it actually doesn’t generate much profit for your firm (in some cases it actually costs your firm money).

You may have seen instances of this occur in your line of work, especially if you work at a contracting or consulting business.

It seems like a natural thing to try and come in as the lowest bidder when competing with others.  The goal is to get the project, right? Well, it turns out that this type of thinking leads to the very situation I’m speaking of.  The team focuses on coming up with the lowest possible estimate they believe they can stand behind, but does so by neglecting to make realistic assumptions about what the task requires or how straightforward the solution will ultimately be.

<sarcasm>Shockingly</sarcasm>, this tends to occur given any of the following:

  • The client has a track record of selecting providers with the lowest bid
  • The market in question has a large number of competing providers
  • The client sets an unrealistic expectation of acceptable bids
  • Bidding is for a fixed-priced project
  • Stated requirements are vague in nature
  • The market in question has narrow profit margins

You may be thinking, “that sounds like the characteristics of every bidding process I’ve ever been a part of”, and this may be true to a degree. After all, businesses have a bottom line. They need some service or product that solves their current requirements while not exceeding the allocated budget. Budgets can be impacted by a number of factors, which may not always take current market trends, or knowledge of the solution, into account.

So how can one best avoid the dreaded winner’s curse?

  • Try to find customers that understand what the solution will involve and value quality and efficiency over lowest price.
  • Give a brief explanation of how your estimate was obtained. Note areas that are based on generic or vague requirements (the customer may not realize the impact this has on the accuracy of your estimates/bid).
  • Before estimating the effort of a potential project, try to determine the total number of competing estimates that will be present (how many teams or companies are going to be giving estimates).  The higher the number of competitors,  the more likely the winner’s curse will occur.