Tuesday, April 26, 2011

Testing Struts 2 Actions with JUnit

I've been trying my best to stick closely to the Test-Driven Development process with my current project.  A couple of my previous blog posts detail my experiences setting up JUnit and later testing Hibernate code with JUnit.

I'm currently working with Struts 2 and I have been researching methods for testing my Actions.  The struts.apache.org website has a nice little tutorial detailing the StrutsTestCase and the Struts 2 JUnit plugin.  I searched for more online resources on this topic but it became quickly apparent that most examples include Stuts 2, JUnit and Spring.  I'm not using Spring in this project and I haven't had the opportunity to get up to speed on the Spring framework yet.  Therefore, a lot of the examples I found were not helpful for me right now.

One concern I had about using the StrutsTestCase is that its Sourceforge project page hasn't been updated in years.  It still proudly displays "Now supporting Struts 1.2 and 1.3!"  However, I decided to give it a try since the Struts 2 documentation offers a tutorial and the struts2-junit-plugin-2.2.1.1.jar is included in the current Struts 2 distribution.

I modified the sample code from the Struts 2 tutorial to suit my needs.

public void testCreateTagFail() throws Exception {
    request.setParameter("name", "");
    ActionProxy proxy = getActionProxy("/createtag.action");
    TagAction tagAction = (TagAction) proxy.getAction();
    proxy.execute();

    assertTrue("Problem There were no errors present in fieldErrors but there should have been one error present", tagAction.getFieldErrors().size() == 1);
    assertTrue("Problem field 'name' not present in fieldErrors but it should have been",
            tagAction.getFieldErrors().containsKey("name") );

}

I had some compile errors and needed to add spring-test-2.5.6.jar and spring-core-2.5.6.jar to my build path.  Both of these jars are included in the Struts 2.2.1.1 distribution.

The method above is quite simple and just tests the Action's validation() method to confirm it returns a FieldError when a value for the Tag Name is missing.

Below is a method that gave me a lot of trouble:
    public void testCreateTag() throws Exception {

        request.setParameter("name", "my tag name");
        ActionProxy proxy = getActionProxy("/createtag.action");
        TagAction tagAction = (TagAction) proxy.getAction();
        String result = proxy.execute();

        assertTrue("Problem There were errors present in fieldErrors but there should not have been any errors present", tagAction.getFieldErrors().size() == 0);
        assertEquals("Result returned form executing the action was not success but it should have been.", "success", result);
    }

This JUnit test caused the Action to throw a Null Pointer exception when I tried to run it.  The problem is the Action expects to find a Hibernate SessionFactory object in the ServletContext.  (This earlier blog post explains my methodology for adding the Hibernate SessionFactory to the ServletContext.)  Since the StrutsTestCase is running outside a real container, using a mock container, the Action is not finding the SessionFactory and returning Null instead.

I did some research and determined I had a few options to resolve this problem.  First, as I mentioned in a previous blog post, I would be better off using mock database objects or DBUnit rather than testing against Hibernate and my actual relational database.  I may do that in the future, but it's not going to happen now.  :)

Another option would be to add the SessionFactory to the mock ServletContext and pass that to the Action through the StrutsTestCase.  This is an option I probably should have pursued and I would love to see some example code for this.

Of course, I went with the third and probably least elegant option.  I created a base class that extends ActionSupport and added a method getSession() which tries to retrieve the the Hibernate SessionFactory from the ServletContext and creates a new one if it fails.
public class FlashCardsAppBaseAction extends ActionSupport{

    protected Session getSession() {

        //try to get hibernate session from the servlet context
        SessionFactory sessionFactory =

        (SessionFactory) ServletActionContext.getServletContext()
            .getAttribute(FlashCardAppConstants.HibernateSessionFactoryName);

        // if the sessionFactory is null then create a new one
        if (sessionFactory == null) {
            sessionFactory = HibernateUtil.createSessionFactory();

            // add the Hibernate SessionFactory to the ServletContext
            ServletActionContext.getServletContext().setAttribute(FlashCardAppConstants.HibernateSessionFactoryName, sessionFactory);
                }

        // get a session from the session factory
        return sessionFactory.openSession();
        }
}

