<%@ Page Language="VB" MasterPageFile="~/MasterPage.master" AutoEventWireup="false" Inherits="TSPage" title="Java One Journal - Volume I - Issue V" MetaDescription="Notes from the 2002 Java One conference by Little Rock, Arkansas-based software developer and consultant, Terry Smith." LocalStylesheet="stylesheet.css" PageDate="March 29, 2002" %>
Unit Testing Made Easy: Design Principles to Facilitate Testing
Using ClassLoaders to Support Better Design, Security, and Hot Swapping of Components
Using java.awt.Robot to Measure Performance, Capacity, and Reliability
Extreme GUI Testing: A Guide to Using the Project "JFCUnit" and HTTPUnit Extensions
Recommendations for Conference Attendees

Unit Testing Made Easy: Design Principles to Facilitate Testing

I'm in the cafeteria watching this session on video simulcast. For you, the reader, this means you won't get any notes until I finish eating my muffin. ...(minutes pass)... Now I'm on my second muffin. There's some code on the screen. If you've seen Java code before it looks very similar to that code. Squint. Yes, it is Java code.

OK, my muffins are down now so let's begin.

This is supposed to be a great article on testing JDBC code:

http://www.mockobjects.com/papers/jdbc_testfirst.html

For multi-threaded code the speaker recommends using Doug Lea's concurrency utilities. See my notes from Doug Lea's talk earlier in the week. "If you have multi-threaded code just start with Doug Lea's libraries to begin with."

For testing GUIs first make sure you break up your code into MVC. "A class should do one thing an do it well." Seems like I've heard that somewhere before.

This is supposed to be a great paper on unit testing your GUIs:

http://users.vnet.wwake/xp/xp0001/index.shtml

Be careful with singletons, specifically with who calls getInstance(). Have limited places where singletons are created and pass them into constructors for your objects. Then your unit tests can replace or subclass the singletons if they need to.

This article discusses the issues of singletons in much more detail:

http://www-106.ibm.com/developerworks/webservices/library/co-single.html

Mock Objects are separate inner classes just for testing. You can set them up to throw exceptions on certain method calls to give you better coverage on your unit tests. They can provide canned data so that your unit tests can run in isolation from your database Check out this URL for more information:

http://www.mockobjects.com

(Note to self: Find a lot of good Java articles on the web, steal their ideas, throw together a few slides, and present at JavaOne.)

"Surface of a class has cutouts that fit interfaces or common data classes." I think this dude had too much sugar in his coffee this morning. Next, he started talking about exposing his composition. The rest isn't really fit to print in this high-quality publication.

Of course, XP says to write all your unit tests first:

http://www.extremeprogramming.org

The speaker also promotes thinking of the unit tests as part of the documentation.

"Write good unit tests and your design will improve."

Using ClassLoaders to Support Better Design, Security, and Hot Swapping of Components

Most of the components that I've seen could use a lot of hot swappin'. Better design is often useful too. Once again, this session is in one of the largest rooms and it's completely packed. A lot of people, included myself, are sitting on the floor. However, I'm one of the upper-class floor people having a wall to lean back against, a clear view of the one of the big screens, and finally a plug-in for my laptop. Life is good.

The speaker is Ian Griffiths, CEO of Yellow-B (just when you thought all the bad company names were taken), and head of the Java Methodology department.

Class loaders are responsible for loading classes. Class loaders can be structured as trees. Each class loader delegates requests to its parent before trying to satisfy it. This is called the "parents-get-satisfied-first methodology". Class loaders read classes from the file system, the network, or generate byte code on the fly.

Class Loaders were introduced with JDK 1.1 but like everything in JDK 1.1 they were difficult to use. JDK 1.2 introduced features which made them simple to program. The JDK 1.4 release introduced something-another to make exceptions easier with class loaders but I missed what he said it was.

Enough filler. Here's some code:

ClassLoader classLoaderA = new MylassLoader();
Class classB = classLoaderA.loadClass("B");

MyInterface b = (MyInterface)classB.newInstance();

b.doSomething();

