Published by Adam Myatt on 26 Mar 2008

Exploring Ant Build File Changes for Java Web Projects in NetBeans 6.1

While working with a Java Web Application in NetBeans, I noticed some slight changes in the Ant build file for my project between NetBeans 6.0 and 6.1. This article explores some of the problems these changes caused to help out anyone with similar issues.

Continue Reading »

Published by Adam Myatt on 11 Mar 2008

Reviewing the NetBeans Unit Tests Code Coverage Plugin

The NetBeans Unit Tests Code Coverage Plugin has been around for several versions of NetBeans. It measures code coverage statistics and displays annotated & highlighted lines in the Source Editor in each class that were executed by unit tests. In a recent release of the plugin, it also provides a report that shows overall, package, and class-level statistics. This article provides a quick overview of code coverage, why it is important, and what the NetBeans Unit Tests Code Coverage Plugin provides. I’ll also cover some pros/cons of the plugin.

Overview of Code Coverage

To quote myself from Chapter 16, Using Code Coverage Tools, of my book, Pro NetBeans IDE 5.5 Enterprise Edition (Apress, March 2007) :

You know that it is important to write accurate and effective tests for your code. But how do you measure the effectiveness of your tests? In a perfect world, you would write a test for every class, every method, and every line of code. Depending on the complexity of your code base, this may be easy or extremely difficult.

How do you know when you’ve written enough tests? If you have 200 tests for your code, and they all pass, then you’re finished, right? Not necessarily. You’re finished writing tests only when you know for a fact how effective your tests are. Since testing often involves visual analysis by programmers and code-based test cases, it’s difficult to know if 100 percent of your code has been tested. This is where code coverage tools come into play.

The first and obvious benefit of using a code coverage tool is being able to measure the coverage of your test cases (and, by association, the test case effectiveness). Untested code can lead to bugs, and bugs lead to many other problems.

Code coverage tools also help you identify areas in your code that are dead or unreachable. Suppose you have written test cases for all the public methods in your code. If your code coverage tool identifies one or more methods with private-level access that have never been executed, then you may be able to remove those methods from your source code. You can then use the NetBeans Safely Delete refactoring to check the method and make sure it is not called by any other code.

A good code coverage tool not only tracks if each line in each method was executed, but also how many times each line was executed. Using this data and the knowledge of what lines were and were not executed, you can understand the flow of program functionality and rearrange code blocks accordingly.

The NetBeans Unit Tests Code Coverage Plugin does not provide access to some of the information mentioned above (such as number of times each line was executed). However, it provides enough of the basic features you will need to be quite useful. Internally, the plugin depends on the Emma code coverage library.

Code Coverage tools like Emma and Cobertura (one of my personal favorites) typically work by instrumenting classes (inserting extra byte codes).  The instrumented classes are then executed instead of the original un-instrumented classes. The inserted byte codes in the instrumented classes then collect different bits of data and deposit them in a file for later analysis.

Getting Started

As of the official release of NetBeans 6.1 Beta, the update centers contained a slightly older version of the code coverage plugin. I would suggest going to the official NetBeans code coverage plugin site and download it using the prominently displayed button labeled “Download Code Coverage Plugin”.

Use the Plugins Manager to install the NBM file. Go to the Downloaded tab and click the Add Plugins button. Accept the license, click Next a few times, and you should be all set.

Once installed, you need to activate code coverage on a per-project basis. For this article, I have a standard J2SE Java Library project. In the Projects window, right-click the project name, and you should see a Coverage submenu. It contains the following options :

    Activate Coverage Collection: When clicked activates code coverage collection for the selected project. This will also generate the file nbproject/coverage.properties and coverage/emmascript.xml, which are covered below.

    Deactivate Coverage Collection: When clicked deactivates code coverage collection.

    Show Project Coverage Statistics: When clicked displays a tab in the Source Editor showing the accumulated statistics collected by the plugin for the selected project.

 Files Generated By Activating Coverage Collection

As previously mentioned, several files are generated by activating coverage collection.

The nbproject.properties file contains several parameters used by the plugin such as :

    coverage.activity=ON
    project.type=java
    coverage.templateFile=coverage/template.emma
    coverage.coverageFile=coverage/coverage.emma

The first parameter obviously indicates whether the coverage collection is active or inactive. The second parameter identifies the type of NetBeans project, and the last 2 parameters identify the paths to specific files used by the plugin.

The coverage/emmascript.xml file contains Ant targets for executing the instrumentation of the project class files.

