Spring Roo and Maven issues converting an existing project

It seems Spring Roo has some issues taking an existing Maven project and converting it to a Roo project, even if the imported project has nothing more than skeleton src folder structure and a vanilla pom.xml file.

Trying to update the project’s config via the Maven plugin in also gives odd errors:

Problems encountered while setting the problem description

Trying to use Roo to get started with the existing project to add your persistence setup gives errors about missing config in your pom.xml:

roo> persistence setup --database MYSQL --provider HIBERNATE 
additionalBuildcommands element of the maven-eclipse-plugin required

I think the main issue is if you take an existing source and then convert it to an Eclipse project with ‘mvn eclipse:eclipse’ – this seems to the be starting point for the issues, as you end up with Eclipse .project and .classpath files configured differently from what Roo + STS is expecting.

I created an empty new Roo project to look at what changes you’d need to do by hand to get this fixed up, and it looks like you need to copy across the following to your existing project:

.project:

	<buildSpec>
		<buildCommand>
			<name>org.eclipse.ajdt.core.ajbuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.springframework.ide.eclipse.core.springbuilder</name>
			<arguments>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.m2e.core.maven2Builder</name>
			<arguments>
			</arguments>
		</buildCommand>
	</buildSpec>
	<natures>
		<nature>org.eclipse.m2e.core.maven2Nature</nature>
		<nature>org.eclipse.jdt.core.javanature</nature>
		<nature>org.eclipse.ajdt.ui.ajnature</nature>
		<nature>com.springsource.sts.roo.core.nature</nature>
		<nature>org.springframework.ide.eclipse.core.springnature</nature>
	</natures>

Maven pom.xml file changes:

    <properties>
        <roo.version>1.1.5.RELEASE</roo.version>
        <spring.version>3.0.5.RELEASE</spring.version>
        <aspectj.version>1.6.11</aspectj.version>
        <slf4j.version>1.6.1</slf4j.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

Repo and plugin in repo settings:

    <repositories>
        <repository>
            <id>spring-maven-release</id>
            <name>Spring Maven Release Repository</name>
            <url>http://maven.springframework.org/release</url>
        </repository>
        <repository>
            <id>spring-maven-milestone</id>
            <name>Spring Maven Milestone Repository</name>
            <url>http://maven.springframework.org/milestone</url>
        </repository>
        <repository>
            <id>spring-roo-repository</id>
            <name>Spring Roo Repository</name>
            <url>http://spring-roo-repository.springsource.org/release</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-maven-release</id>
            <name>Spring Maven Release Repository</name>
            <url>http://maven.springframework.org/release</url>
        </pluginRepository>
        <pluginRepository>
            <id>spring-maven-milestone</id>
            <name>Spring Maven Milestone Repository</name>
            <url>http://maven.springframework.org/milestone</url>
        </pluginRepository>
        <pluginRepository>
            <id>spring-roo-repository</id>
            <name>Spring Roo Repository</name>
            <url>http://spring-roo-repository.springsource.org/release</url>
        </pluginRepository>
    </pluginRepositories>

Dependencies:

    <dependencies>
        <!-- General dependencies for standard applications -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>net.sf.flexjson</groupId>
            <artifactId>flexjson</artifactId>
            <version>2.1</version>
        </dependency>
        <!-- ROO dependencies -->
        <dependency>
            <groupId>org.springframework.roo</groupId>
            <artifactId>org.springframework.roo.annotations</artifactId>
            <version>${roo.version}</version>
            <scope>provided</scope>
        </dependency>
        <!-- Spring dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
    </dependencies>

Build section:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1.1</version>
                <!-- <configuration> <webXml>target/web.xml</webXml> </configuration> -->
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.2</version> <!-- NB: do use 1.3 or 1.3.x due to MASPECTJ-90 - wait for 1.4 -->
                <dependencies>
                    <!-- NB: You must use Maven 2.0.9 or above or these are ignored (see MNG-2972) -->
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjrt</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                </dependencies>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <outxml>true</outxml>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.5</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.8</version>
                <configuration>
                    <printSummary>false</printSummary>
                    <redirectTestOutputToFile>true</redirectTestOutputToFile>
                    <excludes>
                        <exclude>**/*_Roo_*</exclude>
                    </excludes>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.2.1</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.6</version>
            </plugin>
            <!-- IDE -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-eclipse-plugin</artifactId>
                <version>2.7</version>  <!-- Note 2.8 does not work with AspectJ aspect path -->
                <configuration>
                    <downloadSources>true</downloadSources>
                    <downloadJavadocs>false</downloadJavadocs>
                    <wtpversion>2.0</wtpversion>
                    <additionalBuildcommands>
                        <buildCommand>
                            <name>org.eclipse.ajdt.core.ajbuilder</name>
                            <arguments>
                                <aspectPath>org.springframework.aspects</aspectPath>
                            </arguments>
                        </buildCommand>
                        <buildCommand>
                            <name>org.springframework.ide.eclipse.core.springbuilder</name>
                        </buildCommand>
                    </additionalBuildcommands>
                    <additionalProjectnatures>
                        <projectnature>org.eclipse.ajdt.ui.ajnature</projectnature>
                        <projectnature>com.springsource.sts.roo.core.nature</projectnature>
                        <projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
                    </additionalProjectnatures>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-idea-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <downloadSources>true</downloadSources>
                    <dependenciesAsLibraries>true</dependenciesAsLibraries>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>tomcat-maven-plugin</artifactId>
                <version>1.1</version>
            </plugin>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>7.4.2.v20110526</version>
                <configuration>
                    <webAppConfig>
                        <contextPath>/${project.name}</contextPath>
                    </webAppConfig>
                </configuration>
            </plugin>
        </plugins>
    </build>

One last step: copy across a blank applicationContext.xml file from an empty Roo project – if you don’t, when you issue Roo commands it looks for the file expecting it to already exist.

There’s notes here on how to convert an existing project to Roo, though it’s more like some suggestions than actual steps.

Spring Roo, Maven and Oracle JDBC drivers

Oracle JDBC drivers are not freely available in any public Maven repos. Per the Spring Roo docs, if you have an Oracle product installed (presumably you do if you’re trying to connect to it), you can install the provided JDBC driver into your local Maven repo for your code to build successfully.

Using Roo 1.1.5, setting up my persistence with:

persistence setup --provider HIBERNATE --database ORACLE --databaseName XE

Resulted in this dependency added to my pom.xml:

	<dependency>
		<groupId>com.oracle</groupId>
		<artifactId>ojdbc14</artifactId>
		<version>10.2.0.2</version>
		<classifier />
	</dependency>

I’m using Oracle Express 11.2.2.0 on my machine, and my JDBC driver installed with the product is here:

C:oraclexeapporacleproduct11.2.0serverjdbclibojdbc6.jar

So using the Maven install command, I can copy this file into my local repo like this:

mvn install:install-file 
    -Dfile=ojdbc6.jar 
    -DgroupId=com.oracle 
    -DartifactId=ojdbc6 
    -Dversion=11.2.0.2.0 
    -Dpackaging=jar 
    -DgeneratePom=true

And then update my jar dependency in my pom.xml to match the version of the jar that I have:

	<dependency>
		<groupId>com.oracle</groupId>
		<artifactId>ojdbc14</artifactId>
		<version>11.2.0.2.0</version>
		<classifier />
	</dependency>

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>