Monday, September 19, 2011

maven-compiler-plugin configuration for annotations support

Several times I encountered the same problem when building with Maven:
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Compiling 1 source file to /home/stefano/works/stefanocazzola.it/sc/target/classes
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Compilation failure
/home/stefano/works/test/src/main/java/it/stefano/Test.java:[17,2] annotations are not supported in -source 1.3
(use -source 5 or higher to enable annotations)
 @Override
As I said I encountered it many times: I know it's a silly error, but every time I got to search the forums to find the soution (my short-time memory isn't so good, I admit....) so I decided to write a post about that.
The solution os very very simple. Just configure the maven-compiler-plugin like that:
<plugin>
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-compiler-plugin</artifactId>
 <configuration>
  <source>1.5</source>
  <target>1.5</target>
 </configuration>
</plugin>

Friday, September 9, 2011

Cloud Foundry and the missing TLD

I just started with Cloud Foundry and... well... what to say....
WHOOOOAAAAA!
It's absolutely fantastic! I hope the BETA will end soon to switch to a "general availability" of sort.
It took just five (5) minutes to start a complete Spring web project.
The only problem I had was with the c.tld file. Initially I had the problem that Tomcat could not locate the META-INF/c.tld file.
I didnt find any precise answer on the web, but in The Big Moose Saloon gave me the right hint
The problem is that in my POM file I added the dependencies
<dependency>
 <groupId>javax.servlet</groupId>
 <artifactId>servlet-api</artifactId>
 <version>2.5</version>
</dependency>
<dependency>
 <groupId>javax.servlet.jsp</groupId>
 <artifactId>jsp-api</artifactId>
 <version>2.2</version>
</dependency>
Doing so I added these two jars to the classpath but this conflict with Tomcat.
I added them to avoid compilation issues for tag handler in Eclipse.
Obviously, you can simply remove the dependencies and disable JSP validation in Eclipse. But that's not a solution, that's a workaround. And a ugly one, in my opinion.
There is a solution and is very simple. Just tell Maven to trust these jars exist, i.e. change the scope of the dependencies
<dependency>
 <groupId>javax.servlet</groupId>
 <artifactId>servlet-api</artifactId>
 <version>2.5</version>
 <scope>provided</scope>
</dependency>
<dependency>
 <groupId>javax.servlet.jsp</groupId>
 <artifactId>jsp-api</artifactId>
 <version>2.2</version>
 <scope>provided</scope>
</dependency>

Done!

Tuesday, September 6, 2011

Test driven development with Maven and Scala

As projects grow on size and complexity, you can feel a little lost on every issue or bug to fix.
It's very common to fix a bug today and, after few months when project needs to meet one more requirement (due to the fantasy of the customer or of the developer himself...), encouter the same problem once again. It's called "regression".
To avoid this unpleasant situation, you can rely on some tools to perform automatic tests: Java provides JUnit (I use JUnit4) and Scala provides Scalatest.
Obviously you can run the tests invoking the correct tool by command-line, but with Maven you can integrate all the phases of the compilation-testing task in order to have your project compiled and tested (and eventually also deployed to a repo) with one single command.
To do so, you'll have to change a little bit your POM file.
You'll also need to write your tests in the correct manner, but there are official example from the Scalatest team linked at the end of the article.

POM modifications
First add some repository...
<repositories>
 <repository>
  <id>scala-tools.org</id>
  <name>Scala-Tools Maven2 Repository</name>
  <url>http://scala-tools.org/repo-releases</url>
 </repository>
</repositories>

<pluginRepositories>
 <pluginRepository>
  <id>scala-tools.org</id>
  <name>Scala-Tools Maven2 Repository</name>
  <url>http://scala-tools.org/repo-releases</url>
 </pluginRepository>
</pluginRepositories>
Now, the dependencies. You must add the dependency
<dependency>
 <groupId>org.scalatest</groupId>
 <artifactId>scalatest_${scala.version}</artifactId>
 <version>1.6.1</version>
 <scope>test</scope>
</dependency>
I assume you set a property named scala.version valued with the Scala version you are using. Please note the version of this artifact vary with Scala version. I'm using the 2.9.0-1 version of Scala: if you are using another version, check the repo http://scala-tools.org/repo-releases
Optionally, you can remove the dependency
org.scala-tools.testing:specs_${scala.version}
Then jump to the build section.
<build>
 <sourceDirectory>src/main/scala</sourceDirectory>
 <testSourceDirectory>src/test/scala</testSourceDirectory>
</build>
Last thing to do: add the Surfire plugin. Add in the root:
<reporting>
 <plugins>
  <plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-surefire-plugin</artifactId>
   <configuration>
    <scalaVersion>${scala.version}</scalaVersion>
    <includes>
     <include>**/*Suite.class</include>
     <include>**/*Spec.class</include>
    </includes>
   </configuration>
  </plugin>
 </plugins>
</reporting>
Wow! Now you are ready to start writing your tests!

How to write tests
Writing tests using JUnit3
Writing tests using JUnit4
Writing tests using Scalatest FunSuite features
Writing tests using Scalatest Spec features

Executing the tests
Maven will execute these tests whenever you compile, deploy or simply test your projects.
Be carefull to clean your project always before compiling or testing.
For example, the command line to launch tests only (obviously, the project will be compiled too) is
mvn clean test
from the folder containing the POM.xml of your project

Hope you'll find usefull,
S

Friday, September 2, 2011

Nexus - Error 400 redeploying artifact

This is really one of the silliest error I've ever found.
This is stupid because of its solution that is so simple that generally a programmer doesn't think. In the commpon developer's mind (therefore in mine too) every error must be a serious system problem (if you are using Windows could even be a virus!), or some other programmer must have done something wrong, or maybe it's just inexplicable and depends on unknown factors.
In fact, as I said the solution is the simplest one you can think: just configuration of the repo.
You have to
  • open your Nexus server as admin
  • open configuration window of your repo
  • find the parameter "Deployment policy" and set it to "Allow redeploy"
That's it.