I refactored my Actions to extend the new FlashCardsAppBaseAction and they get a handle to the SessionFactory using the super.getSession() method as seen below.

@SkipValidation
public String listTags() {

    try {

        // get a handle to a Hibernate session
        Session session = getSession();

        // get a list of Tags from the data tier
        TagPersister tagPersister = new TagPersister();

        tagList = tagPersister.getTags(session);

        return "success";

    } catch (HibernateException e) {

        logger.error("Exception in listTags():", e);
    
        return "input";
    }
}

The code now works when running in an actual servlet container and also through the mock container via the JUnit tests.

One last note, my new StrutsTestCase tests ran successfully through the Eclipse IDE but were failing when run through ANT outside of Eclipse.  I fixed this by adding the Tomcat jars to the Classpath for the Ant build.xml.

Monday, April 25, 2011

Struts 2 - A simple server-side validation example

There are many options for performing validation in Struts 2.  Below are steps I used to add server-side validation to a Struts v2.2.1.1 web project.
  1. Add validate() method to Action class.  Since my Action classes already extend ActionSupport, it's simple to override the default validate() implementation to provide my custom validations.
    public void validate() {
        logger.debug("Entering validate()");

        if ( tag.getName().length() == 0 ){
            addFieldError("name", getText("error.tag.name"));
        }
    }
    This example simply verifies the "name" attribute of the POJO named Tag exists, adding a FieldError when it doesn't.  Note the getText("error.tag.name") where we call the getText() method of ActionSupport to retrieve the value of the "error.tag.name" message key from the resource bundle.
  2. Add "input" result to struts.xml.  If our validation fails, the validate() method will automatically seek the "input" result.  Therefore, we'll add it to our action element in struts.xml.
    <action name="createtag"
               class="org.robbins.flashcards.presentation.TagAction"
               method="createTag">
        <result name="success">displayTag.jsp</result>
        <result name="input">tagForm.jsp</result>
    </action>
  3. Add <s:actionerror /> and <s:head /> to JSP's. The <s:actionerror /> will render any errors as HTML.  The <s:head /> is optional but will include a CSS (xhtml by default) and a JavaScript utility file.
  4. Add error messages to resource bundle.  In my case, I added  error.tag.name= Tag name is required to my ApplicationResources.properties.  Remember, we added a reference to error.tag.name in our validation code of the Action class.
  5. Add @SkipValidation to methods that don't require validation.  If your Action class is very simple with just a single execute() method then you can skip this step.  However, if you are using several methods in your action classes (ie. create(), edit(), list()) than you may want to add the @SkipValidation annotation to methods you don't need validated.  In my case, I had a list() and display() method that didn't require validation.

Sunday, April 24, 2011

Hibernate - Part 5 - Storing Hibernate SessionFactory with Struts

I'm working on a relatively simple web project using Struts 2 and Hibernate.  I'm not planning on using any EJB's so my persistence code will be directly accessible by my Struts Action classes.  For performance reasons, I know it is recommended to minimize the times you create the Hibernate Configuration and SessionFactory objects.

I did some Googling and didn't find much in the way of best practices for using Struts and Hibernate.  I figured it would make sense to create the Hibernate SessionFactory once and add it to the ServletContext so that it is available for the life of the application.  I found an example of this technique here and adapted it for my application.

I noticed the example created the SessionFactory and added it to the ServletContext but never closed it.  I added code to the contextDestroyed method of my ServletContextListener class to destroy the SessionFactory at shutdown.  I've run this by a couple of people and received differing opinions on whether it is necessary to close it but I don't think there is any harm in doing so.

Here's a snippet of the code I'm using:

