Some reader favorites:
EJB fundamentals and session beans
Create a scrollable virtual desktop in Swing
More action with Struts 2
In a recent review of Struts 2 in Action, JW Blogger Oleg Mikheev notes that Struts 2 is "just a collection of extensions built upon WebWork, which is ultimately
the right thing to learn before starting a Struts 2 project." While Struts 2 has some architectural flaws, Oleg calls WebWork
well-designed, well-tested, and reliable. What are your experiences using Struts 2 and WebWork?
Also see "Hello World the WebWork way," a JavaWorld excerpt from WebWork in Action, by Patrick Lightbody and Jason Carreira.
| Memory Analysis in Eclipse |
| Enterprise AJAX - Transcend the Hype |
Gerardo's product, a Java library called Montage, enabled Java applets or applications to display a special kind of image. The image was special because it was defined not just by data, but also by code.
To display one of these images, the Montage library would first show a background image (stored as plain old image data), then it would dynamically load and execute some Java code (called painters) that massaged the background image. To massage the background image, a painter could process the image to produce a special effect or animate the image -- anything that could be done to an image with Java code a painter could do. The result was the Montage image.
This product stoked my inner nerd sufficiently enough that I wanted to know the details of how he did it. I arranged a meeting with Gerardo in the Hacker's Lounge, a social gathering spot at JavaOne.
There he described the inner workings of the class loader he used to load painters. Our conversation drifted to class loaders, in general, and to Java's overall architecture. Gerardo was very enthusiastic about Java and excited in particular about the new opportunities made possible by its architecture.
Eventually, Gerardo and I left the Hacker's Lounge and headed for a JavaOne session. As we made our way through the crowd, he continued his animated discussion of the benefits of Java.
One thing he said that stuck in my mind was: "When you look at C++'s linking model, it is really just C's linking model with mangled names tacked on. If you look at C's linking model, it is really just Fortran's linking model. But when you look at Java's linking model, it doesn't look like any of those. That's the significant difference about Java!", he exclaimed. "It's the linking model!"
In this article, I'll discuss how to take advantage of one of the more interesting design opportunities made possible by Java's
linking model: dynamic extension. As a background to the design guidelines, I'll give an overview of Java's linking model,
touching on topics such as name spaces, forName(), and class loaders.
For the full details on these topics, I'll refer you to Chapter 7 of my book Inside the Java Virtual Machine, which, partly in honor of my conversation with Gerardo, I named "The Linking Model." In this chapter, I explain in painstaking detail the process of dynamic linking in the JVM, and show how to write and use class loaders.
But you needn't rush to the bookstore to read this chapter; I have excerpted it in its entirety on my Web site. (See the Resources section for a link to this material.)
Java's architecture enables you to write programs that dynamically extend themselves at runtime. Java programs can dynamically extend themselves by choosing at runtime classes and interfaces to load and use.
Looked at another way, dynamic extension means that at compile time, you don't necessarily need to know about all the classes and interfaces your program will use at runtime. In fact, some of those classes and interfaces may not even exist when you do your compile.
Java has two ways to do dynamic extension: forName(), and class loaders. forName(), a static method in java.lang.Class, is the simple, straightforward way to do dynamic extension. Class loaders, subclasses of java.lang.ClassLoader, are the more complicated (and more powerful) way to do dynamic extension.
In a Java program that uses dynamic extension, irrespective of whether it uses forName() or class loaders or both, names of types (classes and interfaces) will be passed around in the program as Strings. To request a certain class be loaded, the program will pass as a String the fully qualified name of the desired type to forName() or the class loader. Because the type name is handed to forname() or the class loader as a String at runtime, the program can be written such that the actual contents of the Strings (the names of the types your program will load at runtime via dynamic extension) are not known at compile time.
Whether you knew it at the time, if you've run a Java program, you have already been using class loaders. Every type (class or interface) used by a Java program must be loaded into the Java virtual machine (JVM), and the JVM loads types through class loaders.
Java has two kinds of class loaders -- the primordial class loader and class loader objects. The primordial class loader is sometimes called the system class loader or the default class loader. Class loader objects are sometimes called custom class loaders.
The difference between these two kinds of class loaders is important to understand. Whereas the primordial class loader is part of the JVM implementation, class loader objects are part of the running Java application.
For example, when I downloaded the JDK for Windows 95, I got a JVM. This JVM, to the best of my knowledge, is written primarily in C. In my case, the primordial class loader is a part of the C program that defines my JVM.
Armed with this installation of Java on my computer, I can then write and run a Java application that uses class loader objects. In this case, I would define class loaders in Java, which my Java application would instantiate and use.
So the difference is this: The primordial class loader (there is only one of these per JVM implementation) is designed and
written by the creators of each JVM. Class loader objects are designed and written by Java programmers. Class loader objects
are defined as classes (subclasses of java.lang.ClassLoader) and instantiated into regular Java objects on the heap.
Whenever the JVM loads a class or interface, it will use either the primordial class loader or a class loader object. Because it is part of the JVM implementation, one (and only one) primordial class loader is always available to a running application. Class loader objects, by contrast, behave like objects. At any one time during an application's lifetime, the application may have zero to many class loader objects in existence and in use.