Feb 24 2008

Introduction to Classes and Objects

I often get asked to explain the difference between a Java class and an object. A common way to describe a Java class is to think of it as a blueprint, cookie cutter, or factory used to create objects with. A class defines the implementation details, the fields and methods to store the state and execute the behavior of objects. In contrast, an object is an instance of a class. There can be one or many object instances for a given class but there is only one class for a given type. A common example of object state is that when you have an ArrayList, the list has a size. The ArrayList also has a certain behavior, to increase by one element and update the list size, when you invoke the add method. The size and contents are the state of an ArrayList, and adding and removing elements is its behavior.

In addition to declaring and implementing the fields and methods, state and behavior, for a object, a class can also define methods that don’t logically belong to a single object instance but that belong to the class type itself. Methods that belong to the class are marked as static. A common example of static methods are those in the Math class. You can’t create a object instance of the Math class, the default constructor is private. Since you can’t instantiate an object, all the methods it declares are invoked at the class level. To invoke the absolute static method made available in the Math class you do so by the following example.

[source:java]
int abs = Math.abs(-10);
[/source]

Here is how you would access the static PI field in the Math class.

[source:java]
System.out.println(“PI: “+Math.PI);
[/source]

Technorati Tags: , , , , , ,


Feb 24 2008

Class Loading Error

The Java language specification dictates that static fields and blocks are initialized the first time a class is loaded, from top to bottom. So my coworker was utterly dismayed when a static hash map in a certain class was getting a new object instance each time he requested an instance of said class. At first I was taken back by the problem as he described it, I thought maybe the object was serialized or marshaled, maybe it was programmer’s error and he had set a new map to the static field in some other setter method, then I remembered that this piece of code uses a new URLClassLoader instance each time it tries to load this particular class. This new class loader was used because we load this class dynamically at runtime as a external plugin. To fix this bug we just keep and used the same class loader instance each time we loaded this plugin class.

Class loaders are fun but this is one example of how if used incorrectly can lead to interesting behavior. These are the type of bugs that reminds me of those Java Puzzlers.

Technorati Tags: , , , , , ,


Feb 13 2008

JavaOne 2008 Sessions

I was reading over the descriptions for the currently scheduled sessions for JavaOne 2008. Here is a short list of the sessions that seem interesting to me in no particular order.

  • BOF-5110: Extending Groovys Swing User Interface in Builder to Build Richer Applications
  • BOF-5998: Meet the Java Posse
  • BOF-6229: Cutting-Edge Productivity with RIFE and Web Continuations
  • PAN-5435: The Script Bowl: A Rapid-Fire Comparison of Scripting Languages
  • TS-4806: JRuby on Rails: Web Development Evolved
  • TS-4868: From Java Technology to Ruby…and Back
  • TS-4895: The NetBeans IDE Compared to the Eclipse Rich Client Platform
  • TS-4982: Extending Swing: Creating Your Own Components
  • TS-4986: JavaScript Programming Language: The Language Everybody Loves to Hate
  • TS-5152: Overview of the JavaFX Script Programming Language
  • TS-5165: Programming with Functional Objects in Scala
  • TS-5416: JRuby: Why, What, How…Do it Now
  • TS-5572: Groovy, the Red Pill: Metaprogramming-How to Blow the Mind of Developers on the Java Platform
  • TS-5579: Closures Cookbook
  • TS-5764: Grails in Depth
  • TS-5793: Groovy and Grails: Changing the Landscape of Java Platform, Enterprise Edition (Java EE Platform) Patterns
  • TS-6096: Nimbus: The New Face of Swing
  • TS-6169: Spring Framework 2.5: New and Notable
  • TS-6457: Choosing Your Java Technology-Based Web Framework: A Comparison
  • TS-6490: JRuby on Rails Deployment: What They Didn’t Tell You
  • TS-6609: The JavaFX Script Programming Language for Swing Developers
  • TS-6611: Filthy-Rich Clients: Filthier, Richer, Clientier
  • TS-6656: Extreme Graphical User Interface Makeover: Rock Stars
  • TS-6929: Creating a Compelling User Experience