public class HibernateListener implements ServletContextListener {

private Configuration config;
private SessionFactory sessionFactory;
private String path = "/hibernate.cfg.xml";

public static final String KEY_NAME = HibernateListener.class.getName();

@Override
public void contextDestroyed(ServletContextEvent arg0) {
    if ( sessionFactory != null ) {
        sessionFactory.close();
    }

}

@Override
public void contextInitialized(ServletContextEvent arg0) {
    try {
        URL url = HibernateListener.class.getResource(path);
        config = new Configuration().configure(url);
        sessionFactory = config.buildSessionFactory();

        // save the Hibernate session factory into serlvet context
        arg0.getServletContext().setAttribute(KEY_NAME, sessionFactory);
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}
 Here's what I added to the web.xml
<listener>
    <listener-class>insert.package.name.here.HibernateListener</listener-class>
</listener>

Thursday, April 14, 2011

"Deployment Assembly" replaces "Java EE Module Dependencies" in Eclipse Helios

Frequent Eclipse users are likely already familiar with this UI change in Eclipse Helios but it's news to me and I figured I'd write a short post about it.

First, some quick background info: I spent some time last night getting up to speed on Struts 2.  I have a decent amount of experience using Struts but it's been a while.  In fact, it's been long enough that when I last used Struts, version 1.1 was the current version.  :) Anyway, I watched a couple of Struts videos on YouTube and read a few online tutorials (link1, link 2) and was ready to get started.  I won't go into detail in this post about the basic Struts configuration of Eclipse.

Everything was going according to plan until I added my previously created Eclipse User Library for Hibernate to the build path of the Dynamic Web Project.  The following warning appeared in the Markers view in Eclipse:
Classpath entry org.eclipse.jdt.USER_LIBRARY/Hibernate-3.6.2.Final will not be exported or published. Runtime ClassNotFoundExceptions may result.
Well, I guess that makes sense.  Thinking back to the days when I regularly used Eclipse (actually I was using the IBM branded version named Rational Application Developer), I figured I probably need to configure the project's "Java EE Module Dependencies".  The only problem was I didn't see it listed in the dialog for Project > Properties.  Huh?

I did some Googling and found some forum posts about the same problem.  It turns out the "Java EE Module Dependencies" has been replaced by the new "Deployment Assembly"  in Eclipse Helios (more specifically Web Tools Platform 3.2 as described here).

I added the Hibernate User Library to the deployment package structure by doing the following:
Project Properties > Deployment Assembly > Add > Java Build Path Entries > and selecting "Hibernate-3.6.2.Final" which is the name of my User Library.

I saved the configuration change and the Warning disappeared from the Markers view in Eclipse.

Wednesday, April 13, 2011

Hibernate - Part 4 - Testing persistence code with JUnit

I'd like to preface this post by saying this is not intended to be a best practice for testing Hibernate related application code.  I'd just like to show the methodology I'm using at the moment and discuss a few of the call outs I've found on this topic.  Of course, reader input and suggestions are always encouraged so please feel free to fire away.

In a previous post, I discussed the Hibernate mappings file and Ant tasks I'm using to create my Java entity classes and database tables.  I've since created some classes that wrap the CRUD functions for these entities.  I'll refer to these as my persistence classes. Of course these classes use the Hibernate framework (Transaction, Session, Query) and also have a little logic for dealing with the underlying relationship between the entities.

So now I need to test the code.  Yes I know, ideally I'd have written the tests before writing my persistence classes.  :)  I'm using JUnit for unit testing and since both JUnit and Hibernate are quite popular I figured I could quickly locate some online examples of using the two together.  Well, here's where things get a little complicated, or should I say controversial...

First off, I should probably refer to the testing of my persistence classes as integration testing and not unit testing.  As this Stack Overflow post explains, a unit test "should be a stand-alone test which is not related to other resources" and the integration test is "similar to unit tests but with external resources (db, disk access)".

Putting aside the semantics, what's the best way to use JUnit to test your Hibernate related code?  Here are some of the suggestions I've found:
  • Don't do a straight test of Hibernate related code with JUnit, use Spring instead.  Spring has a testing module for writing unit and integration tests.
  • Mock the Hibernate layer by using a mocking framework like JMock.  This enables you to focus your unit test on your code and removes any external frameworks (ie. Hibernate) from the test.
  • Use JUnit extension DbUnit to put your database into a known state before test runs.
  • Use an embedded, in-memory, database like HSQL for your testing.  This removes the reliance on your external full-fledged RDMS.
I'm eager to use Spring but it's not going to happen with this project or at least this phase of the project.  I'd also like to try the mocking or DbUnit approach, and I may do so but it won't happen until later either.

For reference, here's a couple of forum posts where JUnit and Hibernate are discussed:

For now, I'm going against better judgement and testing my persistence code with straight JUnit tests against my MySQL database.  I'll test the CRUD functions of my persistence classes and leave it at that.

I've created a JUnit test class for each of my persistence classes.  Rather than creating a Hibernate SessionFactory with each test method, I'll create it once in the JUnit @BeforeClass method and close it in the @AfterClass method.  Here's what it looks like along with one of the test methods:
    @BeforeClass
    public static void oneTimeSetup() throws Exception  {
        logger.debug("Entering oneTimeSetup()");
       
        // A SessionFactory is set up once for an application
        sessionFactory = new Configuration()
                .configure() // configures settings from hibernate.cfg.xml
                .buildSessionFactory();
    }
   
