I few weeks ago, while attending the Central OKC Java Users Group, the presenter asked for a show of hands for how many people had actually used EJB 2.0.  In a crowd of over 50 java programmers.  If anyone raised their hand, I didn’t see it.  You mean to tell me that I suffered guilt and shame over not using EJBs for years for nothing?  You mean to tell me that I was suffering under the delusion that I was the only java programmer who thought that EJB 2.0 seemed cumbersome and of little value given the effort?  Geezaloo!  I thought EVERYBODY was using EJBs…at least until POJO frameworks gained popularity.  Just goes to show you, don’t drink the Kool-aid unless you see it mixed and poured with your own eyes!

Enter Automated Unit Testing.   For years now, I’ve read about automated unit testing with JUnit.  I’ve read articles about it.  Done tutorials where I test a method that takes two integers and adds them together.  I’ve suffered guilt and shame for not doing automated unit testing.   I’ve also suffered in trying support my own buggy code.  And when I’ve tried to write unit tests for real-world scenarios, I’ve struggled to figure it out.  I asked a veteran java programmer if automated unit testing was mixed from the same batch of Kool-Aid that EJB 2.0 was mixed.  She assured me that it wasn’t.   And now I know that she is right.   Automated unit testing is not only achievable, but CRUCIAL!  (I say this with a whole 2 weeks of JUnit under my belt)

I’ve been limping along for years testing the unit only to the extent that my functional testing happens to use this unit or that.  If something blows up, then I drop a breakpoint and take a look.  I’m here to tell you, friends,  that this is not sufficient testing.   Just in the two weeks I’ve been writing JUnit tests for my code, I’ve uncovered half-a-dozen bugs in a class that had already been functionally tested.   These are bugs that had never seen the light of day because the presentation layer could not yet present the unit with enough scenarios.    And now, I’m beginning to actually engage in what was previously believed (by me) to be a purely mythical activity that only organizations like NASA engaged in:  Test Driven Development.   Test and Code, Test and Code, Test and code…whoa!   And I’m writing the best code of my life…code that considers all possible scenarios.

One of the toughest challenges I’ve faced so far is when the class that I’m testing depends on outside resources.  I’ll take some time later to blog about how I’ve used Spring and Mock Object patterns to simulate outside resources.

I’ve been hard at it for a number of weeks.  I’m sorry to say that I’ve made very little contribution to this blog because of it, but I’ve seen the error of my ways and I’m willing to make amends.   Consider this post a promise to write about the following topics:

  • Unit Testing a JHSDK (Java Harvest SDK) application
  • Thoughts, Struggles, and Excitement with Unit Testing
  • ICE ICE BABY!  Marveling at IceFaces 1.7

Introduction

Deploying a web application that uses the JHSDK is not as simple as throwing a jar file in your lib directory. The JHSDK is a little different than other java libraries on three counts:

  1. it is a java wrapper for a C++ library. Allfusion Software Change Manager 7.x is a C++ application. The upcoming v12 release is a java application, so this C++ layer will go away. But for now, we’re stuck with it.
  2. it is a bridge for communicating with another enterprise system. Harvest is a non-web, n-tier system for managing change on software and documents. It has a proprietary front controller that brokers requests from various Harvest clients.
    Harvest Architecture from \
  3. it’s classes are not serializable, which presents problems when using it in Java EE environment

So, for your Java EE application to use JHSDK it must

  1. know where the C++ libraries reside
  2. run in an environment that has a Harvest client installed
  3. use serializable wrappers for the JHSDK classes that you need to persist

CA provides detailed documentation for setting up the environment in their Installation Guide. If you’re not accustomed to installing a Harvest client, this can be somewhat challenging. I found it very easy to deploy my web application to my local windows installation of Glassfish because I already have a working Harvest client installed; however, I worked for nearly three weeks with my Sun admin, Harvest admin, and CA Support to configure our development Solaris environment. We had never used a Harvest client on Solaris before, and you know how UNIX environments are: SOME ASSEMBLY REQUIRED.

Windows Deployment

This is an account of my deployment to a Java EE platform on Windows

OS: Windows XP SP2

Application Server: Sun Java System Application Server 9.0 Update 1 (glassfish v2 ur1)

Harvest: AllFusion Harvest Change Manager 7.0

I didn’t have to set up the Harvest Client because it was already done, so I won’t comment on that.

In Windows, there are two files that Glassfish needs to know about: jhsdk.jar and JHSDK.dll. Both of these files need to be your Glassfish’s path.

