Maven Java Scala project setup

It’s very easy in Maven to add Scala support all we have to do is add the maven-scala-plugin inside the POM:

 		<plugin>
  			<groupId>org.scala-tools</groupId>
  			<artifactId>maven-scala-plugin</artifactId>
  			<version>2.15.2</version>
  			<executions>
  				<execution>
  					<goals>
  						<goal>compile</goal>
  						<goal>testCompile</goal>
  					</goals>
  				</execution>
  			</executions>
  		</plugin>

and of course the single Scala dependency jar:

 	<dependency>
  		<groupId>org.scala-lang</groupId>
  		<artifactId>scala-library</artifactId>
  		<version>2.9.1</version>
  	</dependency>

I have included the code in this Github repository.

Maven, Spring MVC, Eclipse example

Here’s a quick tutorial on how to make Maven, Spring MVC, log4j co-exist happily.

First off we need to create a Maven Project in Eclipse. Our POM is straight forward and looks like this:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.dimitrisli.springMVC</groupId>
  <artifactId>mavenSpringMVC</artifactId>
  <version>1.0</version>
  <packaging>war</packaging>
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>3.1.0.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
    	<groupId>log4j</groupId>
    	<artifactId>log4j</artifactId>
    	<version>1.2.16</version>
    </dependency>
  </dependencies>
  	<build>
		<finalName>MavenSpringMVC</finalName>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
  	<properties>
  		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  	</properties>
</project>

Note how the spring-webmvc dependency is enough to bring all the other main Spring dependencies along due to the dependency hierarchy that Maven is taking care of gracefully and silently behind the scenes.

Since we are building a webapp we would need the webapp/WEB-INF structure which we host in /src/main/.

The web.xml would look like this:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.dimitrisli.springMVC</groupId>
  <artifactId>mavenSpringMVC</artifactId>
  <version>1.0</version>
  <packaging>war</packaging>
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>3.1.0.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
    	<groupId>log4j</groupId>
    	<artifactId>log4j</artifactId>
    	<version>1.2.16</version>
    </dependency>
  </dependencies>
  	<build>
		<finalName>MavenSpringMVC</finalName>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
  	<properties>
  		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  	</properties>
</project>

A few things to notice:

  • We define as the sole servlet of our application Spring’s DispatcherServlet that delegates requests to controllers accordingly.
  • We define Spring’s ContextLoaderListener  as a listener in the web.xml to initialize Spring on webapp startup.
  • The defined context-param needs to have to have as name: <servletNameWeGaveToTheServletDispatcher>-servlet.xml otherwise it will throw an error during runtime load-up.

The view of the response is built up internally using Spring’s InternalResourceViewResolver that is dynamically add a prefix and suffix:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.1.xsd">

	<context:component-scan base-package="com.dimitrisli.springmvc" />

	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix">
			<value>/WEB-INF/jspview/</value>
		</property>
		<property name="suffix">
			<value>.jsp</value>
		</property>
	</bean>

</beans>

Finally the Controller looks like this:

package com.dimitrisli.springmvc;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@RequestMapping("/something.do")
@Controller
public class MyController {

	private static final Logger logger = Logger.getLogger(MyController.class);
	@RequestMapping(method = RequestMethod.GET)
	public String method(ModelMap modelMap){
		modelMap.addAttribute("msg","Hello world");
		return "test";
	}
}

The Spring annotations @Controller and @RequestMapping are defining the fact that the POJO is a Controller and where the request should be forwarded to respectively.

After we mvn package the war file should be ready for deployment waiting for us in Maven’s target dir. Making use of Eclipse’s WTP we can deploy the application inside the familiar place of Eclipse. To do so all we need is the Servers view where we need to create a new Tomcat server pointing to our Maven war file.

After starting-up the application pointing a browser session to the http://localhost:8080/mavenSpringMVC/something.do should go through the controller and give us back the hello world output.

The source code can be found in this Github repository.

JUnit 4 Showcase – assertThat and Hamcrest Matchers

Surely assertEquals() can get you far but you will be amazed with the versatility of assertThat() combined with the expressive and human friendly Matchers of the Hamcrest library.

The needed static imports in your JUnit 4 test case:

import static org.junit.Assert.*;
import static org.junit.matchers.JUnitMatchers.*;
import static org.hamcrest.CoreMatchers.*;

You could use the is() and not() matchers like so:

	@Test
	public void assertThat1(){
		double d = 1.3;
		assertThat(d, is(1.3));
		assertThat(d, is(not(1.4)));
	}

or equalTo():

	@Test
	public void assertThat2(){
		String str="test";
		assertThat(str, equalTo("test"));
		assertThat(str, not(equalTo("anotherTest")));
	}

or anyOf():

	@SuppressWarnings("unchecked")
	@Test
	public void assertThat3(){
		String str="test";
		assertThat(str, anyOf(is("test"), is("this"), is("that")));
		assertThat(str, not(anyOf(is("tasty"), is("this"), is("that"))));
	}

or lessThan() and hasItem() for Collections:

	@SuppressWarnings("serial")
	@Test
	public void assertThatCollections1(){
		List<String> list = new ArrayList<String>(){{add("one");add("two");add("three");}};
		assertThat(list, hasItem("two"));
		assertThat(list, not(hasItem("ttwo")));
	}
	
	@SuppressWarnings("serial")
	@Test
	public void assertThatCollections2(){
		List<Integer> list = new ArrayList<Integer>(){{add(1);add(2);add(3);}};
		assertThat(list, not(hasItem(lessThan(0))));
	}

or hasKey() and hasValue() particularly for Maps:

	@Test
	public void assertThatMaps1(){
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("one", 1);
		map.put("two", 2);
		map.put("three", 3);
		assertThat(map, Matchers.<String,Integer>hasKey("one"));
		assertThat(map, Matchers.<String,Integer>hasValue(2));
	}

A thing to note in the above example is the way we need to explicitly define the types on the key/value Map pair before summoning hasKey() or hasValue(), a bit weird why type inference didn’t help us there.

Finally we could even query properties of Java Beans:

@Test
	public void assertThatProperty1(){
		
		class Bean<T> {
			private T t;
			public void setT(T t){this.t = t;}
			public T getT(){return this.t;}
		}
		
		Bean<String> myBean = new Bean<String>();
		myBean.setT("hi");
		assertThat(myBean, hasProperty("t",is("hi")));
		assertThat(myBean, hasProperty("t",startsWith("h")));
	}

The code can be found in this Gitbub repository.