<?xml version=”1.0″ encoding=”UTF-8″?>
<project basedir=”.” default=”echoit” name=”Coverage Tasks”>

    <target name=”echoit” description=”test target”>
        <echo message=”Test succeeded.”/>
    </target>     
    
    <target name=”instr” description=”Instrumenting jars”>
        <echo message=”Instrumenting started.”/>
       
        <java classname=”emma” fork=”true”>           
            <classpath >
                <pathelement location=”${emma}”/>
            </classpath>
            <arg line=”instr -verbose -m overwrite -cp ‘${jarfiles}’ -outdir ‘${output.dir}’ -outfile ‘${output.dir}/template.emma’”/>
        </java>
        <echo message=”Instrumenting done.”/>
    </target>
    
</project>

 The instr target runs the main emma class passing it several arguments to overwrite the application JAR file with a JAR file of the project’s instrumented classes.

Creating Sample Code

First, create a simple Java Class like this :

public class StringUtils {

    public static String tryIntToString(int numLoops) {

        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < numLoops; i++) {
                sb.append(String.valueOf(i));
        }
        return sb.toString();
    }
}

 It is basically a ‘hello world’ class that takes in a counter variable, numLoops, instantiates a StringBuffer, and loops appending an int converted to a String into the StringBuffer. The method then returns the value of the StringBuffer.

To test this method, create a JUnit test. Right-click the class listing in the Projects window and select Tools >> Create JUnit Tests (or press Control+Shift+U). Select your preferred JUnit version (4.x in this case) and the various other JUnit settings you are prompted for. Once created, I implement a basic test case for the StringUtils class passing in a value and setting the expected return.

public class StringUtilsTest {

    public StringUtilsTest() {
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
    }

    @Before
    public void setUp() {
    }

    @After
    public void tearDown() {
    }

    @Test
    public void testTryIntToString() {
        System.out.println(”tryIntToString03″);
       
        int numLoops = 10000;

        String result = StringUtils.tryIntToString(numLoops);

        int expectedResult = 38890;
       
        assertEquals(expectedResult, result.length());
    }
}

Continue Reading »

Published by Adam Myatt on 06 Mar 2008

Sharable Libraries Feature in NetBeans 6.1 Beta

I’ve been excited waiting for the new Sharable Libraries feature to be delivered in NetBeans 6.1 Beta. The concept is similar to the current Libraries features in NetBeans, but as I understand it has a few additional benefits. One of the big ones (at least from my perspective) includes better portability of NetBeans projects to continuous integration servers (Hudson being my favorite CI server of choice).

Now that NetBeans 6.1 Beta has been released I wanted to explore this feature a little and document some of what I found.

Steps I took to try it out….

I created two sample Java Web Applications called MyWebApplication5 and MyWebApplication6. The projects were created in my D:\projects\test directory.

On the Sharability screen in the project creation wizard, as shown in Figure 1, I make sure the field ‘Project shared with other users’ is checked. The ‘Sharable libraries location’ field is initially set to the relative path of “..\libraries”. The concept of relative paths here makes a big difference, especially if your development team works on and deploys to multiple platforms. You definitely do not want to use any sort of hard-coded or absolute path (there may be certain cases where the opposite is true).

I also left the ‘Copy jars to sharable location’ radio button selected. This will cause all of the web server’s JAR files into a sharable library. This can be useful if you want to make sure every developer is working on the same set of Tomcat server libraries if you deploy to a specific version of Tomcat. If you select the first radio, the project will use the JAR files for the server registered locally in your IDE. If you have multiple developers with different versions of NetBeans, there may be different server versions present. A mild warning to beware of.

Figure 1 
Figure 1

Once the projects were created I looked at the D:\projects\test directory and saw my two project directory names, ‘MyWebApplication5′ and ‘MyWebApplication6′, as well as a ‘libraries’ folder. This is the relative location that the NetBeans new project wizard generated.

The libraries folder contains a folder for the server libraries (if you chose to copy them here), as well as the 2 supported JUnit versions (JUnit 3.X and 4.X). The directory ‘junit’ contains the JUnit 3.X libraries and the directory ‘junit_4′ contains the JUnit 4.X libraries.

The top-level libraries folder also contains a file named ‘nblibraries.properties’, the contents of which are shown below :

libs.junit.classpath=\
    ${base}/junit/junit-3.8.2.jar
libs.junit.javadoc=\
    ${base}/junit/junit-3.8.2-api.zip
libs.junit_4.classpath=\
    ${base}/junit_4/junit-4.1.jar
libs.Tomcat_6.0.type=j2eeshared
libs.Tomcat_6.0.javadoc=\
    ${base}/Tomcat_6.0/javaee5-doc-api.zip
