Letters to the editor

Tips 'N Tricks

'Java Tip 105: Mastering the classpath with JWhich'

Mike Clark

Does this tip apply to resource-intensive initializers?

Mike,

Thank you for your article. That little gem of wisdom may prove valuable to my organization. I just wanted to point out one detail that I'm sure you're aware of, but you probably glossed over to save space. I experimented with your code a bit, to see if I could resolve those somewhat cryptic systemresource:/ZIP11/+... and systemresource:/FILE01/+... lines into a real File(), and I figured it out -- in principle. But in the process, I found that your code loads the classfile, and actually executes the static initializer if the class hasn't already been loaded. If someone has resource-intensive initializers, this code probably isn't recommended for browsing the available classes.

Bob Gilmore

Bob, Indeed, the Class.getResource() method will order the class loader to load the class, if found, which will cause the static initializer to execute per the language specification. Your point about resource-intensive static initializer blocks is a good one. Although I haven't had any problems with static initializers, it's certainly something to keep in mind. In regard to resolving the returned URL string, I simply print it out in its raw file form. I think it is the most descriptive and compact representation for JWhich. However, I have used the guts of JWhich in a full-scale application that required the URL string to be parsed into its representative pieces. Generally, if the string contains a ! token, then the class is bundled inside a JAR or ZIP file, with the filename preceding the token and the archive entry (class) name trailing the token. If the string does not contain a ! token, then it's not bundled in an archive. A few convenience methods can help encapsulate the details of resolving a raw string. For classes bundled in archive files, you can obtain input and output streams to the class entry, but the only way to construct a File object is to first extract the class entry into an unbundled classfile. Mike Clark

Testing Techniques

'Test infect your Enterprise JavaBeans'

Michael T. Nygard, Tracie Karsjens

Testing EJBs outside the container

Michael,

Your article illustrates how to test the bean when it is deployed inside the Enterprise JavaBean (EJB) container. That is an important step, but sometimes the container may not be available, or you may have to complete more basic tests of the bean code before testing them inside the container. I have found that I can easily write such tests to run inside JUnit. I simply mimic the container's function and implement a simple InitialContext.

Magnus Lundgren

