Tuesday, April 5, 2011

Getting better data for testing

I learned something neat the other day that I thought was worth writing about. I write a lot of unit test code to test the code I am writing. Since I use an ORM, I am able to create the persisted 'objects' in memory using mock factories. These are great because you can do something like
MyObject object = MyObjectMockFactory.create(EntityManager)
object.setProperty(blah);

and then use it in my testing and do something like
assertEquals( expectedValue, object.getProperty);
This is great. I especially enjoy using all that MockFactory based magic to create proper data structures in memory. All the relationships between tables in the database are created properly. There is a slight drawback to this approach though. Say you have an object that you are interested in testing. It is related to 20 other objects that you need to exist for your test. Now, you have to create all those objects, associate them properly so that you can use it in your test. Except you don't care about those objects. You just want them to exist. This starts to get annoying after a while. Imagine the object you are interested in is also relevant to many other classes and tests. All of a sudden, everyone has to create that object and its associated objects over and over for their unit tests. This gets painful (and inconsistent) quickly.

So how can we make this better? One solution I came across was DbUnit. To make this really effective though, I ended up using Jailer to extract the data and use it using DbUnit to do the tests. Jailer is really neat. It allows you to model the data structures you care about, filter it and export it in a DbUnit compatible flat file. Once that is done, you use DbUnit to load up the DbUnit xml files, create the structures in HSQLDB and you're off to the races.

The benefit to using Jailer is that you can have consistent data sets for multiple tests that multiple people can now use without having to build up all those 20 objects one at a time and associating them. All that stuff is now taken care of by a couple of calls to the DbUnit API. 

There are down sides to it for sure. In my case, I have to test for some data that doesn't exist or doesn't match up. That is hard when all the data is exported from a consistent database. But you can doctor that after the model is loaded up. You also need to have representative datasets. As in, if you expect 10 types of orders to be in the database for your tests, the exported data better have that. People also need to know what the data stored in the XML files so that they can use them in the appropriate manner.

I really do like not having to generate tonnes of data artificially; rather, it makes sense to get the data that already exists, plunk it into the model and get on with testing.  And this can be extended to large regression testing models. Generate the model, understand it and add more. OF course, you don't want to bloat your DbUnit tests with large data sets... but you can if you want to I suppose.

Sunday, March 6, 2011

COBOL!

That's right. COBOL. I am learning COBOL. Its a long story as to why. All I can say is, there are some amazing programmers out there who are retiring now who have written some awesome COBOL programs. It is something of a wonder that so much in life that I took for granted runs on COBOL. And until this week,  I had no idea how much of what's out there is dependent on COBOL and other old languages.

From DMVs to supply chains, lots of things run quietly in the background, making life function. A lot of it is not running today's technology; rather, it is running on mainframes with code written years ago. Food for thought eh?

Sunday, February 27, 2011

Why can't I start JBoss on my Linux machine

So, I've been fiddling about JBoss recently with the intention of doing things with EJBs. To do so, I installed the JBoss 6 application server on Windows 7 and Linux (Ubuntu). JBoss starts fine on both environments via the standalone
$JBOSS_HOME/bin/run.sh
script. I think I had to set the JBOSS_HOME variable on Windows, on Ubuntu, either JBoss knows to look in /usr/local/jboss (where I installed it) or it doesn't care about the JBOSS_HOME variable.


What I am having a problem with is the inability to start JBoss from Eclipse on my Linux environment. For whatever reason, JBoss 6 is not one of the server options in Eclipse, so I used JBoss 5 instead. Doing this sorted out the startup and shutdown of JBoss from Eclipse on my Windows environment. No such luck on the Linux one.

It kept trying to start up and I get this error:


In the Console, the only error I see is this:

02:49:50,294 ERROR [AbstractKernelController] Error installing to Instantiated: name=PostEjbJarMetadataDeployer state=Described: java.lang.NoSuchMethodError: javax.annotation.Resource.lookup()Ljava/lang/String;
    at org.jboss.metadata.annotation.creator.AbstractResourceProcessor.createResourceEnvRef(AbstractResourceProcessor.java:394) [:2.0.0.Alpha24]
    at org.jboss.metadata.annotation.creator.AbstractResourceProcessor.process(AbstractResourceProcessor.java:237) [:2.0.0.Alpha24]
    at org.jboss.metadata.annotation.creator.AbstractResourceProcessor.process(AbstractResourceProcessor.java:163) [:2.0.0.Alpha24]



I tried changing the timeout for startup (double click on the JBoss Server in the Servers tab > Timeout > Start (in seconds) to 120) and that seemed to have done the trick. If you run into this, give that a try. It boggles my mind that JBoss takes longer than 50 seconds to start!

Sunday, November 7, 2010

Darn it JSPs!

I learned something really neat... well not so neat about JSPs and how they get compiled.  Say you have something like this:

<% if (request.isUserInRole("user")) { %>

<p>Hey, let's do something with this user role business</p>


<% } %>
<% else if( request.isUserInRole( "guest" ) ) { %>

<p>Let's do something with the guest role </p>

<% } %>

You would think it would work. There's an if statement, then an else if statement... Except, when the JSP compiles, it looks like so:


if (request.isUserInRole("user")) {
      out.write("\n");
      out.write("\n");
      out.write("
<p>Hey, let's do something with this user role business</p>\n");
      out.write("\n");
      out.write("\n");
 }
      out.write("\n");
      out.write("\n"); 
else if( request.isUserInRole( "guest" ) ) {
      out.write("\n");
      out.write("\n");
      out.write("<p>Let's do something with the guest role</p>\n");
}
 Because of those newlines, the if/else if doesn't look right and it throws errors when you run. The only way I was able to get it to work was to put the close brace and the else if in the same statement:

<% } else if( request.isUserInRole( "guest" ) ) { %>

Once that was done, the thing compiled properly and worked fine. A neat little thing to keep in mind when throwing scriptlets in the JSP.

Monday, October 25, 2010

Why can't I view JSPs on my Linux box?

This is a bit insane I must say. I have the following setup: Eclipse Helios, 64-bit JDK (1.6.0_21), Tomcat 6 (6.0.29), and a pretty straightforward JSP that does nothing other than evaluate the date.

I get this crap all the time:

javax.servlet.ServletException: java.lang.NoClassDefFoundError: javax/el/ELResolver
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:268)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
test.test01.MainServlet.goToPage(MainServlet.java:50)
test.test01.MainServlet.doGet(MainServlet.java:36)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)


root cause


java.lang.NoClassDefFoundError: javax/el/ELResolver
java.lang.ClassLoader.defineClass1(Native Method)
java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
java.lang.ClassLoader.defineClass(ClassLoader.java:616)
java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
java.net.URLClassLoader.access$000(URLClassLoader.java:58)
java.net.URLClassLoader$1.run(URLClassLoader.java:197)
java.security.AccessController.doPrivileged(Native Method)
java.net.URLClassLoader.findClass(URLClassLoader.java:190)
sun.misc.Launcher$ExtClassLoader.findClass(Launcher.java:229)
java.lang.ClassLoader.loadClass(ClassLoader.java:307)
java.lang.ClassLoader.loadClass(ClassLoader.java:296)
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
java.lang.ClassLoader.loadClass(ClassLoader.java:296)
java.lang.ClassLoader.loadClass(ClassLoader.java:248)
org.apache.jasper.runtime.JspFactoryImpl.getJspApplicationContext(JspFactoryImpl.java:209)
org.apache.jsp.WEB_002dINF.jsp.search_jsp._jspInit(search_jsp.java:22)
org.apache.jasper.runtime.HttpJspBase.init(HttpJspBase.java:52)
org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:159)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:329)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
test.test01.MainServlet.goToPage(MainServlet.java:50)
test.test01.MainServlet.doGet(MainServlet.java:36)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
 I have checked everything I can think of (JAVA_HOME, CATALINA_HOME variables) and all check out okay. The project in eclipse is a dynamic web project and has all the $CATALINA_HOME/lib jar files in it including the el-api.jar file.

So what gives? The real annoying thing about this whole process is that I can export the war file, pop it onto my windows machine and it works just fine! I tried doing the same with Tomcat on Ubuntu and running it from there directly but am no better off. So, anyone know what the heck I am doing wrong?

Thursday, June 3, 2010

Dynamic graphing in the web world

Instead of studying for my midterm, I am sitting here wondering if there is a way to create and interact with dynamic graphs in the web-based world. I don't know of too many things that are even out there that behave in the manner I envision, apart from perhaps the charts in google finance.

What I want to accomplish can be done using Swing and Java. I suppose I could create an applet that allows you to interact with the data and do things with it. My main motivation for having the ability to interact with data is the following use-case. 

Where I work, we use an HP tool called LoadRunner. It has a fairly useful (if sometimes annoying) tool called LoadRunner Analysis. This tool allows you to dynamically select regions of the various graphs it displays to the end user and then does stuff (in this case, updates the data you see to align with the regions of the graph you selected). Data it presents includes things like averages of whatever you happen to be looking for on the graph, max, mins, that sort of thing. 

We also have similar data externally. One example is the verbose GC logs of the JVM we use. It would be useful if I could find a way to graph the data in a reasonable manner and then interact with it by highlighting regions of interest and then finding out for example when the last full GC was or what the average time is between two young GCs or how much space on average is gained after a full GC in that selected time-frame. 

I suspect something like the dynamic 2D graphs that google finance uses would be sufficient to do most of this work, but I have never seen it used anywhere else before. So, does anyone know what I am talking about and how to go about implementing it?

Friday, February 12, 2010

Trying to use the Java plugin in Firefox

I've been trying forever to get the Java plugin to work on Firefox on Linux. There is an Ubuntu specific way to do it but I don't want to use apt to install it. My JDK is installed in /usr/local/jdk1.6.0_18.

So how do I do it? Used to be, you could go into the mozilla/plugins folder and you link the libjavaplugin_oji.so from the jre/plugins folder. Except no such file exists on my installation of the JDK. After searching on google and looking at official documentation from Oracle/Sun, I saw others have it... but not me. Turns out that my JDK is 64-bit and the setup is different. From one of the Oracle/Sun forums, I noticed that the name and path to the plugin are now different on the 64-bit version of the 1.6 JDK.

So, in my case, the plugin is located at
/usr/local/jdk1.6.0_18/jre/lib/amd64/libnpjp2.so
and by creating a symbolic link to it in ~/.mozilla/plugins, I have access to the Java plugin now. I needed that to use webex on my Ubuntu machine.