libs.Tomcat_6.0.classpath=\
    ${base}/Tomcat_6.0/annotations-api.jar;\
    ${base}/Tomcat_6.0/catalina-ant.jar;\
    ${base}/Tomcat_6.0/catalina-ha.jar;\
    ${base}/Tomcat_6.0/catalina-tribes.jar;\
    ${base}/Tomcat_6.0/catalina.jar;\
    ${base}/Tomcat_6.0/el-api.jar;\
    ${base}/Tomcat_6.0/jasper-el.jar;\
    ${base}/Tomcat_6.0/jasper.jar;\
    ${base}/Tomcat_6.0/jsp-api.jar;\
    ${base}/Tomcat_6.0/servlet-api.jar;\
    ${base}/Tomcat_6.0/tomcat-coyote.jar;\
    ${base}/Tomcat_6.0/tomcat-dbcp.jar;\
    ${base}/Tomcat_6.0/tomcat-i18n-es.jar;\
    ${base}/Tomcat_6.0/tomcat-i18n-fr.jar;\
    ${base}/Tomcat_6.0/tomcat-i18n-ja.jar;\
    ${base}/Tomcat_6.0/tomcat-juli.jar

This file lets your Ant build scripts access the shared libraries using simple properties. Note that the directory paths contain a reference to a ${base} property.

If you open the nbproject/buildimpl.xml file for one of the web applications, you can look at the -init-libraries target.

    <target depends=”-pre-init,-init-private” name=”-init-libraries”>
        <property location=”..\libraries\nblibraries.properties” name=”libraries.1.path”/>
        <dirname file=”${libraries.1.path}” property=”libraries.1.dir.nativedirsep”/>
        <pathconvert dirsep=”/” property=”libraries.1.dir”>
            <path path=”${libraries.1.dir.nativedirsep}”/>
        </pathconvert>
        <basename file=”${libraries.1.path}” property=”libraries.1.basename” suffix=”.properties”/>
        <touch file=”${libraries.1.dir}/${libraries.1.basename}-private.properties”/>
        <loadproperties srcfile=”${libraries.1.dir}/${libraries.1.basename}-private.properties”>
            <filterchain>
                <replacestring from=”$${base}” to=”${libraries.1.dir}”/>
            </filterchain>
        </loadproperties>
        <loadproperties srcfile=”${libraries.1.path}”>
            <filterchain>
                <replacestring from=”$${base}” to=”${libraries.1.dir}”/>
            </filterchain>
        </loadproperties>
    </target>

The line :

<property location=”..\libraries\nblibraries.properties” name=”libraries.1.path”/>
The property libraries.1.path references the ‘nblibraries.properties file that contains the directory/JAR references in the sharable library. After the paths are converted, the target reaches the <loadproperties>directive that loads the actual property names and values from the nblibraries.properties file. The JARs from the sharable library are then able to be referenced by your build script.

You can then go about the business of adding JARs and libraries to your web application. In the Projects window, if you right-click the Libraries node in the Java Web Application, MyWebApplication5, and select Add Library, the Add Library window will appear, as shown in Figure 2.

Figure 2
Figure 2

In Figure 2, you can see the junit, junit_4, and tomcat_6.0 libraries that exist after the project creation. Let’s say I wanted to create a small library of XML JAR files. Click the Create button and the Create New Library window appears. Type the name of the library, such as XML-Libraries, and make sure Class Libraries is selected in the Library Type field. Click the OK button. The Customize Library window appears. Here, you can click the Add JAR/Folder button to select the JAR files that will belong in the library.

The Browse JAR/Folder dialog should appear allowing you to navigate your file system and choose JAR files. In Figure 3, notice the right side of the dialog window. In contains 3 fields related to sharable libraries.; ‘Use relative path’, ‘Copy to shared libraries location’, and ‘Use absolute path’. Since we’re using a shared libraries directory, select the second radio button for ‘Copy to shared libraries location, and click teh Add JAR/Folder button. The Customize Library window should display the list of selected JAR files in the Classpath tab. Clck the OK button.

Figure 3
Figure 3

The new library, XML-Libraries, should now appear in the Add Library window, as shown in Figure 4. Now click the Add Library button to associate the newly created library with your web application.

Figure 4
Figure 4

The new library will appear listed under your Libraries node in the Projects window.

Notice the contents of the d:\projects\test directory have changed. The directory now contains the 2 XML-related JARs that I added to the XML-Libraries library.

NOTE : One thing to note, however, is that they are not placed inside a directory called XML-Libraries, like the other libraries in that folder, such as junit, junit_4, and tomcat_6.0. I wonder if that is intentional or unintentional. Anyone from the NetBeans team care to comment?

Also notice the contents of nblibraries.properties has changed.  The following is added to the bottom.

libs.XML-Libraries.classpath=\
    ${base}/xalan.jar;\
    ${base}/xerces.jar

