Saturday, February 11, 2012

Good tutorial on maven, spring

Well, our hopes for a quick attack on Spring 3.0 have been somewhat dashed by an apparent bug in the template generation for an MVC app - although we did luckily manage to get one up and running, which I've carefully preserved.
(note - this was fixed by just doing a "clean" on the project).

The tutorial did give a pom.xml file at the end - and I'm wondering if it's possible to use a war file generate from that successfully create multiple mvc apps.

Maven is something I've never really had a chance to get into, so I took this as an opportunity to learn a *little* bit about it.

This is a tutorial I landed upon:

http://pookey.co.uk/wordpress/archives/50-getting-started-with-maven-and-spring

I actually got the whole thing to work, start to finish.

The first thing your supposed to do is this command:

mvn archetype:generate --batch-mode \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DgroupId=uk.co.pookey.spring \
-DartifactId=spring-hello \
-Dversion=1.0-SNAPSHOT

When you run it from the command line, get rid of the backslashes and put it all on the same line. It turns out when you run it, because you're specifying the archetype, it's based on some kind of super-pom that specifies a lot of files.

It also creates a source and build file structure, and a program called App.java, which looks like this:


package uk.co.pookey.spring;

public class App
{
public static void main( String[] args )
{
System.out.println( "Hello World!" );
}
}


My theory is that the "hello world" app is part of the archetype template. So, you just get this nice vanilla directory structure with a hello world app built in.

The directory created gets its name from DartifactId=spring-hello

it also creates a file called pom.xml, as well as src and target directories.

Here's the path of the App.java: src/main/java/uk/co/pookey/spring/App.java

In order to get the App.java to work, you need to add this to your pom.xml:


<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>

<configuration>
<mainClass>uk.co.pookey.spring.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>

This makes this command possible:

mvn exec:java

which will execute the java class.

But first, you need to compile it:


$ mvn compile

Then run:

$ mvn exec:java


It you'll see the "Hello" message.


This is fine for creating a standard product structure, but we're trying to learn a little bit of spring too.

Well, this example does that for us. First it specifies in pom.xml a dependency on the spring container:


<dependencies>
...
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.5</version>
</dependency>
</dependencies>


I turns out there's a huge, searchable archive of maven dependencies here:

http://www.mvnrepository.com/

But, this is the one where we are getting our version from:

http://www.mvnrepository.com/artifact/org.springframework/spring


This is the strength of maven - it just knows what the version numbers of the jar files you need are, automatically - since you specified them in the first place. It also pulls down any spring dependencies.

Next we create a new pojo in src/main/java/uk/co/pookey/SayHello.java:

package uk.co.pookey;

public class SayHello
{

private String name;

public void setName(String name)
{
this.name = name;
}

public String getName()
{
return name;
}

public void greet()
{
System.out.println("Hello " + getName());
}

}

This can accept a dependency injection of name, which is printed out later on.

Next we create the famed bean configuration file:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="hello" class="uk.co.pookey.SayHello">
<property name="name" value="Pookey" />
</bean>
</beans>


This is going to be placed in src/main/resources/application-context.xml. You need to create the resources directory.

Finally, we see an example of dependency injection:



package uk.co.pookey.spring;

import uk.co.pookey.SayHello;

import org.springframework.core.io.ClassPathResource;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;

public class App
{
public static void main( String[] args )
{
BeanFactory factory = new XmlBeanFactory(
new ClassPathResource("application-context.xml"));

SayHello hello = (SayHello) factory.getBean("hello");
hello.greet();
}
}



The app class pulls the hello bean from the XMLBeanFactory and calls "greet" on it. The factory has already taken care of setting the name to "Pookey" based on the configuration.

Just type "mvn clean compile exec:java" from the directory level of the pom.xml, and you see the "hello, Pookey" result.

To summarize, we've figured out how to create a simple hello world app using maven and spring, even bringing in some dependency injection. You can create a project from out of nowhere using maven from the command line. It uses an archetype that it finds in the cloud and downloads a bunch of jars and creates your directory structure. We added a couple of entries to allow us to execute the program, as well as introduce a dependency on Spring 2.5. We also added the bean configuration file to specify the dependency.

The next question is, how to we import the into an IDE like STS? We'll tackle that in a subsequent post.

No comments:

Post a Comment