There are three class loaders that ship with Java 2: java.net.URLClassLoader (light-blue on the slide) inherits from java.security.SecureClassLoader (orange on the slide) which intern inherits from java.lang.ClassLoader (red on the slide).

You can roll your own class loader by copying this code:

class DecryptingClassLoader extends ClassLoader
{
   String key;

   DecryptingClassLoader(String key)
   {
      this.key = key;
   }

   public Class findClass(String name)
   {
      byte[] b = loadClassData(name);
      return defineClass(name, b, 0, b.length);
   }

   private byte[] loadClassData(String name)
   {
      // load the class data and decrypt it
      ...
   }
}

The speaker followed with showing an XML file from his company where they map class loaders to stuff. I couldn't tell if the "stuff" were individual class names, jar files, or "actions" of some sort.

Now we get to the hot swappin' of classes. His explanation was very brain dead. For class D you first get rid of all instances of class D. This is at runtime. Once that's done the existing class loader for class D will be garbage collected next Wednesday morning. Then you can have a different class loader that reloads a class. This was exemplified with the stupidest, crappiest demo of all demos at this year's conference.

URLClassLoader loads classes and resources from a search path of URLs referring to both JAR files and directories. It's useful, so remember it.

JDK 1.4 as introduced assertions and your can change their default behavior in your class loader :

void setDefaultAssertionStatus(...)
void setPackageAssertionStatus(String pakageName,
                               boolean enabled)
void setClassAssertionStatus(String className,
                             boolean enabled)
public void clearAssertionStatus()

JSR-121 is for Application Isolation. This is for creating a subprocess within the same JVM.

Using java.awt.Robot to Measure Performance, Capacity, and Reliability

Before the talk as people are still coming into the room the speaker has a demo running on the big screens showing a very decent looking Swing GUI going through automated testing. Fields are plugged, records are accessed, and things flash on the screen in Commander Data speed-daemon fashion. The speaker seems like a real developer from a company that does real work. In fact, he is. This should be a cool talk.

He's from Automatic Data Processing (ADP) in Atlanta. ADP started their development of their middle tier server in 1997 before commercial Application Servers were available. They wrote their own. Their system has to scale from a laptop sales demo to a processing center.

The Robot class was added to J2SE in 1.3. It's an easy-to-use class that generates native mouse and keystroke events. The speaker's company wrapped it to use simple "testing scripts" implemented as Java classes. TestRobot is part of their framework and wraps java.awt.Robot to provide extra features that facilitate writing load generators.

They have a Swing client that talks HTTP with compressed serialized objects (their own brew) to the server which then talks JDBC to their database. Their business logic is some type of 4GL language that's stored as metadata. No more specifics were given.

The speaker switches from his slides back over to his robot that is still running. Their application is a Human Resources Management System. Their dialogs are built at runtime using metadata. In one course-grain call they bring back the metadata to describe a panel and the data for the panel. Next the speaker demonstrates the keyboard navigation for his application which besides being good for usability makes it much easier to write Robot scripts.