Magnus, You make an excellent point -- in fact, I prefer to test components outside of application servers. Because it is much faster to run the test without starting an application server, developers tend to run their tests more often if they are independent of the app server. Unfortunately, sometimes it is not practical to create a test harness complete enough to suit the classes under test. For example, one class I tested recently would have required a test harness of more than 15 classes. When the test harness is this complex, a high probability of bugs in the harness itself will result. (By bugs, I mean behavior that doesn't comply with specifications or differs from what the application server exhibits.) That causes a risk of false-negative results, in which the test cases pass -- negative failure -- but the class doesn't actually work -- real defect. For these situations, I advocate the servlet TestRunner. Michael T. Nygard

C# vs. Java

'C#: A language alternative or just J--?'

Part 1: What the new language for .Net and post-Java Microsoft means to you

Part 2: An in-depth look into the semantic differences and design choices between C# and Java

Mark Johnson

Does Java require enumerations?

Mark,

One of the biggest misconceptions about Java is that it needs enumerations. It will take a long time to educate people on this point. I will start with you.

This is how to do typesafe enumerations:

public class Description {
   public static final Description Good = new Description();
   public static final Description Bad = new Description();
   public static final Description Ugly = new Description();
   private Description() {
   }
}
public class Sheriff {
   protected Description description;
   public Sheriff() {
     description = Description.Good;
   }
}

To iterate over the descriptions, do this:

public class Description {
   public static final Description Good = new Description();
   public static final Description Bad = new Description();
   public static final Description Ugly = new Description();
   private static Vector collection = new Vector();
   private Description() {
     collection.addElement(this);
   }
   public static Iterator iterator() {
     return collection.iterator();
   }
}

Enumerations are actually quite bad, because they reveal far too much of their implementation (integers).

Marcus Andersson

Marcus, Thanks for writing. I really like your way to do typesafe enumerations in Java. Some might say that the overhead of object construction is a high price to pay for type safety. However, I wouldn't make that argument unless execution profiling revealed a problem. Thanks for the tip. Mark Johnson

Server-Side Java

'Make an EJB from any Java class with Java Reflection'

Tony Loton

Are any open source projects available?

Tony,

Thank you for such an interesting article. I wish we could just drop existing Java code directly into an application server, which would then generate the EJB interfaces, package the classes, and deploy the EJB automatically. Wouldn't that be nice? I would not be surprised if that capability starts to pop up on many Java 2 Platform, Enterprise Edition application servers in the future.

As for converting static methods, we might have to resort to putting them in a separate stateless EJB interface.

This would also be an interesting open source project. Do you know of any like it?

Jon Lee

Jon, I'm glad you liked the article. Regarding your first point, this feature seems to crop up in IDEs rather than applications servers, which seems a bit illogical to me. As for your second point, I, too, think a separate stateless EJB could be used to hold the static/class methods. But I wonder how one could present the two EJBs as a single entity via the client-side factory, and preserve the semantics of class versus instance methods as used nonremotely. You're the second person to suggest an open source project. Although this isn't a commercial project right now, I'm still considering the intellectual property/copyright implications for my company and pondering the effort needed for such an undertaking. Tony Loton

Enterprise JavaBeans

'Reduce EJB network traffic with astral clones'

Martijn Res

Should you access an entity bean from a client?

Martijn,

You wrote a very interesting article. I'm not sure I fully agree, but I'll give you the benefit of the doubt until I can investigate. My personal rule is to never access an entity bean from a client. That was your first mistake, and the reason for poor performance. I also design so that only session beans access entity beans, since it might not be necessary to bring every property of an entity bean back to the client. Nevertheless, great idea! It was elegant, and the article was easy to read. Thanks. Taylor Cowan

Taylor, Using session beans is one way to bring the process and data together. In this case, you chose to delegate the process to the data's location (the application server). But in the real world of distributed computing, there are more complex system architectures than thin clients, so I think it's nice to be able to bring the data to the process, which is transparent and preserves encapsulation. Also, I think that separating data and business logic ("stupid" entity beans with only getters and setters, and session beans containing the business logic) is evil. I must say that "Building user interfaces for object-oriented systems, Part 1," by Alan Holub (JavaWorld, July 1999), has influenced me greatly regarding encapsulation (excluding the UI stuff described in the rest of that series). But this would not stop me from applying session beans if I feel I need them when tweaking a system. Martijn Res

Java Q&A

'Buy, don't build'

Tony Sintes

Building a chat system

Tony,

I know exactly what you mean when you say "buy, don't build" a search engine.

I am building a chat system designed for a client's specific needs.

I'd like to know how you feel about the current basic technical requirements for a chat system to succeed in the market.

Joseph Fenyes

Joseph, I'm not really sure what is required for a chat system to succeed, but I can make some guesses. If you want to compete with some of the commercial systems, you should be able to message people on AIM, ICQ, and whatever Microsoft offers. I'd start by examining the available services and making a list of their features. Once you have that list, find out what your customer wants, since this effort is customer-driven. You'll need to ask the customer questions like:

  • How many concurrent users do you want to support?
  • What protocols do you want to support?
  • Is the chat client for internal use, a customer feedback/support Webpage feature, or a generic worldwide chat service like ICQ or AIM?

The answers to such questions will drive your architecture. Obviously, supporting 5 to 10 people at once is much simpler than supporting thousands of concurrent users. You won't need to support AIM and ICQ if you build an internal tool; a proprietary protocol will suffice. A chat client can mean different things to different people. You'll have to obtain a good definition of what your customer wants and go from there. Tony Sintes

Java Q&A

'Singletons rule'

Tony Sintes

Further evidence that singletons rule

Tony,

Regarding your great article on general object-oriented design advantages, I would like to add one Java-specific advantage.

In Java, not only are objects garbage-collected -- so are instances of the Class classes that represent classes to the Java VM. After all, those instances are just objects to the Java VM. If there are no references to a class, it might as well be thrown out during garbage collection. If a reference from a live object or a class running in one of its methods points to a class instance, then the Class object will stick around. If not, and you can double-check me on this, then the class's Class object is a candidate for garbage collection. When the Class object is garbage-collected, the current values in its static fields go with it.

Now we have a problem: the Class object can be recreated the next time it encounters a reference, but its fields will reset to their defaults.

For example, currConnection:java.sql.Connection, which had a value of a JDBC connection to a database, will be null. activeJobs:Hashtable, which contained a list of threads that some service manages, will set to null or an empty hash table, depending on whether the field has an initializer in its declaration. Both cases will likely not produce the desired state. Also, primitive fields like currAcctId:int will no longer equal the current account ID.

Thus, storing state information in any or all of a static class's fields is dangerous, unless you can guarantee a reference to that class.

The best way to do that is to use the singleton pattern when implementing that class. As part of its contract, the application using the class should keep a direct or indirect reference to the singleton object, as long as it wants the class's state to be maintained. The application should not reset the singleton to its just-loaded state at some random time during execution.

Does that clearly describe the special need for the singleton pattern in Java and the risk of not using it? It's an obscure point that doesn't receive much attention. I am sure this affects many applications, especially server-based apps like servlets.

Using the singleton pattern to save a class instance's life is easy, and does not sacrifice the ability to directly reference the class's static methods. The minimum requirement is simply that the top level of the application call the getInstance() method; the reference will be held until no more references to the object's state -- e.g., calls to its static methods that refer directly/indirectly to its fields - can be made.

Programmers who keep a live reference to the singleton instance are rewarded. Those who don't use the pattern at all or who do, but don't keep a live reference, are punished; their programs crash due to the unexpected resetting of the fields back to their default values.

The latter victims are left with a bad taste in their mouth for using Java for long-running programs, such as servers and services; that is not really fair to Java.

So while the standard application is good enough for justifying using singleton in C++, it is 100 times more important to mention its importance in Java. The instance needs to be held for the reasons given, or the program will crash at random. Do you agree? John Collins

John, You are correct.

public class Singleton
{
    private Singleton() {}
    
    public synchronized static Singleton getInstance()
    {
        if ( _instance == null )
        {
            _instance = new Singleton();
        }
        return _instance;
    }
    
    private static Singleton _instance;
}
Related:
1 2 Page 1
Page 1 of 2