You can put them in

GLASSFISH_HOME\lib

or

GLASSFISH_HOME\domains\domain1\lib

If you deploy the jhsdk.jar file without the JHSDK.dll file, then you will receive the following error:

java.lang.UnsatisfiedLinkError: no JHSDK in java.library.path

At this point in the development process, my application provides a list of versions for a particular Harvest Package. The JCaVersion class does not implement java.io.Serialiable, so I was not able to bind it to my JSF component. So I wrote my own version of JCaVersion. I looped through my array of JCaVersions (which is returned from JCaPackage getVersionList()), and built an array of MyVersion instances with the same data. Then I could bind my array of MyVersion instances to my JSF component.

Finally, I deployed my WAR file and I was ready to go. I was so excited. WOW! That was easy! I’ll just deploy it on the Solaris box and I’ll be ready for show and tell. And……PRESTO!!! 3 weeks, 5 support emails to CA Support, a chat fight with my Sun admin, 50 meetings with my Harvest Admin later, it’s working!

Solaris Deployment

OS: Solaris 9

Application Server: Sun Java System Application Server 9.0 Update 1 (glassfish v2 ur1)

Harvest: AllFusion Harvest Change Manager 7.0

The first issue that arose was that the client was not fully installed on the Solaris box. Our app server and the Harvest server happen to be installed on the same machine, so the client should have been installed and available already. The key command-line utilities were there, and the HSDK and JHSDK are supposed to come with the command-line utilities, but they didn’t. So, we reinstalled the command-line utilities, and that set up all the files and directories we were needing.

Once we had the client installed, we needed to configure an environment for using the JHSDK. CA’s installation guide is pretty explicit, but I had trouble using it…perhaps because I’m not really that skilled with Solaris. Here’s what my env looks like:

JAVA_HOME=/usr/java
HARVESTHOME=/xxx/ca/harvest
CACRYPTINI=/opt/CA/CAcrypto/cacrypt.ini
CACRYPTDIR=/opt/CA/CAcrypto
DVHOME=/xxx/ca/pec/graphics/sun4_solaris
RTARCH=sun4_solaris
RTARCH_UC=SUN4_SOLARIS
RTHOME=/xxx/ca/pec
_app=/xxx/ca/pec/app-defaults
export JAVA_HOME HARVESTHOME CACRYPTDIR CACRYPTINI
export DVHOME RTARCH RTARCH_UC RTHOME _app
LD_LIBRARY_PATH=${CACRYPTDIR}:${RTHOME}/lib/sun4_solaris:${RTHOME}/graphics/sun4_solaris/lib:/usr/lib
LD_LIBRARY_PATH=${HARVESTHOME}/lib:${HARVESTHOME}/HSDK/lib:${HARVESTHOME}/JHSDK/lib:$LD_LIBRARY_PATH
PATH=${RTHOME}/bin:${HARVESTHOME}/bin:$PATH
export LD_LIBRARY_PATH PATH

I recommend following CA’s advice to test your environment with the sample JHSDK application as detailed in the Installation Guide. This will tell you whether or not you were successful.

The next step is to configure Glassfish. This is where it gets weird. Even though we’ve setup all this path info in the environment, we have to do it again in Glassfish. My guess as to why? The Java EE environment needs to know the paths to the native libs so the when the JHSDK classes are called, then can know where to find their C++ peers. The user environment needs to know the paths so that when when one of the native C++ classes is called, it knows where they are and where Harvest is. Again, that’s my best guess. If I learn different, or if you know different please tell me and I will give an update.

So here’s what my Native Library Path Suffix in Glassfish looks like:

:/xxx/ca/harvest/lib:/xxx/ca/harvest/HSDK/lib:/xxx/ca/harvest/JHSDK/lib:/opt/CA/CAcrypto:/xxx/ca/pec/lib/sun4_solaris:/xxx/ca/pec/graphics/sun4_solaris/lib:/usr/lib

Here’s what my Classpath Suffix looks like:

:/usr/java/jre/lib:/usr/java/lib:/xxx/ca/harvest/lib:/xxx/ca/harvest/HSDK/lib:/xxx/ca/harvest/JHSDK/lib:/xxx/ca/harvest/JHSDK/lib/jhsdk.jar

Look for future posts here on my use of JHSDK in my Java EE application. The journey has only begun…