The application has a Robot menu (of course normal users don't see this) for choosing and configuring tests. One of the dialogs available from it configures the number of repetitions, the number of rows to access, etc. This is their Read/Write robot that puts a load on the server by doing reads and updates constantly on database rows.

The next robot is the Client Load. You can set the number of repetitions, the number of panels to display, and the number of tabs to tab-in on each panel.

They have another applet which is a Server Management Console. It displays the number of calls to the server, the number of rolling, average, and maximum response times, and much more. You can click on one of this dialog's rows to see similar time breakdowns for each panel (or GUI screen). A lot of other stuff is also displayed.

Their TestRobot class is a singleton. It can't run on the system's EventQueue thread and still fire off all the Swing events that it needs to, so it inherits from the Thread class. A static function called execute(…) on TestRobot is passed a TestRobot.RunInterface. The run() method on TestRobot is called to actually run the test case. TestRobot.RunInterface has two methods:

boolean runDialog(TestRobot);
void runTest();

The RobotRW class, for the Read/Write test, implements RunInterface.

The TestRobot thread can produce events very quickly. It can't produce the next event until the EventQueue is ready for it. Robot.setAutoWaitForIdle() is called to wait before issuing another robot instruction. It's implemented using SwingUtilities.invokeAndWait(Runnable).

The TestRobot framework will provide the time that a test took. The speaker's company runs repeated trials at first so that they build up their caches at the Swing client, the app server, and the database levels. It also takes awhile for the JIT to kick it. After everything levels off you can do a fair test.

For serializing objects over sockets they use OutputStream -> FilterOutputStream (deflater) -> ObjectOutputStream. java.util.zip.Deflater is used for deflation.

The speaker showed some very cool graphs showing the results of running their robot tests on different server configurations, different JVMs, etc. Running under 1.3.1 -classic is 2.5 times slower than 1.3.1 -server for their application. There's not much different running between 1.4 -server and 1.4 -client.

They use their tests to determine how big their server should be and to benchmark a server configuration. They measure RPCs per minute and average response time.

These URLs tell more about tuning for Hot Spot:

They ran their robot tests with different heap size settings on the JVM using these:

A. JVM defaults
B. -Xmx192m and -XX:MaxNewSize=64m
C. -Xmx128m and -XX:MaxNewSize=(missed this number)

The MaxNewSize parameter sets the portion of the heap size for new, small objects.

They have started an automated test on Friday night long enough to run all weekend with 500,000 server calls. As a result of this stress testing, they have had systems running for months without needing maintenance.

This was a very good talk and highly informative. The speaker had real experience and knew what he was talking about. Demoing his company's real application instead of a dumbed-down demo was a major plus. The author's system is not open source, and in the Q&A session he said he might look into that, get permission, etc. Someone in the audience mentioned something about an open-source project named "Gemmy" (I think that's it anyway). I went to the microphone and told the speaker that it seemed like he had to invent his own JUnit-type framework on top of java.awt.Robot, and did he agree with my comparison? He didn't understand my question, thinking the subject was still on "Gemmy" (or whatever) which he didn't know anything about. After lunch, I noticed that my next scheduled session was on JFCUnit.

Extreme GUI Testing: A Guide to Using the Project "JFCUnit" and HTTPUnit Extensions

The speaker started with a decent introduction to JUnit which I won't bother repeating here. There are several decent tutorials on the web which would be much better for you to read instead. (Go to http://www.junit.org) JUnit is great for testing Java classes but it can't test web pages.

HTTPUnit extends JUnit to allow automatic testing of Web sites. It emulates a web browser, including form submission, basic HTTP authentication, cookies, milk, and automatic page redirection. It provides methods to examine returned pages as text, and XML DOM, or containers of forms, tables, and links. HTTPUnit parses HTML using a program called Tidy brought to you by the makers of Tidy-Bowl.

Note that HTTPUnit can't create tests that use JavaScript. In other words, it will not run any of your JavaScript code, so you might as well go ahead and delete it.

The classes WebConversation, WebRequest, and WebResponse are used to retrieve web pages.

The pages can be examined by:

Here is some code:

public void testWelcomePage() throws Exception
{
   WebConversation convs = new WebConversation();
   WebRequest request = new GetMethodWebRequest
      ("http://localhost:9090/httpUnitDemo");
   WebResponse resp = resp.getResponse(request);
   WebForm form = response.getForms()[0];
   Request = form.getRequest();
   Request.setParameter( "username", "Tom" );
   ...
   response = convers.getResponse( request );
   ...
   WebTable flightTable = response.getTables()[0];
   TableCell tcell= flightTable.getCell(0,0);
   ...
   WebLink link = response.getLinks()[0];
   ...

JFCUnit extends the JUnit test suite for Swing applications. JFCUnit provides the JFCTestHelper class that allows test methods to find components of a Swing application. JFCUnit provides a way to manage the awtThread so test methods do not interfere with event processing. It's presently in Beta release.

JFCTestHelper provides the following methods:

findButton(String, Container, int);
findJLabel(String, Container, int);
findNamedComponent(String, ontainer, int);
findNamedComponent(String, Class, Container, int);
findComponent(Class, Container, int);
findComponent(ComponentFinder Container, int);

JFCUnit provides two methods to manage the AWT Thread. awtSleep() and awtSleep(long sleepTime ). The first defaults to 100ms. These don't force the AWT thread to sleep; rather, they make your test case sleep until Swing is done doing its stuff.

Yet again, here's some more code:

public class JFCUnitDemoTester extends JFCTestCase
{
   private JFCTestHelper helper;
   private static Boolean winCreated = false;
   private Window appWindow;
   private JTabbedPane tabbedPane;

   public JFCUnitDemoTester(String name)
   {
      super(name);
      helper = new JFCTestHelper();
      if( !winCreated )
      {
         String[] stringArray = new String[1];
         JFCUnitDemo.main(stringArray);
         ...

See his slides for more code examples.

The speaker ran a Swing GUI and demoed using JFCUnit to test it, but it wasn't nearly as awesome as the previous speaker's demo (using his own framework) because he used a very naïve sample GUI to demo with. A real application for the demo would have been much more effective.

Well, that was all the content for this session. Try browsing these sites if you really want to learn something:

Recommendations for Conference Attendees

I've attended many software development conferences over the past few years, so I thought I'd list some suggestions based on my experience. These are for conferences in general and are not specific to JavaOne.

Picking good speakers is a crap shoot. In my experience the best talks are given by real developers with real experience. Consultants give you a decent chance at learning something because they generally do real work (well most of the time), but be wary of those (consultants and otherwise) who write too many books or who have titles like Chief Software Evangelist and Chief Methodologist. Managers also sometimes give talks and you want to avoid them like the plague. Talks given by engineers from big companies like Sun, IBM, and the like are fine for finding out what APIs are coming out next, what's going to be in the next release, and similar information that's nice to know and to research when you get back home. Just don't expect to learn anything profound or applicable to what you do everyday. There are also a tiny minority of speakers who are extraordinarily entertaining and who you should see no matter what their lecture topic is. Scott Myers, Allan Cooper, and Jared Spool are good examples. They will always teach you something even if it's the level of your own ignorance.

In light of the above, always have an exit plan. One of the best methods is to try to always sit at the end of a seating row. If a talk is bad, go to another one or go to the show floor and let the salespeople fall over themselves trying to interest you.

Speaking of sales people on the show floor, it's always fun to act dumb at first, listen to their spill, then based on that ask them an extremely hard question that they're very unlikely to have an answer for, and then walk away. The trick is to stump them good enough to leave them starring into space long enough to allow you to grab a couple of handfuls of vendor booty off their tables before they wake up to their sad reality of an existence.

Don't hesitate to schedule two, three, or even four classes in the same timeslot and then makeup you mind five minutes beforehand. In the nerd lifestyle this is called "living on the edge".

Take a laptop to type notes. Even if you're not a fast typist chances are you're not buying yourself anything trying to scribble down notes as fast as you can on paper. You may think you're going to type them all up when you get back home, but you're not.

If you've read an entire book on a certain topic, you generally will not get anything out of attending a session on the same topic. Most speakers (certainly not all) assume their audience is made up of total idiots. Even if you do get an interesting tidbit of information out of one of these sessions it will only be after listening through thirty minutes of material that you already know. Devote a good percentage of your classes to topics which you know absolutely nothing about. Your expectations will be low, and you will probably learn something.

Make a mental note of everyone else's ignorance for your own personal peace of mind. This is a goal you can take into any conference and always be successful with. It's crystal clear at these conferences that everyone else around you is at least as clueless as you are and often more so. It's also interesting to watch how the industry's big-wig developers with high notoriety generally seem to know this and often alienate themselves to corners of the universe and do their best not to play with others. It's not hard to see why. If there's anything you can get out of all of this, it's knowing that you are not alone in not knowing what the answers are and, in fact, if you have the slightest idea of what the questions are then you are already vastly ahead of everyone else.

Previous ] [ Index ]