I have gone to JavaOne four out of the last five years and have compiled pretty complete conference notes for JavaOne 2007 and JavaOne 2006.

Technorati Tags: , , , , , , , , , , ,


Jan 17 2008

Print a PDF Document in Java

For some time now I have searched for a way to print a PDF document from Java code. Up to now, I have had to shell out and invoke Acrobat from the command line but this hack has been painful to support in the field because of the multiple version of Acrobat and its quirks.

A new PDF Renderer project has recently been released on java.net which can in addition to rendering and viewing a PDF document, it can be used to print a PDF document. If you download the PDF Renderer you can run the jar to start a sample PDF viewer application which can print PDF documents. All the code listed below is inspired from the PDF Renderer sample application.

The following code uses classes from the PDF Renderer library and standard Java. Like usual, I have omitted all import statements.

// Create a PDFFile from a File reference
File f = new File("c:\\juixe\\techknow.pdf");
FileInputStream fis = new FileInputStream(f);
FileChannel fc = fis.getChannel();
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
PDFFile pdfFile = new PDFFile(bb); // Create PDF Print Page
PDFPrintPage pages = new PDFPrintPage(pdfFile);

// Create Print Job
PrinterJob pjob = PrinterJob.getPrinterJob();
PageFormat pf = PrinterJob.getPrinterJob().defaultPage();
pjob.setJobName(f.getName());
Book book = new Book();
book.append(pages, pf, pdfFile.getNumPages());
pjob.setPageable(book);

// Send print job to default printer
pjob.print();

One critical class required to print a PDF document using PDF Renderer is the PDFPrintPage. The PDFPrintPage implements the Printable print method. The PDFPrintPage is included in the PDFRenderer.jar, but in the source distribution it is found under the demos project. I have included the source to PDFPrintPage print method here…

class PDFPrintPage implements Printable {
  private PDFFile file;
  PDFPrintPage(PDFFile file) {
    this.file = file;
  }

  public int print(Graphics g, PageFormat format, int index) 
    throws PrinterException {
    int pagenum = index + 1;

    // don't bother if the page number is out of range.
    if ((pagenum >= 1) && (pagenum < = file.getNumPages())) {
      // fit the PDFPage into the printing area
      Graphics2D g2 = (Graphics2D)g;
      PDFPage page = file.getPage(pagenum);
      double pwidth = format.getImageableWidth();
      double pheight = format.getImageableHeight();

      double aspect = page.getAspectRatio();
      double paperaspect = pwidth / pheight;

      Rectangle imgbounds;

      if (aspect>paperaspect) {
        // paper is too tall / pdfpage is too wide
        int height= (int)(pwidth / aspect);
        imgbounds= new Rectangle(
          (int)format.getImageableX(),
          (int)(format.getImageableY() + ((pheight - height) / 2)),
          (int)pwidth,
          height
        );
      } else {
        // paper is too wide / pdfpage is too tall
        int width = (int)(pheight * aspect);
        imgbounds = new Rectangle(
          (int)(format.getImageableX() + ((pwidth - width) / 2)),
          (int)format.getImageableY(),
          width,
          (int)pheight
        );
      }

      // render the page
      PDFRenderer pgs = new PDFRenderer(page, g2, imgbounds, null, null);
      try {
        page.waitForFinish();
        pgs.run();
      } catch (InterruptedException ie) {}

      return PAGE_EXISTS;
    } else {
      return NO_SUCH_PAGE;
    }
  }
}

A final note, PDF Renderer does require Java 1.5 or greater.


Jan 10 2008

The Great Grails Switch