Ok.  This stuff is NOT easy.  No problems on Windows platform, but Solaris is a whole ‘nother ballgame!  I don’t really want to publish anything until it is working.  I’ll give you a nice guide to JHSDK in the enterprise environment when all my issues are resolved.  CA Support has been helping me get through this, and I expect to have a breakthrough any day now.

The primary issues revolve around configuring my Glassfish environment to recognize all the C++ libraries that accompany the java toolkit.

Sun?!!!  If CA can’t get me through this then you’re next!  I will be knocking on your door to get some help even I have to PAY for it!

It appears that the bean classes in JHSDK  such as JCaVersion and JCaPackage do not work well in my Glassfish web container.  In fact, my app server just blows up.  It gives no errors or warnings in the log. 

Maybe it has something to do with the dependence on a DLL.  I’m not sure.  It runs fine until I try to use the bean in the JSF page.

Fortunately, I have a work around.   I wrote my my own version of JCaVersion.  I loop through my array of JCaVersions (which is returned from JCaPackage getVersionList()), and build an array of MyVersion instance with the same data.   Then I can bind my array of MyVersion instances to my JSF component. 

Java Harvest SDK (JHSDK) is not just a library of helpful Harvest-related classes, it has a very specific focus. JHSDK is for building a custom Harvest client. JHSDK serves as your proxy for interacting with Harvest. The very first thing your Harvest client has to do is log in to Harvest…duh. Your client can do absolutely nothing until it’s logged in.

The first class that you need to become familiar with is com.ca.harvest.jhsdk.JCaHarvest. This is your application’s key to the wonderful world of Harvest. The Javadoc says “This is the main Harvest object used to set up a session and generate a context. ” The session is your live, authenticated access to Harvest. And if JCaHarvest is the key, then JCaContext is the java representation of the world itself. More about JCaContext later. Let’s login to Harvest.

  1. Import your JCaHarvest class
    import com.ca.harvest.jhsdk.JCaHarvest;
  2. Create a reference to a JCaHarvest class
    private JCaHarvest harvest;
  3. Instantiate JCaHarvest with your broker name
    harvest = new JCaHarvest("mybroker");
  4. Call login method with user name and password returning int to check status of the login
    int rtn = harvest.login(”myusername”, “mypassword”);
  5. If the return code is zero, then login succeeded. If it’s not zero, then the login failed and you get can getLastMessage() to get the error message.

So your login method my look something like this

fig17.jpg

Once you have an authenticated JCaHarvest object, you have the functionality of Harvest in your java application! Pretty powerful!

In an enterprise application, you want to consider how to manage your JCaHarvest reference(s). Logging in is a pretty expensive call. You probably don’t want to create a new instance or perform a new login with every call to the system. So far, my plan is to

  1. create a pool of shared Harvest sessions for read-only gestures
  2. prompt the user for their login when they need to perform some non-read-only operation (ie checkin or a checkout for update)
  3. cache their Harvest session in the Session scope

Check back with this category for future blogs documenting the success (or failure) of this technique for managing Harvest sessions in an enterprise application. My Harvest administrator and I have been discussing this technique and we believe it will work.

Our organization uses a Computer Associates product called CA Software Change Manager to manage change on code and documentation.  It used to be called Harvest (much easy to say), so please excuse me, CA, if I go ahead and refer to it as Harvest from this point forward.  It’s a very robust and very extensible CM platform.   In the past, I’ve built custom extensions for Harvest for our division using SQL and a set of command-line utilities that ship with the product.   I’ve been aware for some time, however, that CA also ships the Java Harvest SDK.  This is supposed to be the best way to extend and integrate with Harvest.

 Here’s a picture of my proposed architecture.  Notice where the JHSDK fits in with it.

fig17.gif

First major issue I will have to address:

Harvest connection management.  JHSDK has a class called com.ca.harvest.jhsdk.JCaHarvest that represents an active session with the Harvest application.  My plan is to pool some instances of these classes with a generic webuser account for browse/read-only stuff, but make them authenticate when they need to checkin a new file or checkout a file for update (thereby creating new JCaHarvest instances with their specific logins).

This is an exciting bit of development for me!   This wouldn’t be a bad topic for a CA World conference.  First things first, let’s get this thing working!

Eclipse launches quickly.

Eclipse crashed 6 times.  3 times in the Database Development perspective and 3 times in the JPA perspective.  I’ll see about tracking the actual sequence of events and errors in the future, but I just didn’t have the patience yesterday to do anything but throw immature little hissy fits.  I still haven’t successfully used the JPA “Generate Entities” function.

