My 5 favorite NetBeans IDE features (vs. Eclipse)

In my current project, Eclipse Kepler has been selected by the customer as the preferred IDE for all main tasks. Of course, I’m also using NetBeans 8.0 for some activities like, for example, legacy code test coding.

I have already used Eclipse some years ago and, at that time (2009), Eclipse Galileo were quite superior to NetBeans 6.x: faster, rich of code hints and warnings, full of useful plugins. So, I was not really happy when the project moved to NetBeans (because of its Swing support).

Now let me compare them again, Eclipse Kepler 4.3 vs NetBeans 8.0, on same project (a big ant based web project) and on the same PC (Win7 64bit 4G RAM).

Speed

My first big surprise. Five years ago, when I moved from Galileo to NetBeans I really missed Eclipse speed: coding, windowing, compilation, everything were significantly faster in Eclipse.

Now this speed advantage is gone. I don’t have benchmarks to demonstrate my feeling but now my coding is visibly faster with NetBeans 8.0 than with Eclipse Kepler. If you install Findbugs and PMD plugins, Eclipse becomes really slow.

Native testing support

Second surprise. Why, in 2014, an IDE for Java EE developers does not include full testing support ?

I cannot imagine any real EE developers which does not need any kind of test support from the IDE.

In NetBeans there is complete native jUnit and TestNG support (templates, test runs, jump to test option in the editor, both *Test and *IT files support) which I found very useful and efficient.

Eclipse native support is poor but of course it can be extended via plugin. I’m using MoreUnit plugin which is quite nice and add many missing features to Eclipse. See here for a small tutorial.

But even if you install a test support plugin like MoreUnit, still an important Eclipse limitation remains : the possibility to have a dir for test files separated from the main src dir, which is an essential feature to let us handling deployments. If you don’t believe me, have a look at this 2008 bug still open: https://bugs.eclipse.org/bugs/show_bug.cgi?id=224708 and its related bugs.
Simply unbelievable.

Java Hints and FindBugs integration

While coding, it is important to have feedbacks from the IDE about the quality of the code and possible errors. NetBeans Java hints is a very reach set of the code checks which helps me to avoid stupid errors and keep high the quality of my work. In addition, NetBeans includes first class support for FindBugs which, again, helps me during coding sessions.

I’ve found NetBeans code quality checks support better than the one available in Eclipse Kepler + FindBugs plugin. More checks and better control on how, for example, disable a FindBugs warning on a line (because it is ok) using an annotation: just a click with NetBeans and by hand with Eclipse.

Coding support: templating, completion,interfaces…