The Apple Switch Ad campaign was very successful for Apple, so much so that there seems to be a sort of switch meme campaign amongst Grails folks to try to get Ruby on Rails developers to switch to Grails. Originally this blog post presented 10 reasons to switch from Rails to Grails and now Graeme Rocher of G2One has added another ten. Here is the complete list of reasons to switch to Grails… or at least top reasons to give Grails a try…

  • GORM with hibernate/spring and jpa is much better than ActiveRecord
  • No distribution problems; runs in many production ready containers
  • Internationalization out of the box (not specifically ignored as DHH does)
  • Transactions actually work, and they include save-points.
  • Not only dynamic finders and counters, but dynamic listOrderBy
  • No green threads (although this may be fixed in Ruby 2.0, around 2010?)
  • Ability to use pessimistic locking out of the box
  • Real-live prepared statements and .withCriteria method
  • Production level test reporting with built in Mocking and Stubbing
  • Search operations are based on Lucene (with a plugin)
  • A view technology that doesn’t suck
  • Mixed source development made easy with the Groovy joint compiler (no falling back to C to solve those performance problems ;-)
  • Built in support for rich conversations with Web Flow
  • A rich plug-in system that integrates Grails with technologies Java people care about like GWT, DWR, JMS etc.
  • A buzzing and growing community with a larger traffic mailing list as opposed to a stagnating one
  • Built on Spring, the ultimate Enterprise Application Integration technology
  • A Service layer with automatic transaction demarcation and support for scopes
  • More books coming and being adopted by enterprise organizations near you

For the true die hard Ruby on Rails developers this might not be reason enough to switch to Grails, but for those Java developers on that are on the fence Grails might seem a bit more attractive now.

For those interested in getting started with Grails, take a look at my Groovy and Grails tutorials.

Technorati Tags: , , , , , ,


Jan 2 2008

Debugging Users and Invisible Characters

As a developer working for a startup with live software in the field, I often have to problem solve some interesting and out of the box bugs. One recent bug was related to changes to the Daylight Standard Time and Sun’s Java Timezone Updater, which is far from the control of my code. The Timezone Updater is a simple Java application that can be run as follows.

"c:\Program Files\Java\jre1.5.0_10\bin\java" -jar tzupdater.jar -f -bc

After documenting, testing, and validating the process of running the Timezone Updater from the command prompt we had our sales engineer upgrade the all of our clients’ JRE with the current timezone data. After some time we had reports that some clients had a problem running the above command, they where getting the following Java error.

Exception in thread "main" java.lang.NoClassDefFoundError: ûjar

It seemed that Java could not find a class named ujar (notice that funny hat over the u). Our sales engineer, with the aid of a software engineer, spent all day going back and forth with the client. As you might have guessed, updating the timezone data worked for our engineers but at the client site they consistently got the above error. After a long email thread full of instructions, screen shots, and frustration I was pull in.

I too was unable to reproduce the error until I considered the error. The only clue in the above error is the funny character u. After some time it occurred to me that the -jar had been corrupted into ujar. But what would distort the dash? Word. The instructions to run the Java Timezone Updater where written and sent in Outlook and cut and pasted from Outlook. Outlook uses Word as the default mail editor and Word has the awful tendency of distorting plain old ASCII text into special characters at will, try typing :) in Word.

This bug was not obvious to our client’s IT personnel, our front line sales engineer, and an experienced software engineer. Having code working on the developer’s machine is not a valid solution, software needs to work at the client’s site too!

One lesson that most developers don’t learn is to debug outside the debugger. As an engineer there are times you need to trouble shoot, problem solve, and debug not just your software from the comforts of your favorite IDE but the whole software stack, network, hardware, user’s environment, and even the user himself.

Every problem, issue, and bug experienced by the end user directly and indirectly with your software eventually needs to be implicitly and explicitly dealt with by your software development team. Bugs that are on the fringes of the code base are the most difficult to solve, that is why each member a software development team needs to take full ownership of the whole code base, and every known issue.

Technorati Tags: , , , , , ,