NetBeans and Maven – A quick start guide

A few months ago, I was reading the book “Wicket in Action”. I was new to Wicket and Maven then. I followed the instructions given in the book to create a maven project. The book went one step further and explained how to create eclipse and idea projects from the pom, but nothing was mentioned about NetBeans. I felt sad that there is no maven plugin out there to create projects that NetBeans can understand.

But later when I realized that there is no such need to create Netbeans projects from Maven pom, I was thrilled. Maven, is a first class citizen in NetBeans. Any Maven project “is a” NetBeans project.

Over the months, as I continued to learn and use Maven, NetBeans made the the learning curve easy. So I thought of putting up this post to benefit new Maven users.

Setup

If you are using Maven for the first time, you may want to download and install it on your machine.

Though NetBeans comes with an embedded Maven instance (version 3.0-SNAPSHOT in NetBeans 6.9 at the time of writing this post), it’s still a good idea to have your own Maven instance, so that you can use it outside the IDE as well.

Installing Maven is quite easy. Download the latest Maven distribution (version 2.2.1 at the time of writing) and follow the installation instructions for your operating system.

Now, let’s quickly dive into action by firing up the IDE and create a new Maven project.

Creating a new Maven project

Open NetBeans IDE and click “File -> New Project” and then choose “Maven” as the category and “Maven Project” as the project type.

NetBeans Maven Project - Step 1

In the next step, select “Maven Quickstart Archetype” as the maven archetype.

NetBeans Maven Project - Step 2

Finally, enter other details of your project and finish the wizard.

NetBeans Maven Project - Step 3

That should leave you with a new Maven project with a structure similar to this:

NetBeans Maven Project - Step 4

One thing I like about NetBeans is that it always gives you some workable defaults whether it’s a web project or a simple java project.

No difference here. Just right click the java source file the IDE generated for you to watch your Maven project in action.

And this is the default “pom.xml” the IDE generated for you:


<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/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<groupId>examples.maven</groupId>
<artifactId>hellomaven</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>hellomaven</name>
<url>http://maven.apache.org</url>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>

If you know Maven already, you know what’s happening. Even if you are new to Maven, there is nothing to worry. Every Maven project needs a few mandatory definitions and that’s what you are seeing now.


Improving the default project

There are a couple of things we can improve in this project. First let us cleanup the “pom.xml”. As you can see, a depedency to junit 3.8.1 has been declared in the pom. That’s pretty archaic and let us change the junit version to the latest available version.

You need not scratch your head to figure out what’s the latest version of junit. The IDE is right there to help you. Keep the cursor near the version element and invoke the code completion by pressing the appropriate key. (In my case it’s CTRL + SPACE). Now, the IDE should give you a list of available junit versions in the default Maven remote repository.

Choose the latest available junit version and save the details.

Let us rewrite the test case making use of the recent junit enhancements. Delete the existing unit test class and create a new one by right clicking the java source file and then selecting “Tools -> Create Junit Tests”. You should see the IDE displaying a dialog saying that it cannot create junit 4.x tests.

There is nothing wrong with the IDE here. Because JUnit 4.x makes use of annotations and hence need a Java source level of 1.5 or above. By default, Maven doesn’t assume your source files to be 1.5 compatible, so you need to tell Maven exactly what Java source version you would be using in your projects. Doing that is quite simple. Open the project’s “pom.xml” in the editor and define the Java source level 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/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<groupId>examples.maven</groupId>
<artifactId>hellomaven</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>hellomaven</name>
<url>http://maven.apache.org</url>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>

</project>

You should be able to create JUnit 4.x tests from the IDE now.

Applying “Test Driven Development” to our project, let us create an unit test for an non-existent method in the java source.

And now write the actual method in the java source so that the IDE doesn’t complain about the errors in our unit test.


protected String sayHello(String input)
{
String output = "Hello " + input;
return output;
}

Go back to the unit test and run it.(I usually type CTRL + F6 to run the unit tests). Congrats! Your Maven project is seriously ready for prime time.

Do not take me wrong but it’s really a good practice to write unit tests for everything and that’s why I bothered you with this stuff.

Don’t use System.out.println!

Though we are already familiar with dependencies, we only used JUnit which is a test dependency. And this is a good time to dive into the dependency hell by introducing our next dependency to this little project, “slf4j” or “Simple Logging Facade for Java”.

It’s hard to imagine any project without “logging” and our example project is no exception. (Heck, what’s there to log in this project???)

And with “slf4j” gaining wide spread adoption, let us make use of it. “slf4j” doesn’t tie our application to any logging framework (other than itself :-) ). It’s something like “jpa”. It gives you the freedom to choose your own logging provider. (My current favourite is logback)

Enough talking, let us starting using logging in our project.

To justify the use of logging, let us create some opportunity by updating our “main” method.


public static void main(String[] args)
{
if(args != null && args.length > 0)
{
System.out.println(new App().sayHello(args[0]));
}else{
System.out.println("You have to pass atleast one argument to get a warm response from me!");
}
}

Time to fix those “System.out.println” calls by using slf4j. Create a slf4j Logger instance.

That’s obvious. By no way the IDE can figure out what is happening here apart from resolving the “Logger” to java.util.logging which is not our objective.

Now click the edison’s bulb in the gutter to see what magic the IDE has under it’s hat.

Select the option “Search Dependency at Maven Repositories…”. The IDE should popup a window with the possible matching artifacts.

