Friday, April 18, 2014

Less is better

Once I got testing working, I turned to log generation. Nothing helps debug more than log files. Apache just put out a release candidate for version 2 of their Log4j utility. I've used version 1 in the past and, of course, "new is always better".

Unlike my experience with v1, I decided to actually learn how the utility is supposed to work, so I could create real log files, and actually manage the output with valid configuration files.  I read the introduction and implementation documentation.  I figured I was ready to try it out.

I downloaded the zip file, unzipped it into my shared library folder.  Created a library in NetBeans included all the jar files, linked them into my project, wrote some test code into my java and ...


Null Test:  Caused an ERROR
org/slf4j/ILoggerFactory
java.lang.NoClassDefFoundError: org/slf4j/ILoggerFactory
 at java.lang.ClassLoader.defineClass1(Native Method)
 at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
 at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
Test org.looman.birddog.data.DataEntityTypeTest FAILED

What!!!  I did everything the way I was told.  Back to the internet for help.  Turns out the documentation for Apache Log4j 2 doesn't include information on implementing the jar files into your classpath.  I guess they assume if you're using it, you must be advanced enough to know how to put jar files into your projects properly.

UGGGHHHHH!!!!!

More internet.  By far the best (and by "best" I means "worst") answer I found was this gem:  "You have to provide one of the various SLF4J implementation .jar files in the classpath, as well as the interface .jar file. This is documented."  by the user EJP

Documented?  Really?  Where?  What implementation .jar files are available?  No links were provided.  That was the whole answer.  And the really surprising thing is this answer got four upvotes!!

Finally, I found this post by SContributor.  The solution is that only two jar files are needed:  log4j-api.2.0-{version}.jar and log4j-core-2.0-{version}.jar.  The {version} may be different, as it refers to the unique version of the jar file.  In my case, I have release candidate 1, so the file names are log4j-api.2.0-rc1.jar and log4j-core-2.0-rc1.jar.  SContributor's solution referenced the Beta 9 version, so the file name was slightly different.  (Log4j is about to move from Release Candidate to General Availability, so your downloaded files might be slightly different).  I removed all the other jar files from the library and lo and behold, it worked beautifully!

Sometimes including everything is not only overkill, but it kills your application altogether.

On a slightly different note:
It took me a bit to get Log4j to find my configuration file.  The solution:  Using the project properties, make sure the folder containing your configuration file is included in the list of source package folders.

Friday, April 11, 2014

Making Progress

In my last post, I lamented how difficult it is to unit test the Persistence layer.  My problem revolves around creation of a valid EntityManager.  Today, I revisited Joerg Gross' DevBlog entry "JPA Unit test setup with NetBeans". This time, I worked through each step of his sample code and managed to get my test case to compile and successfully instantiate an EntityManager.

But what was even more useful, was that the failures in instantiating the EntityManager clearly identified several issues with my Entity classes.  Now that I've finally got the EntityManager working, I can move on to actually building test cases.  Stay tuned.

In my implementation, I did two things differently from Mr. Gross.  First, I don't have a web tier, so the reference to /WEB-INF/classes/ in the build file isn't relevant.  Also, I didn't create an orm.xml file. 

Here is the code as I implemented it:

In the Test class:
  @BeforeClass
  public static void setUpClass() {
    /* Code adapted from
     *  Author: Joerg Gross
     *  Title: DevBlog "JPA Unit test setup with NetBeans"
     *  URL: http://eercp.blogspot.com/2011/12/ide-setup-with-netbeans.html
     */
    Properties props = new Properties();
    props.put("javax.persistence.transactionType", "RESOURCE_LOCAL");
    props.put("javax.persistence.jtaDataSource", "");
    props.put("javax.persistence.nonJtaDataSource", "");
    props.put("eclipselink.jdbc.driver", "org.apache.derby.jdbc.EmbeddedDriver");
    props.put("eclipselink.jdbc.url", "jdbc:derby:testDB;create=true");
    props.put("eclipselink.jdbc.user", "");
    props.put("eclipselink.jdbc.password", "");
    props.put("eclipselink.ddl-generation", "drop-and-create-tables");
    props.put("eclipselink.logging.level", "INFO");

    try{
    em = Persistence.createEntityManagerFactory("BirdDogDataPU",props).createEntityManager();
    } catch(PersistenceUnitLoadingException e){
      System.out.println(e.getMessage());
      throw e;
    }

  }