    @AfterClass
    public static void oneTimeTearDown() {
        logger.debug("Entering oneTimeTearDown()");
       
        if ( sessionFactory != null ) {
            sessionFactory.close();
        }
    }
   
    @Test
    public void testCreateTag() {
        logger.debug("Enter testCreateTag()");
       
        // create new Tag object
        Tag tag = new Tag("tag1");
       
        TagPersister tagPersister = new TagPersister();
       
        // Ask for a session using the JDBC information we've configured
        Session session = sessionFactory.openSession();
       
        assertTrue("Error while creating new Tag", tagPersister.createTag(tag, session));
    }
What do you think?  Reader ideas and suggestions are encouraged and appreciated.

    Tuesday, April 12, 2011

    Hibernate - Part 3 - Creating entity classes and database tables

    My previous blog post described the basic process I used to configure my Eclipse Java project to use Hibernate.  At the time, I was playing around with the example code from the Harnessing Hibernate book.  I found the examples helpful and now I'm ready to start using Hibernate in my own Java project.

    Hibernate gives you several options for creating your Java entity classes and database tables.  This is important and necessary because there will be times when we'll need to integrate Hibernate into existing projects where some combination of the entity classes and database tables may already exist.

    In my case, I'm literally starting from scratch and need to create everything.  Should I use Hibernate mapping files (.hbm), Hibernate Annotations, or Java Persistence API (JPA) Annotations?

    I played around with JPA Annotations as described in this tutorial video.  JPA has the advantage of being the Java standard and capable of working with ORM tools other than Hibernate.  I'd like to continue getting up to speed with JPA but for now I decided to use Hibernate mapping files (.hbm).

    I copied an existing .hbm file from the samples included in Harnessing Hibernate and modified it for my own entity classes.  After all, isn't copying existing code how we always get started?  :)

    At this point in my project, I have created an .hbm file for two entities: FlashCard and Tag.  What makes these interesting is that FlashCard contains a collection of Tag objects and will therefore need a join table (ie. flashcard_tag) in the database.  Here's where Hibernate shows its strength and ease of use.  We can define the relationship between these two entities in the mapping file and let Hibernate create the Java classes and database tables for us.  Hibernate understands the relationship.

    Here's an excerpt from a mapping file where the relationship between FlashCard and Tag is defined:
            <set name="tags" table="FLASHCARD_TAGS">
                <meta attribute="field-description">Tags for this FlashCard</meta>
                <key column="FLASHCARD_ID" />
                <many-to-many class="org.robbins.flashcards.model.Tag"
                    column="TAG_ID" />
            </set>
    Now that I've got my Hibernate mapping files ready, I need to have Hibernate go ahead and create my Java entity classes and tables in the MySQL database.

    I'm going to let Ant and the HibernateTool task generate the Java code and database tables.  Here's an excerpt from my build.xml which I adapted from the Harnessing Hibernate examples
        <!-- create the Java entity classes -->
        <target name="codegen" depends="prepare, refresh.local"
                    description="Generate Java source from the O/R mapping files">
            <hibernatetool destdir="${source.dir}">
                <configuration configurationfile="${source.dir}/hibernate.cfg.xml" />
                <hbm2java jdk5="true" />
            </hibernatetool>
        </target>

        <!-- create the database tables -->
        <target name="schema" depends="prepare, refresh.local"
                description="Generate DB schema from the O/R mapping files">