I like NetBeans coding support: code templates (some letters + tab to get most used keywords and structures (see here for some examples), auto-completion, now also using sub words, I can easily jump from an interface to its implementation, the new indent guide lines.

Similar features are available in Eclipse using, for example, the Code Recommenders plugin but I’ve found it quite slow on my machine so I had to disinstall it.

User Interface

NetBeans user interfaces has improved a lot while keeping its strong point: it is easy to use. Windows and menus are easy to find and the full screen mode is very useful on small screens. I really like the color coding setup (Norway Today) which makes code reading a pleasure and the dark skins for working late in the evening.

On the contrary, Eclipse interfaces remains somehow confusing and, my personal opinio, perspectives and workspaces are simply a waste of time.

Tutorial: unit testing in Eclipse with moreUnit plugin

Eclipse Kepler, even in the Java EE Developers edition, does not include a good enough support for automatic tests development. Both NetBeans and IntelliJ have superior native support for testing. For example, if you rename one class, Eclipse does not rename its test class.

To overcome such limitations, we need to install a plugin.

In this tutorial, I will describe moreUnit (http://moreunit.sourceforge.net/), a plugin which extends Eclipse testing support. I will not cover moreUnit installation because it is quite standard.

Let’s create a standard ant based Eclipse project. In the example the project name is “EclipseTest” and the main package is “it.gualtierotesta”.
20140522_01
In the package, I’ve created a new Java class named MyClass with the following content:

package it.gualtierotesta;

public class MyClass {

    private String msg;

    public String message() {
        return generateMsg();
     }

    private String generateMsg() {
        return "Hello " + msg;
    }

    public String getMsg() {
        return msg;
     }

    public void setMsg(String msg) {
       this.msg = msg;
    }

}

Very simple. We want now to create a unit test to check the message() method. While in the Java Editor window, you should press Ctrl+R (or, from the contextual menu, MoreUnit –> Jump To Test) to trigger test class creation.

20140522_02
where we can select our preferred unit library. In this tutorial we will use JUnit 4.

Press “Finish” to confirm. Note: Eclipse will eventually ask you to add JUnit library to the project build path.

In the created test class (MyClassTest.java file), add the following contents:

package it.gualtierotesta;

import org.junit.Assert;
import org.junit.Test;

public class MyClassTest {

@Test
 public void showMessage() {
     // given
     MyClass sut = new MyClass();
     sut.setMsg("Gualtiero");
     // when
     String res = sut.message();
     // then
    Assert.assertEquals("", res);
 }

}

Note: sut is system under test.

In the test class window, press Ctrl+R to run the test. Test will fail:
20140522_03This is expected because the Assert.assertEquals check for the wrong result.
Change the Assert line as following:

Assert.assertEquals("Hello Gualtiero", res);

E re-run the test (Ctrl+R). Test will now succeed.
20140522_04
Note: in the test method body I added some comment lines to divide the body instructions in three sections. Given section is where the test texture is prepared, when is the execution of the method under test and the then section marks the results checks instructions (assertions). This is a good habit to make test strategy clearer. It comes from BDD, Behavior Driven Development (http://en.wikipedia.org/wiki/Behavior-driven_development).

 

A nice moreUnit feature is to mark the Java source file icon with a small green rectangle to show that the class has a test class.
20140522_05We have now our test running without failure but still our setup is not correct: test classes should be placed in a different source folder because they should not be packaged and released to the user.

Traditional approach is to have src dir for Java source files and test dir for test classes.

We create now a new folder named “test” under project root:
20140522_06
Then in the Java Build Path section of the project properties we add the new test folder as one of the project source folders:
20140522_07
Finally we configure moreUnit to use the “test” folder as the place to create and look for test classes:
20140522_08
Finally we can move the MyClassTest.java to the test folder (or create it again).

At the end, the project configuration is the following:
20140522_09As shown in this short tutorial, moreUnit plugin simplify a lot test classes handling in Eclipse.

Moreover, moreUnit offers special support for mocking libraries users. The test class creation wizard has additional pages to insert mocking specific instructions in the test class:
20140522_10
In this page, you can select the dependencies you want to mock and moreUnit will add specific mocking instructions. For more info about Mockito, have look here and here.

GDocx 3.0.0 released

GDocx, the fluent interface to the Docx4J library, version 3.0.0 has been released.

What’s new ?

GDocx now uses the latest (3.0.1) Docx4j version.

Other changes includes replacement of Fest Assert with the AssertJ library which is more flexible and powerful.

All files, including source and javadoc can be downloaded from the project home at the https://java.net/projects/gdocx

Review: Jboss as 7 Development

Jboss as 7 Development
Jboss as 7 Development by Francesco Marchioni
My rating: 4 of 5 stars

Good introduction and overview of Java EE 6 development using JBoss as application server.

Some chapters are dedicated to the installation, management, clustering and
security configuration of a JBoss application server.

The rest of the book (the greater part) is dedicated to Java EE6 development
topics: EJB, CDI, JMS, Soap and RESTful web-services.

There is also a chapter on unit and integration testing (with Arquillian).

The book is well written and with good explanations, even if some topics are only mentioned.

Suggested to everybody interested in starting to work with Java EE6 and JBoss AS 7.

View all my reviews

Tutorial: how to create a JUnit test method template in NetBeans

NetBeans has a very nice feature: code templates.

Let me show how I use it to add a new JUnit test method in the test classes.

Go to Tools → Options → Editor → Code Templates and add the following template:

Abbreviation: te (this is only my proposal)

Expanded text:

@${baseType type="org.junit.Test" default="Test" editable="false"}
public void ${cursor}() {
    // given

    // when

    // then

}

2014-03-05_pic01Then go to a test class, type “te” (our template abbreviation) and press the TAB key.

See what’s happen:

2014-03-05_pic022014-03-05_pic03

First, the org.junit.Test include has been added (if not already in). This is thanks to the ${baseType} instruction we added in the template.

Second, the prompt is waiting for you for the method name. See ${cursor} instruction in the template.

Just write the name and we have complete test method template in our class.

2014-03-05_pic04

Of course, the template can be adjusted to your needs and habits.

Benefits:

  • we code faster
  • we have more uniform code style

NetBeans code template syntax is (partially) documented here.

Tutorial: using Lombok to reduce boilerplate code in Java

Lombok (http://projectlombok.org) is a very useful Java annotation library which help us to:

  • reduce boilerplate code
  • code faster
  • avoid stupid errors like forgetting the getter and setter for a new added field.

Lombok can create getter, setters, toString, constructor, equals and hashCode methods automatically. You just need to write the class and add the fields.

Lombok provides several annotations (see http://projectlombok.org/features/index.html for the complete list) but, in my projects, I usually use few of them and, in this tutorial I will show which and why.

To better show Lombok benefits, let’s start with a very simple (Maven based) project. You can find complete project source code here.

We should first define Lombok Maven dependency in the pom.xml file:

 <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.12.4</version>
    <scope>provided</scope>
</dependency>

Important: scope should be provided because we do not want Lombok jar file to be included in our build file.

Let’s now add to a project a very basic class without using any Lombok annotations.


public class WithoutLombokAnnotations {
    private boolean flag;
    private final int number;
    private final String text;
    private List<String> strList;

    public WithoutLombokAnnotations(int number, String text) {
        this.number = number;
        this.text = text;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public List<String> getStrList() {
        if (strList == null) {
            strList = new ArrayList<>(128);
        }
        return Collections.unmodifiableList(strList);
    }

    public void setStrList(List<String> strList) {
        this.strList = strList;
    }

    public int getNumber() {
        return number;
    }

    public String getText() {
        return text;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 11 * hash + this.number;
        hash = 11 * hash + Objects.hashCode(this.text);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final WithoutLombokAnnotations other = (WithoutLombokAnnotations) obj;
        if (this.number != other.number) {
            return false;
        }
        if (!Objects.equals(this.text, other.text)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "WithoutLombokAnnotations{" + "flag=" + flag + ", number=" + number + ",
            text=" + text + '}';
    }
}

Comments on the above code:

  • The class has four fields, two of them are final so we need a constructor.
  • The flag field is a boolean so the getter is named isFlag() and not getFlag()
  • The strList getter method initialize the list if necessary
  • The strList is not included in the toString method
  • Equals and hashCode are calculated on number and text fields only.

A lot of boilerplate code for a very simple class.

Let’s reduce it with the help of Lombok annotations.

GETTER and SETTER

First step: the getters and setters (http://projectlombok.org/features/GetterSetter.html). In our example, all of them are very simple and standard except the strList getter. We can use Lombok’s @Getter and @Setter annotations to remove all standard getters and all setters from our code and have Lombok to generate them during compilation.

Our class code becames:

@lombok.Getter
@lombok.Setter
public class GettersAndSetters {
    private boolean flag;
    private final int number;
    private final String text;
    private List<String> strList;

    public GettersAndSetters(int number, String text) {
        this.number = number;
        this.text = text;
    }

    public List<String> getStrList() {
        if (strList == null) {
            strList = new ArrayList<>(128);
        }
        return Collections.unmodifiableList(strList);
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 11 * hash + this.number;
        hash = 11 * hash + Objects.hashCode(this.text);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final GettersAndSetters other = (GettersAndSetters) obj;
        if (this.number != other.number) {
            return false;
        }
        if (!Objects.equals(this.text, other.text)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "WithoutLombokAnnotations{" + "flag=" + flag + ", number=" + number + ",
            text=" + text + '}';
    }
}

Great. Same functionality and 18 lines of code removed. We left in the code the strList getter because it has non standard functionality.

By using Lombok’s @Getter and @Setter annotation at class level we ask Lombok to generate getter and setter for all non-static fields. Of course final fields will not have setters.

@Getter and @Setter annotations can be placed at class level (like in the example) and at field level.

I usually prefer to use Lombok annotations at class level for two reasons: to not forget to add proper annotations when I add new fields in the class and to avoid to clutter class code with too many annotations (at fields level; see for example when you are using Lombok in JPA entity classes).

 

CONSTRUCTORS

Second step: the constructor (http://projectlombok.org/features/Constructor.html). By adding the @lombok.RequiredArgsConstructor annotation at class level, we can remove the 4 lines of the constructor.

Lombok has three different annotations for the constructors:

  • @RequiredArgsConstructor, the one we used in the example, generates a constructor for all final fields, with parameter order same as field order
  • @NoArgsConstructor creates an empty constructor.
  • @AllArgsConstructor creates a constructor for all fields

 

HASHCODE and EQUALS

Third step: the hashCode and equals methods (http://projectlombok.org/features/EqualsAndHashCode.html). In the example we have created these methods using the number and text fields.

By adding the @lombok.EqualsAndHashCode(of = {“number”, “text”}) annotation we can remove Equals and HashCode methods, going down by other 26 lines of code. And Lombok also generates the canEqual method. See here (http://www.artima.com/lejava/articles/equality.html) for the reasons.

Important: never use @lombok.EqualsAndHashCode without specifying the fields. Always use the of parameter (or the opposite exclude parameter). Without parameters, @lombok.EqualsAndHashCode will use all fields, possibly creating heavy equals and hashCode methods.

 

TOSTRING

Last step is to use @lombok.ToString (http://projectlombok.org/features/ToString.html) to implement the toString method. While having a toString method is highly suggested (for ex. for debugging and analysis purposes), my usual approach is to avoid collections and arrays fields in the toString method to avoid cluttering logs and messages windows with too long text lines.

After all our changes, the original class is now:

@lombok.Getter
@lombok.Setter
@lombok.RequiredArgsConstructor
@lombok.EqualsAndHashCode(of = {"number", "text"})
@lombok.ToString(exclude = "strList")
public class EveryThing {
    private boolean flag;
    private final int number;
    private final String text;
    private List<String> strList;

    public List<String> getStrList() {
        if (strList == null) {
            strList = new ArrayList<>(128);
        }
        return Collections.unmodifiableList(strList);
    }
}

Very short and with just the relevant code shown: the fields and the custom getter. No boilerplate code. Exactly what we were looking for.

LOGGING

Another quite useful Lombok annotation is related to logging (http://projectlombok.org/features/Log.html): Lombok can create a Logger field, named log, in our class. There are six variations of the annotation depending on the logging framework (java, apache, log4j, slf4j,,,).

The logging annotation does not reduce the amount of code in our class (one line for the annotation vs. one line for the manual logger definition) but it can help us to guarantee that we are using the same logging framework among all project classes. In some projects with large teams, I’ve found different logging frameworks used simply because different programmers were using IDE auto-complete functions in a different way.

Having something like

@Slf4J
public class ….

help us to use the same logger on all the class files.

@DATA

The @lombok.Data annotation (http://projectlombok.org/features/Data.html) is a short version for @Getter @Setter @EqualsAndHashCode, @ToString and @RequiredArgsConstructor.

At first glance it looks very convenient (one annotation instead of five) but, unfortunately, we cannot specify the fields for @EqualsAndHashCode and @ToString so it is not a good idea to use the @Data annotation unless the class is really a very simple POJO, without complex fields.

Moreover @Data does not generated automatically a no args constructor, required by JavaBeans and XML conversions so a @NoArgsConstructor annotation is also needed.

SUGGESTIONS

Lombok is very useful to reduce boilerplate code but it is important to keep in mind what Lombok is doing on our code to avoid useless and heavy generated code.

My personal suggestions:

  1. Always specify the fields you want in @EqualsAndHashCode or, in another words, never use the default @EqualsAndHashCode behaviour (all fields). Very important if the class is a JPA entity, where generated ID field should not be used for equality.
  2. Always exclude heavy fields (collections, arrays) in @EqualsAndHashCode and @ToString unless it is really necessary.
  3. Use @NoArgsConstructor when an empty constructor is needed (like for XML conversions and in JavaBeans)
  4. Never use Lombok @Data. As mentioned before, with the @Data annotation we cannot specify the fields for @EqualsAndHashCode and @ToString (see previous suggestions).
  5. On JPA entities:
    @EqualsAndHashCode: exclude generated @Id fields (persistence equality constraint: a generated ID field is not always defined during entity life-cycle.)
    @ToString: exclude other JPA entities and relationship to reduce method weight and avoid unexpected persistence problems like lazy initialization exceptions.

 

FINDBUGS and PMD

FindBugs works well with Lombok because it analyses the compiled code, so after Lombok.

On the contrary PMD, which analyses the source code, does not work well. I suggest to add a @SuppressWarnings(“PMD”) annotation at class level to tell PMD to completely skip the class. See here (http://pmd.sourceforge.net/pmd-5.1.0/suppressing.html) for more details.

 

DELOMBOK

Lombok provides a “delombok” (http://projectlombok.org/features/delombok.html) function so we can look at the code is really compiled, after Lombok processing.

We should open a terminal window, go to the project root dir and run the following command:

java -jar <path_to_lombok.jar> delombok src -d src-del

where

  • <path_to_lombok.jar> is the path to the lombok jar file. Maven users can find it at <maven_repository>/org/projectlombok/lombok/<version>/lombok-<version>.jar
  • src is the name of source dir (Maven default)
  • src-del is a name of the dir where we want delombok to put all files.

Our delombok-ed file is

public class ToString {
    private boolean flag;
    private final int number;
    private final String text;
    private List<String> strList;

    public List<String> getStrList() {
        if (strList == null) {
            strList = new ArrayList<>(128);
        }
        return Collections.unmodifiableList(strList);
    }

    @java.lang.SuppressWarnings("all")
    public boolean isFlag() {
        return this.flag;
    }

    @java.lang.SuppressWarnings("all")
    public int getNumber() {
        return this.number;
    }

    @java.lang.SuppressWarnings("all")
    public String getText() {
        return this.text;
    }

    @java.lang.SuppressWarnings("all")
    public void setFlag(final boolean flag) {
        this.flag = flag;
    }

    @java.lang.SuppressWarnings("all")
    public void setStrList(final List<String> strList) {
        this.strList = strList;
    }

    @java.beans.ConstructorProperties({"number", "text"})
    @java.lang.SuppressWarnings("all")
    public ToString(final int number, final String text) {
        this.number = number;
        this.text = text;
    }

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public boolean equals(final java.lang.Object o) {
        if (o == this) return true;
        if (!(o instanceof ToString)) return false;
        final ToString other = (ToString)o;
        if (!other.canEqual((java.lang.Object)this)) return false;
        if (this.getNumber() != other.getNumber()) return false;
        final java.lang.Object this$text = this.getText();
        final java.lang.Object other$text = other.getText();
        if (this$text == null ? other$text != null : !this$text.equals(other$text)) return false;
        return true;
    }

    @java.lang.SuppressWarnings("all")
    public boolean canEqual(final java.lang.Object other) {
        return other instanceof ToString;
    }

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public int hashCode() {
        final int PRIME = 277;
        int result = 1;
        result = result * PRIME + this.getNumber();
        final java.lang.Object $text = this.getText();
        result = result * PRIME + ($text == null ? 0 : $text.hashCode());
        return result;
    }

    @java.lang.Override
    @java.lang.SuppressWarnings("all")
    public java.lang.String toString() {
        return "ToString(flag=" + this.isFlag() + ", number=" + this.getNumber() + ", text=" +
            this.getText() + ")";
    }
}