In the build-impl.xml file:
    
        
        
            
        
    


On a slightly different note:
Does anyone else ever enter their password into the username field? About 20% of the time, my login pages will open without the username auto-populated and I automatically start typing my password, oblivious to the fact my cursor is in the wrong place. Have you ever done this?  No, just me. Yeah, I figured as much.

Monday, April 7, 2014

Unit Testing JPA is Painful!!!

So, I decided since I'm rebuilding my BirdDog app from scratch, I'd take the time at each tier to implement thorough unit testing.  Should be easy enough, right.  Not so much.  First, there isn't any automatic help in NetBeans (or anywhere else it seems) for creating the necessary persistence objects in order to test the entity classes.  It is easy to create the JUnit Test classes, though.

So, I went in search of some help.  So far, I've found a few promising web pages.  I had a few bumps, but one thing remains broken.  I can't get the EntityManager to create properly.  UGH!!!!

Here is my current error:
Could not initialize class org.looman.birddog.data.test.PersistenceHelper.

PersistenceHelper is a static class for setting up a test database in Derby and creating the EntityManager.  Here's the code that's failing:

  private static final EntityManager entityManager;
  static {
    Properties props = new Properties();
    props.put("javax.persistence.transactionType", "RESOURCE_LOCAL");
    props.put("javax.persistence.jtaDataSource","");
    props.put("javax.persistence.nonJtaDataSource", "");
    props.put("eclipselink.jdbc.driver", "org.apache.derby.jdbc.EmbeddedDriver");
    props.put("eclipselink.jdbc.url", "jdbc:derby:testDB;create=true");
    props.put("eclipselink.jdbc.user", "");
    props.put("eclipselink.jdbc.password","");
    props.put("eclipselink.ddl-generation", "drop-and-create-tables");
    props.put("eclipselink.logging.level", "INFO");
    entityManager = Persistence.createEntityManagerFactory("BirdDogDataPU").createEntityManager();
  }

[EDIT 11-Apr-2014: I found a great source for formatting the code to make it more readable as code.  This is an implementation of SyntaxHighlighter by Alex Gorbatchev. David Craft provided easy to follow instructions for using this on his blog, CraftyFella's Blog.]

These are the two pages I found most useful.
Unit Testing your Persistence Tier code - By Neil Buesing on Nov. 9 2010
DevBlog: JPA Unit test setup with NetBeans - Joerg Gross

I'm done for the night.  Hopefully, the light will shine on soon.

On a slightly different note:
If anyone is following this, I have a question for you.  Would it be beneficial for me to upload my code into SourceForge?  Personally, I don't need the version control, etc.  However, if people are interested in seeing the code or helping me learn, then I'll go through the trouble of creating a project.  You have to reply in the comments and let me know you'd like to see this.

Good night.

Thursday, April 3, 2014

Upgrading to NetBeans 8

I upgraded to NetBeans 8 a couple days ago and so far, I am really enjoying the changes.  One of my favorites is not well advertised and probably won't appear on anyone else's Top New Features List.

The refactoring in variable renaming is much improved.  First, when you rename an inner variable, you have the option of renaming all the associated Getters and Setters.  That alone is a significant time saver for me.

The second feature I've noticed in refactoring variable names happens in JPA Entity classes.  Relationships between classes depend on the inner variable names.  In the past when I changed the names, I would often forget one or two of the related class references and my code would fail.  Then I would spend hours trying to find the problem, because the log files weren't very clear on the problem.  Now, when you refactor a variable name in one class, the "MappedBy" value in the related class is updated automatically, removing one of my most common nemeses in debugging.

If you're interested in the new NetBeans IDE, you can download it here.  There are certainly enough new features to warrant the upgrade.  If you're new to NetBeans, I recommend it.  The learning curve is quick, better than Eclipse or JDeveloper, and the NetBeans Platform for developing Rich Client apps is a great time saver.