            <delete dir="${data.dir}" />
            <mkdir dir="${data.dir}" />

            <hibernatetool destdir="${source.dir}">
                <configuration configurationfile="${source.dir}/hibernate.cfg.xml" />
                <hbm2ddl drop="yes" />
            </hibernatetool>
        </target>

    Hibernate - Part 2- Getting Started

    As mentioned in a previous post, I've been preparing for using Hibernate in my latest project by reading Harnessing Hibernate, the Getting Started Guide, and watching some tutorials on YouTube.  At this point, I was ready to do some coding.

    I opted to download and play with some of the tutorials from the Harnessing Hibernate book.  However, I wouldn't be using the code as-is.  I'd be making some initial modifications to the sample code:
    1. I'd use the current version of Hibernate (v3.6.2.Final), Hibernate Tools (v3.2.4.GA) and Ant (v1.8.2) instead of the older versions discussed in the book.
    2. I decided, at least for now, not to use the Maven ant tasks for downloading and maintaining library dependencies.  Instead, I would manually download the Hibernate release bundles from SourceForge.
    3. I would run the examples through Eclipse rather than solely through the file system as described in the book.
    4. Instead of using the example "test" code as-is (Java classes with main() method), I would incorporate the test code into JUnit tests.
    So far so good, right?  Well I quickly ran into some challenges getting the sample code running on my dev system.

    Downloading and unpacking the Hibernate resource bundles is a no-brainer, but do I need to do anything special to Eclipse?  Of course, my project will need the Hibernate jars in its classpath (more on the later) but if I want the Eclipse IDE to include the Hibernate perspective and tooling I'll also need to install the Hibernate Tools directly into Eclipse.  Although I won't really leverage the Hibernate / Eclipse integration right now, I'd like to at least get it configured.  Rather than go step-by-step through the process, I recommend following the directions as described in the JBoss Tools 3.2 Installation From Update Site.

    At this point, I created a new Eclipse Java Project and imported the Harnessing Hibernate sample code for Chapter 3.  The sample code includes an Ant build file, the Hibernate configuration and mapping files as well as test classes for inserting records and querying records.

    I had compile errors in the Java classes that reference Hibernate.  It's worth noting that even though we installed the Hibernate Tools into Eclipse (and indeed Eclipse now recognizes and assigns special icons and editors to the Hibernate config and mapping files) we still need to add the Hibernate and dependent jars to the project build path.

    Several of the online tutorials I read suggested using Eclipse User Libraries as a convenient way to organize the Hibernate jars in the project's build path.  The User Libraries initially seemed like a good solution and my Java classes now compiled without errors.  However, I soon realized my Ant build wasn't aware of the User Libraries I created.  I describe in detail in an earlier blog post my attempts to overcome this issue.  In the end I decided to utilize User Libraries in Eclipse and add separate classpath references for the jars in the Ant build file.  It seems like a duplication of effort but it's workable for now.

    An inspection of the Ant build.xml included in the Harnessing Hibernate sample code shows Ant tasks for using the HibernateTool task to create both Java classes and Database tables.  The Hibernate Tool uses the hibernate.cfg.xml and a couple of Hibernate mapping files (.hbm) to determine what to create and where.  For these samples, we are using an HSQLDB database.

    Before we run the Ant tasks and actually use Hibernate for the first time, let's take a moment to review what we've done so far:
    1. Download and unpack the release bundles for Hibernate, Hibernate Took and Ant.
    2. Install the Hibernate Tools into Eclipse using Help > Install Software
    3. Create a new Eclipse Java Project and import the sample code from Harnessing Hibernate (Chapter 3)
    4. Create Eclipse User Libraries for Hibernate
    5. Update the Ant build.xml classpath with references to the Hibernate and Hibernate tool jars.
    At this point, I ran the HibernateTool tasks in the Ant build file for creating the Java entity classes and database tables.  Ant executed without any stack traces and ended with BUILD SUCCESSFUL.  Awesome!  I confirmed the new Java classes were created but when I fired up the HSQL Database Manager I couldn't see the new database table.  What gives?  Why did Ant finish successfully but not create the table?