Scroll to the bottom and locate “slf4j-api” and click “Add”. This will add the latest version of slf4j-api as a dependency. If you want to be more specific on the version, you can expand the slf4j-api node and choose the appropriate version.

Go back to your “pom.xml” and see a new dependency for “slf4j-api” has been added. If you don’t want all this hassle, you can straight away add the following snippet in your pom.xml to add a dependency for slf4j-api.


<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
<type>jar</type>
</dependency>

Fix your imports in the source file and you are set to use slf4j.

Now change the reference to “System.out.println” with appropriate logging calls.


public static void main(String[] args)
{
if(args != null && args.length > 0)
{
logger.info(new App().sayHello(args[0]));
}else{
logger.warn("You have to pass atleast one argument to get a warm response from me!");
}
}

Run your main class to ensure that everything is fine.

That’s not we expected. Nothing is logged! There is nothing wrong with this phenomenon as we haven’t defined any logging provider yet. Remember, slf4j is just a specification.

Okay, it’s time to add a logging provider and with all the bias let us choose “logback” for this purpose. (Please feel free to use your preferred logging provider.)

Slf4j has a bunch of adapters for popular logging frameworks like “log4j” and “jul” (java.util.logging). (Please don’t raise flame wars by asking whether “jul” is really popular!)

If log4j is your cup of tea or coffee, please go ahead and check the slf4j manuals for further reference. :-)

I’ll use “logback” for this example and let us add the dependencies for that now. Right click the “Libraries” node of your project and click “Add Dependency”.

The IDE should popup a window now where you can search the dependencies you want to add by typing the respective name in the “Query” field.

To use logback in your project, you need to add the dependency “logback-classic”. (This will automatically add the transitive dependency “logback-core”)

Expand the respective node, choose the version you want and click “OK” to add them to the project.

You can see the added dependencies in the “Libraries” node of the project.

Again, if you are not a big fan of wizards, you can drop in the following snippet in the pom.xml straight away.


<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>0.9.24</version>
</dependency>

That’s it. If you run the main class now, the logging calls should be negotiated properly.

To remove a dependency, you can either right click the respective dependency in the “Libraries” node and then click “Remove dependency” or edit your pom.xml and delete the respective reference to the dependency. It’s upto you.

To keep this post live up to it’s title, I’ll not discuss the tons of other Maven related stuffs NetBeans has. I’ll probably cover some of them in a later post.

For the sake of completeness, here is the final pom.xml:


<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/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<groupId>examples.maven</groupId>
<artifactId>hellomaven</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>hellomaven</name>
<url>http://maven.apache.org</url>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
<type>jar</type>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>0.9.24</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>

</project>

And the java source file:


package examples.maven.hellomaven;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Hello world!
*
*/
public class App
{
private static final Logger logger = LoggerFactory.getLogger(App.class);

public static void main(String[] args)
{
if(args != null && args.length > 0)
{
logger.info(new App().sayHello(args[0]));
}else{
logger.warn("You have to pass atleast one argument to get a warm response from me!");
}
}

protected String sayHello(String input)
{
String output = "Hello " + input;
return output;
}
}

The Junit test class:

package examples.maven.hellomaven;

import org.junit.Test;
import static org.junit.Assert.*;

/**
 *
 * @author james
 */
public class AppTest
{
 public AppTest()
 {
 }

 @Test
 public void testSayHello()
 {
 App app = new App();
 String input = "Maven";
 String expected = "Hello " + input;
 String result = app.sayHello(input);
 assertEquals(expected, result);
 }
}

As you have seen above, NetBeans offers great support out-of-the-box for Maven. No plugins required. If you are not a NetBeans user but use Maven, I recommend you to give it a try. You’ll not be disappointed.

Thanks for reading patiently and please leave your comments if you have any.

9 comments to NetBeans and Maven – A quick start guide

  • Nice write up ! One comment – I think, to set the Java source level, using the wizard happens to be more convenient instead of editing the pom.xml directly (at least in this case).

    Go to the “project properties” view, (right-click on project name in projects view –> Properties) then go to “Sources” and you can find a “Source Format” setting at the bottom of the wizard.

  • James

    Thanks Peter for the suggestion. I didn’t know that.

  • James

    Wow, that’s a fantastic tip. Thanks for sharing it. I too use a code template for this purpose but yours looks more sophisticated!

  • James

    That worked like a charm!
    I previously used the following template:


    private static final Logger logger = LoggerFactory.getLogger(${classVar editable="false" currClassName default="getClass()"}.class);

    That didn’t add the import statement, yours’ did. Can’t live without these code templates nowadays!

  • Jiri Pejchal

    I use code template for creating slf4j loggers (with abbreviation logs):


    private static final ${LOG_TYPE type="org.slf4j.Logger" default="Logger" editable=false} logger = ${LOG_FACT type="org.slf4j.LoggerFactory" default="LoggerFactory" editable=false}.getLogger(${classVar editable="false" currClassName default="getClass()"}.class);

    Just type logs TAB and the following will be generated(including imports):

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;

    private static final Logger logger = LoggerFactory.getLogger(Test.class);

  • biyan li

    I cannot get it work after I modified the AppTest file with testSayHello() function. It complains that App class cannot be found.

  • Kirill Lassounski

    Hy there James!
    I really liked your post and I`m starting to use Maven in my projects.
    But when I was mining the web for Builder tools i found out the BuildR from Apache. People are saying that this tool is a lot better. What is your opinion ?

  • killer

    Thanks…Nicely done…

Leave a Reply

  

  

  

*

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>