Notice that JAR files are only referenced in the base directory and not in a separate sub-directory as mentioned above.

When you added the new library to the Java Web Application project it also sets that library and its files to be packaged with the distribution of the application. You can deselect this by right-clicking the project name in the Projects window and selecting Properties. When the Project Properties window opens, click to the Libraries tab and uncheck the checkbox in the Package column for the library. This will allow you to have the library used at compile time, but not packaged or deployed with the application.

The XML-Libraries library that was created is now also referenced in the project’s nbproject/project.properties file  as :

libs.XML-Libraries.classpath.libfile.1=../libraries/xalan.jar
libs.XML-Libraries.classpath.libfile.2=../libraries/xerces.jar 

These properties in then referenced by the build-impl.xml file in the library-inclusion-in-manifest and dist.ear.dir targets :

     <target depends=”init” name=”library-inclusion-in-archive” unless=”dist.ear.dir”>
        <copy file=”${libs.XML-Libraries.classpath.libfile.2}” todir=”${build.web.dir}/WEB-INF/lib”/>
        <copy file=”${libs.XML-Libraries.classpath.libfile.1}” todir=”${build.web.dir}/WEB-INF/lib”/>
    </target>

and :

    <target depends=”init” if=”dist.ear.dir” name=”library-inclusion-in-manifest”>
        <basename file=”${libs.XML-Libraries.classpath.libfile.2}” property=”included.lib.libs.XML-Libraries.classpath.2″/>
        <basename file=”${libs.XML-Libraries.classpath.libfile.1}” property=”included.lib.libs.XML-Libraries.classpath.1″/>
        <copy-ear-war file=”${libs.XML-Libraries.classpath.libfile.2}” propname=”included.lib.libs.XML-Libraries.classpath.2.X”/>
        <copy-ear-war file=”${libs.XML-Libraries.classpath.libfile.1}” propname=”included.lib.libs.XML-Libraries.classpath.1.X”/>
        <mkdir dir=”${build.web.dir}/META-INF”/>
        <manifest file=”${build.web.dir}/META-INF/MANIFEST.MF” mode=”update”>
            <attribute name=”Class-Path” value=”${included.lib.libs.XML-Libraries.classpath.1.X} ${included.lib.libs.XML-Libraries.classpath.2.X} “/>
        </manifest>
        <delete dir=”${dist.ear.dir}/temp”/>
    </target>

Long story short, this makes the JAR files more portable, especially if you’re running a continuous integration server. In Hudson’s project configuration, I used to have to specify a set of name/value settings that were then passed to the build file when it ran. These name/value settings were hard-coded paths to things like JUnit libraries that existed on my build server. NetBeans previously referenced these using a relative location that didn’t exist relative to the project build directories in Hudson, nor would it have been convenient to place the JAR files there either. So I had to override the specific location properties of all the libraries and provide hard-coded absolute paths. This new sharable library feature helps correct the problem. I can have all the shared libraries in one location that I specify and that is referenced correctly in the actual project’s build.xml file, NOT buried in a configuration screen in Hudson.

Published by Adam Myatt on 06 Mar 2008

NetBeans 6.1 Beta Available

The NetBeans team has released the BETA edition of NetBeans 6.1 (Download it here : http://download.netbeans.org/netbeans/6.1/beta/).

NetBeans 6.1 Beta Release 

Included in this release are :

 -  Performance Improvements (JSP parsing, Incremental parsing in Java editor, faster cold start, Visual Web designer, and more).
 - Windowing system improvements
 - Sharability of libraries
 - JSF CRUD Generator
 - MySQL support in Database Explorer
 - Java Beans support
 - Javadoc code completion
 - Spring Framework support
 - Web Services Axis2 support

For the entire list of release notes visit this link : 

http://www.netbeans.org/community/releases/61/relnotes.html#601

Published by Adam Myatt on 04 Mar 2008

Sun Releases Java 6 Update 5 (JDK 1.6.0.05)

Bug Fixes

This release contains fixes for one or more security vulnerabilities.
For more information, please see Sun Alerts
233321,
233322,
233323,
233324,
233325,
233326, and
233327.

Other bug fixes are listed in the following table.

BugId Category Subcategory Description
6647251 java classes_security Add DigiCert root CA certs to JDK
6647254 java classes_security Add TrustCenter root CA certificates to the JDK
6651160 java classes_security Add AOL root CA certs to JDK
6624769 java classes_util_i18n (tz) Support tzdata2007i
6646197 java classes_util_i18n (tz) Support tzdata2007k
6637304 java install Obsolete XPIs and replace them with new jinstall.exe to cover Java Stat’s xpi and jxpi metrics.
6622366 java sunservicetags JDK Product Registration Support

« Prev - Next »