    This caused a lot of confusion on my part and began a period of tweaking my classpath and log4j logging levels in an effort to understand the problem.  The first thing I noticed was my updated log4j level (now DEBUG) wasn't printing anything to the console.  I was only seeing INFO level logging.  Hmmm.

    Remember, up to now I've been running the Ant build directly from Eclipse.  At this point I tried running Ant directly from a Command Prompt and voila!  The output showed DEBUG log4j logging and most importantly the database table was now created in HSQL.

    After some more trial and error, I modified the JRE setting in Eclipse for the Ant build file (Right click on build.xml > Run As > Ant build...) and changed the Runtime JRE from "Run in the same JRE as the workspace" to "Separate JRE".  The JRE specified in the "Separate JRE" was the EXACT same JRE that Eclipse was using.

    I then reran Ant tasks from within Eclipse and this time it worked!  I don't understand why it works in a separate JRE but not within the same JRE.  I posted to the Tools forum in the Hibernate Community.  One of the guys from the Hibernate Team posted some responses but in the end suggested keeping the "Separate JRE" setting which is what I've done.  I also made a similar post on the Stack Overflow boards.

    Friday, April 8, 2011

    Using Eclipse "User Libraries" with Ant

    An Eclipse User Library is simply a set of JAR files defined within the IDE.  It provides a convenient way to organize and include jars in your project's build path without having to actually import the jars into your project and having them get deployed with your project.  User Libraries can be reused across multiple projects.  I haven't tried it myself, but it appears the User Libraries can be shared across machines with minimal hoop jumping.

