Spring STS, Eclipse WTP, and building web apps with Maven

I get Maven. I get Eclipse & WTP. I want to use Maven for my dependency management, and I want to use Eclipse for it’s built in server suppport, for publishing, stopping and starting servers etc.

Several months back I took a look at M2Eclipse and it seemed it didn’t coexist well with WTP’s approach to web app directory structures. I’ve just taken another look and I got it working, but it took a few false starts and trial and error to find what works for me. In trying various things I’d either end up with a WTP style project which Maven wouldn’t build, or a Maven like directory structure which Eclipse wouldn’t build or deploy.

I’m pretty sure there’s many ways to do this, and I’m also sure Spring Tool Suite should be able to deploy a web project out of the box to your tc server without too much trouble, but it took a while to find what works.

One approach that does work but is probably not the best, is to add the tomcat-maven-plugin plugin to your pom.xml, define your Tomcat manager app userid and password in your maven settings.xml, and then deploy using the tomcat:deploy goal – this does work, but I’m pretty sure this is not the way you’re supposed to do things:

<build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>tomcat-maven-plugin</artifactId>
      <configuration>
      <url>http://localhost:8080/manager/html</url>
      <server>tomcat</server>
      <path>/TestWebApp</path>
      </configuration>
    </plugin>
  </plugins>
</build>

Add to settings.xml, in the servers section:

<server>
  <id>tomcat</id>
  <username>manager</username>
  <password>yourpassword</password>
</server>

The way I think it’s supposed to work with the M2Eclipse plugin and STS, is you start with a web app project created via the M2Eclipse plugins archetype support, which sets up the project config exactly to work with WTP and deploy seamlessly to tc or other WTP supported servers:

File … New… Other… Maven… Maven Project… New

Set project location then Next. From the archetype list, select ‘maven-archetype-webapp’ ‘. Fill in the maven details, then Finish. That’s it.

When you select Run As… Run on Server, it will build automatically using your pom.xml and deploy to the server. Awesome. It’s pretty easy when you know how 🙂

One catch I noticed – the maven-archetype-webapp creates a web.xml which is for Servlet 2.3:

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

This caused me a couple of hours trying to work out why my JSTL tags and EL were not working when deploying to Tomcat 7. Changing the web.xml to 2.5 fixed my jstl issues. Couple of hours of trial and error and plenty of Googling, ready to roll.

2.5 web.xml:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">

Maven dependencies for Spring Framework libraries

Updated 10/8/14: In reality you only need a couple of the core jars because all the others will be pull in as dependencies. For example, for a 3.2.11 web app using Spring MVC, these two are sufficient:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>3.2.11.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>3.2.11.RELEASE</version>
</dependency>

Starting a new Spring-based project from scratch, what Spring libraries do you need in your maven pom file? This post has a good list with an explanation of each  – here’s the list from the article (for Spring 3.0):

<!-- Shared version number properties -->
<properties>
<org.springframework.version>3.0.0.RELEASE</org.springframework.version>
</properties>
<!--
Core utilities used by other modules.
Define this if you use Spring Utility APIs (org.springframework.core.*/org.springframework.util.*)
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.core</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<!--
Expression Language (depends on core)
Define this if you use Spring Expression APIs (org.springframework.expression.*)
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.expression</artifactId>
<version>${org.springframework.version}</version>
</dependency>


<!--
Bean Factory and JavaBeans utilities (depends on core)
Define this if you use Spring Bean APIs (org.springframework.beans.*)
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.beans</artifactId>
<version>${org.springframework.version}</version>
</dependency>


<!--
Aspect Oriented Programming (AOP) Framework (depends on core, beans)
Define this if you use Spring AOP APIs (org.springframework.aop.*)
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.aop</artifactId>
<version>${org.springframework.version}</version>
</dependency>


<!--
Application Context (depends on core, expression, aop, beans)
This is the central artifact for Spring's Dependency Injection Container and is generally always defined
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.context</artifactId>
<version>${org.springframework.version}</version>
</dependency>


<!--
Various Application Context utilities, including EhCache, JavaMail, Quartz, and Freemarker integration
Define this if you need any of these integrations
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.context.support</artifactId>
<version>${org.springframework.version}</version>
</dependency>


<!--
Transaction Management Abstraction (depends on core, beans, aop, context)
Define this if you use Spring Transactions or DAO Exception Hierarchy
(org.springframework.transaction.*/org.springframework.dao.*)
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.transaction</artifactId>
<version>${org.springframework.version}</version>
</dependency>


<!--
JDBC Data Access Library (depends on core, beans, context, transaction)
Define this if you use Spring's JdbcTemplate API (org.springframework.jdbc.*)
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.jdbc</artifactId>
<version>${org.springframework.version}</version>
</dependency>


<!--
Object-to-Relation-Mapping (ORM) integration with Hibernate, JPA, and iBatis.
(depends on core, beans, context, transaction)
Define this if you need ORM (org.springframework.orm.*)
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.orm</artifactId>
<version>${org.springframework.version}</version>
</dependency>


<!--
Object-to-XML Mapping (OXM) abstraction and integration with JAXB, JiBX, Castor, XStream, and XML Beans.
(depends on core, beans, context)
Define this if you need OXM (org.springframework.oxm.*)
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.oxm</artifactId>
<version>${org.springframework.version}</version>
</dependency>


<!--
Web app development utilities common across Servlet/Portlet environments (depends on core, beans, context)
Define this if you use Spring MVC, or wish to use Struts, JSF, or another web framework with Spring (org.springframework.web.*)
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.web</artifactId>
<version>${org.springframework.version}</version>
</dependency>


<!--
Spring MVC for Servlet Environments (depends on core, beans, context, web)
Define this if you use Spring MVC with a Servlet Container such as Apache Tomcat (org.springframework.web.servlet.*)
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.web.servlet</artifactId>
<version>${org.springframework.version}</version>
</dependency>


<!--
Spring MVC for Portlet Environments (depends on core, beans, context, web)
Define this if you use Spring MVC with a Portlet Container (org.springframework.web.portlet.*)
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.web.portlet</artifactId>
<version>${org.springframework.version}</version>
</dependency>


<!--
Support for testing Spring applications with tools such as JUnit and TestNG
This artifact is generally always defined with a 'test' scope for the integration testing framework and unit testing stubs
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>org.springframework.test</artifactId>
<version>${org.springframework.version}</version>
<scope>test</scope>
</dependency>

For a Spring 3.1 MVC web app, here’s a similar list (also including JSTL jars) – notice the artifact id names changed between Sprintg 3.0 to 3.1:

<dependencies>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
    <version>1.2</version>
</dependency>
<dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>3.1.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>3.1.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>3.1.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-tx</artifactId>
    <version>3.1.2.RELEASE</version>
    </dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-orm</artifactId>
    <version>3.1.2.RELEASE</version>
    </dependency>
<pre></dependencies>