I learned that you have to run an update on the Data Tools Platform in order to set up database connection profiles properly.

I like the concept of perspectives, but I’m still getting used to them.

I question whether JBoss Tools is going to give me a proper means of comparing with Netbeans.  I’m thinking seriously of purchasing JBoss Developer Studio.  After 1 day of trial, I haven’t even touched the JSF stuff.  I’ve spent most of my time installing plugins, updates, and trying to figure out what I’m doing wrong.

Not a stellar start, but I’m trusting in the multitude of Eclipse fans out there to have a good reason to love this development platform.

Choices we’ve made so far:

1.) Swing or JSF? We chose JSF

2.) JPA or Stored Procedures? We chose JPA.

3.) Netbeans with Woodstock or JDeveloper 11g with ADF Faces? We eliminated JDeveloper 11g.

Our final choice is between Netbeans with Woodstock or JBoss Studio Developer with RichFaces. My coworker, Hobi, and I both developed prototypes. He used RichFaces and I used Woodstock. He chose not to use an IDE for his coding, I chose to use Nebeans Visual JSF. We both had good experiences and we both admired each others’ results. Because my team is mostly coming from the Powerbuilder context, I am insisting that whatever JSF implementation we choose, it must be well-supported by an IDE. In my experience, visual interfaces are best designed with visual development environments. I spent years designing Swing GUIs without a visual designer, and when I began using Matisse (Netbeans GUI Builder) my productivity and design improved dramatically.

So, our next logical step is to tryout JBoss’s brand new but supposedly relatively mature Developer Studio 1.0. It should be relatively mature because it is built on the Eclipse IDE platform and Exadel (which was at version 4 before they open-sourced and joined with Redhat and JBoss). Rather than pay the $99 to tryout Developer Studio, we’ve opted to use the JBoss Tools 2.0 Eclipse plugin (which is supposed to be exactly the same).

If we find that JBoss Developer Studio is as good an IDE or better than Netbeans for developing JSF with JPA, then we will probably go with JBoss. We both like the idea of using Facelets/XHTML instead of JSP, and we’ve both found RichFaces widgets to be more responsive because of the heavy use of AJAX (which we also like). So it comes down to the tools.

This will not be an easy choice. Netbeans 6.0 is considered by some to be the most competitive release of Netbeans ever, on a par with Eclipse. I’m also emotionally attached to Netbeans, having used it since before 3.6.

More to come…

When you create an Entity Class in Netbeans 6.01, you have to choices:

  1. New –> Entity Class
  2. New –> Entity Class from Database

Choosing “Entity Class from Database” brings up a wizard to choose which database table you would like to map. If your Netbeans project is a Web Application, you get a list of Data Sources from which to choose. It shows all the JDBC Resources that are configured in your application server. Piece of cake. You’re good to go.

fig13.jpg

This is great if you’re setting up your data model inside your web application. However, if you are setting up your data model in a Java Application project (like in the tutorial), you get the list of Database Connections that are configured on your Netbeans Services tab under the Databases node.

fig14.jpg

Perhaps Netbeans has a easy/slick way of switching from Database Connection to Data Source mode on this wizard, but I haven’t found it yet. Here’s my workaround:

1.) Go ahead and select your Database Connection and complete the wizard

2.) Open persistence.xml in XML mode

3.) Remove the following properties from the properties tag:
<property name=”toplink.jdbc.user” value=”app”/>
<property name=”toplink.jdbc.password” value=”app”/>
<property name=”toplink.jdbc.url” value=”jdbc:derby://localhost:1527/sample”/>
<property name=”toplink.jdbc.driver” value=”org.apache.derby.jdbc.ClientDriver”/>

4.) Add the following tag after the provider tag

<non-jta-data-source>jdbc/sample</non-jta-data-source>

Then, we you drop the jar file for your JPA model into your web application, it will know to access the database through with a JNDI lookup at runtime.

2 cents from a RAJP:

cent 1

If you need to use this persistence unit (PU) in a web application, you ought to be using a data source (no question about it!). If you need to use the PU from a Java SE application as well, then set up two persistence units: 1 for the web that uses a Data Source and 1 for the SE app that uses a Database Connection. I haven’t tested this out, but it seems feasible.

cent 2

DO separate your JPA data model into a separate Netbeans Java Application project.  Don’t build your model in your web application.  You want a clear separation between the web tier and the persistence tier.

2 cents is about all this is worth because I’m a JPA newb.

Next Page »