    So far so good.  But how will Ant access these User Libraries?  As far as I can determine, there's no out-of-the-box way for Ant to reference an Eclipse's User Library in it's classpath.  Here's a couple of relevant forum posts on the topic:
    So what's the solution? Here's the options I've seen so far:
    1. Use the Eclipse User Library as-is then configure the Ant build file separately for the jars you need in your classpath.  I consider this option the "hard way" and of course it's what I'm doing for now.
    2. Use Apache Maven instead of Ant for build and project dependencies.  I'd like to give this a try when I have time. 
    3. I've seen a few people suggest using Ant4Eclipse.  I haven't had time to try it myself yet but it sounds like a potential solution.
    4. Don't utilize Eclipse User Libraries and copy your required jars to a /lib folder in your project.  Of course, this is just ignoring the issue isn't it. :)
    I'm interested in other approaches and options for this problem.  Please feel free to comment.  Thanks.

    Hibernate - Part 1- Learning Resources

    My previous experiences with enterprise Java utilized many of the core J2EE design patterns.  We used Data Access Objects (DAO), List Handlers, Value Objects, etc.  Sticking with these design patterns within our team ensured our apps would be flexible, reusable and standardized.

    Developers were able to jump from project to project and hit the ground running because the persistence code was similar between all of our applications.  I learned a lot from this experience and the J2EE design patterns provided good runtime performance

    The only problem I found with the J2EE design patterns for data persistence was the time required to create the necessary classes for each database table.  Coding the persistence layer was long and arduous and slowed down application development.

    In the years since we began using the core J2EE design patterns, open source frameworks have gained popularity. I'm eager to use Hibernate for the persistence layer in my new application.  I'm hopeful that Hibernate will reduce complexity and most importantly reduce the time required for persistence coding.

    I'm currently reading Harnessing Hibernate and working with some of the included code examples.  Some of the Amazon.com reviews are critical of this book's emphasis on other technologies like Ant and Maven.  The reviewers felt the book loses focus on Hibernate and spends too many pages elsewhere.  I don't share that sentiment, at least not yet.  I like to see how Hibernate fits into the whole ecosystem of a typical application.

    Here's a very basic step-by-step tutorial for setting up Hibernate and Log4j on Eclipse.

    I always look for YouTube videos on any new topic I'm trying to learn.  You might not think YouTube would be a great place to learn about java coding but there's plenty of helpful videos out there.  There's a series of 18 Hibernate videos from Patrick Washington that I've been watching and recommend.

    Here's a video of the 1st part in the18 part series:


    What resources have you found useful for learning Hibernate?  Your comments are welcome.

    Old JRE's on my dev computer

    I mentioned in an earlier post that I installed JDK 1.6.0_24.  I noticed that Sun (or should I now say Oracle) recommends uninstalling older version of Java from your system.  They say the older versions present a "serious security risk".  I didn't feel too worried but I figured I'd go ahead an uninstall the JRE's and JDK that I'll never likely use again anyway.  After all, I can use all the disk space I can get on this old resource starved dev machine.

    Sun conveniently provides instructions for uninstalling Java on Windows.  It's the usual Control Panel > Add / Remove Programs (at least that's how XP still does it).  I ran the uninstaller for the half dozen of so previous Java versions without incident.

    After all was said and done I opened Windows Explorer and looked for the old Java install folders.  I was a little disappointed to still find each of the old Java install root folders on my system with a handful of .dlls and .jars in each folder.  Of course I've seen many uninstallers leave artifacts on my system but it's always a little annoying.  I Googled a few the .dll names and found some posts of others asking what to do about these remnants.  Sorry I didn't take a note of any examples before I deleted the folders from my system.  They're gone now and I haven't experienced any side effects. I wish the Java uninstallers did a complete job.

    Note: It's a good idea to check your %Java_Home% and %Path% Windows Environment Variables to confirm they are set to your current JDK.  I had to update mine.

    Maybe there's a good reason for leaving these old .jars and .dlls?  Please post comments if you have anything to add.

    Thursday, April 7, 2011

    Getting started with JUnit and Eclipse

    Over the years I've done load testing and user acceptance testing but this is the first time I've done any serious unit testing. I'm be using JUnit 4.x and trying my best to stick test-driven development.

    Everyone learns in different ways, some are book-learners and others like to dive right in and get their hands dirty.  I'd like to think I take a hybrid approach but I'm always thankful for a nice tutorial.  I definitely recommend the Eclipse and Java for Total Beginners video tutorial.  Sure it's geared for true Java and Eclipse beginners but it covers JUnit and test-driven development in some clear and concise detail.

    The tutorial doesn't include using Ant to run your JUnit tests.  Here's the code I am currently using in my Ant build.xml for invoking the JUnit tests in my project.

    <target name="junit" depends="compile, jar">
        <junit showOutput="true" printsummary="on" fork="true" haltonfailure="true" dir="${basedir}">
            <classpath refid="project.classpath" />
            <formatter type="xml" />
            <batchtest todir="${output.dir}">
                <fileset dir="${test.dir}">
                    <include name="**/*Test*.java" />
                </fileset>
            </batchtest>
        </junit>
    </target>
    

    Wednesday, April 6, 2011

    Next steps in setting up my development environment...

    Baby steps folks, baby steps...

    In my previous post I installed Java SDK 1.6.0_24 and Eclipse EE IDE 3.6.2.  When everything goes right, as it did for me, these two installs are a no brainer.

    Next in line for installs are MySQL, MySQL Workbench, the MySQL JDBC driver, Apache Tomcat, and Apache Ant

    Let's start with MySQL, the MySQL Workbench and JDBC driver.
    Prior to the install I watched a free webinar titled "MySQL Essentials Series - Part 1: Building, Installing and Configuring MySQL" which covers in some detail a number of installation and configurations options available for MySQL.  I thought the video was worth my time.

    My needs should be simple so I opted for the MySQL Community Server 5.5.11 using the MSI Installer for 32-bit Windows.  I installed to "C:\Program Files\MySQL\MySQL Server 5.5" and chose to store the MySQL data in my dev directory, "C:\dev\MySQL Datafiles".

    I opted to install MySQL as a Windows Service and later configured the service from Automatic startup to Manual.  As I've said before, my dev machine is under-powered and I need to conserve RAM usage.  I also changed the password for the root user.

    I installed MySQL Workbench 5.2.33 alongside MySQL in "C:\Program Files".  After installation, I fired it up and created a new connection to my local instance of MySQL running on the default port 3306.  I confirmed the workbench can connect to the running MySQL database.

    Lastly, I downloaded MySQL Connector/J which is the JDBC driver for MySQL.  I unzipped the file and copied the "mysql-connector-java-5.1.15-bin.jar" to my "C:\dev\plugins" directory.

    After downloading the driver and placing it in your "plugins" directory (or wherever you are storing it), go ahead and create a Driver Definition for your MySQL database in Eclipse.  Reminder: you need the EE version of Eclipse.

    Eclipse  > Open Perspective > Database Development
    Database Connections > New > MySQL > MySQL JDBC Driver 5.1
    Enter the values for you MySQL installation, including the location of the JDBC Driver, Database Name, User ID and Password.

    I'm looking forward to blogging more about developing against the MySQL database.  I used it only once before when testing a Media Wiki instance.  Most of my previous database experience has been with Oracle and SQL Server.

    Next install was Apache Tomcat.
    I downloaded the current stable release, version 7.0.11, which implements implements the Servlet 3.0, JSP 2.2 and EL 2.2 specifications.  I chose the zip of the core distribution.  As I reflect on this, I'm not sure why I didn't just choose the .exe version which automatically installs Tomcat as a Windows service.  I kind of like the zip version because I can simply unzip it anywhere and it will run using the startup.bat found in the Tomcat "bin" directory.  Also, why install yet another Windows service that I'm going to change from Automatic startup to Manual on my resource starved dev machine? I'd be interested in any comments or thoughts on which Tomcat install is best.

    Confirm your Windows Environment Variable "JAVA_HOME" is pointing to your JDK install.  I had to update my "Java_Home" because it was set to a previous JDK install.

    I ran startup.bat, watched the console output for errors and confirmed a successful server startup by navigating to http://localhost:8080/ in my browser (which these days is Firefox).

    Next, we need to tell Eclipse about Tomcat.  In lieu of me explaining step-by-step I'll suggest you read this very good tutorial from coreservlets.com: Tutorial: Installing Tomcat 7 and Using it with Eclipse

    Install Ant
    The current version of Apache Ant is 1.8.2 which I downloaded and unzipped to "C:\dev\Ant".

    Create a new Windows Environment Variable "ANT_HOME" and point it to your Ant install.  In my case "ANT_HOME=C:\dev\Ant\apache-ant-1.8.2".

    Well, that's it for now.  Truth be told, I did these installs about a week ago, before I decided to keep a running blog of my progress.  Going forward, my posts should be more detailed (and more accurate?) particularly as I begin configuring Eclipse to use Hibernate and using Ant to build my project.

    Installing the Eclipse IDE for Java EE

    My first experience with a Java IDE was VisualAge for Java back in 2000.  Before long, my company's development team moved on to WebSphere Studio Application Developer (WSAD) which before long was rebranded as Rational Application Developer (RAD).

    It's funny now but after all these years, this will be the first time I have used the regular Eclipse IDE and not the IBM branded version.  What's the difference anyway?  My understanding is that IBM's version had additional support for integration with other IBM products in the IBM and Rational product suite.  I guess I don't really know all the differences. Anyone have any additional details they can add?  Please feel free to add comments to this post.

    I downloaded Eclipse IDE for Java EE Developers (Helios 3.6.2) and unzipped it to a folder near the root of my workstation: C:\dev\eclipse\eclipse_EE_3.6.2.  That's the install in a nutshell.  Nothing to it.

    Documentation for installing and configuring Eclipse can be found in the Getting Started section of the The Official Eclipse FAQs.

    So why install Java EE version instead of the standard Java version?  The Compare Packages page details the differences between the two versions.  The EE includes packages needed for web development.  Namely the Web Tools and the Data Tools.  These tools will be necessary as I develop using Hibernate persistence in MySQL and deploy to Tomcat.

    I guess now is a good time to mention that I'm using an Dell XPS/Dimension 400/9150 circa 2006 with a single dual core 2.79 GHz CPU with only 1 GB of RAM.  This old boy is still running Windows XP.  Is this sufficient power for running a development environment with Eclipse, Tomcat, MySQL?  I hope so.  For the time being, I've splurged and ordered another 1 GB of RAM.  Hopefully, 2GB is noticeably better than 1 GB of RAM.

    Prior to the Eclipse installation, I installed JDK 1.6.0_24.