HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML

Q & A

Unlike the doctor who works for your HMO, I won't require a copayment for each visit nor ask you to fill out long arduous forms.  I'm here to help readers of Java Developer's Journal find a cure for their Java system ills.

Q. What unique parameters accessible from pure Java can be used to identify a machine? We’re working on a licensing mechanism for software currently in development. We’ve toyed with using the IP address, but this won’t work with dynamic IP addresses or if there’s no network connection. There doesn’t seem to be a lot that can be discovered about the machine using only Java, and if there is, it isn’t very well documented.

A. You can do a ton of things to add licensing features to your product. Let’s discuss some of the techniques and the pros and cons of each. Let’s first consider the use of dongles within your application. If the user is running Windows 95, 98, or ME, Linux, and so on, you can query the serial port from Java. If your application is running on Windows NT, 2000, or XP, dongles won’t work. It’s possible to use a USB-based dongle, but this won’t be supported by Windows 95 or NT. Of course, depending on the choice of dongle, you’ll have to incur hardware costs.

You could query settings within each operating system – provided you want to write custom JNI code for each target platform. For instance, on the Windows operating system you could make a Win32 call to GetSystemInfo, which will return information about the machine, such as the number of processors and their type (e.g., Intel, AMD, Cyrix, and so on). On a Windows platform you could also query the registry to determine the particular machine’s GUID (Global Unique ID), which is guaranteed unique by Microsoft. This, of course, would mean the user couldn’t move the application to another machine without contacting you. Many platforms support storing unique serial numbers on the CPU chips themselves, but this can be turned on and off in the BIOS.

If you can at least guarantee that the machine has a network card, regardless of whether it’s connected to the network, you could use JNI and/or run the netstat command to get its MAC address. The MAC address is also globally unique. If you could guarantee a network connection, you could consider implementing Kerberos, where each time the program starts, it checks with a central server (most likely in your company) for authorization to run.

If you want to explore the Java security packages, you could consider implementing digital certificates. Upon startup, Java could check for the existence of a valid digital certificate. You could investigate becoming your own Root CA or at least use a Test CA to check the certificate against your own keystore.

Finally, trying to implement any of the above recommendations will make the average developer’s head hurt. I recommend considering a vendor who’s developed easy-to-use APIs you could easily integrate into your product – FlexLM (www.flexlm.com), for example. Many tools, such as Rational Rose, use their licensing approach.


Q. I’ve been tackling EJBs for a while using stateless session beans. Now I want to use entity beans. In all that I’ve read, the ejbCreate() method in the entity bean returns the primary key of the newly created entity. The caller provides it with the primary key (hence no problem).

I’m using the autoincremented primary keys found in most databases (I’m using MS SQL), so I insert only the record but not the primary key. After the insert I don’t want to requery the database to find out the newly created primary key. Is it mandatory that I return the primary key?

A. I’ve got the answer to your problem and it’s easier than you may think. The primary key class doesn’t need to be the same as the primary key in the database. The only requirement for primary key classes is that they be unique. You can accomplish this by overriding the hashcode() and equals() methods so two rows don’t equal.

The trick is to make your EJB’s primary key some unique combination of information that isn’t related to your autoincrementing sequence number. Let’s say you were developing a human resources application and the respective employee bean. You could make the database primary key the employee ID and make the EJB primary key the social security number.

For those who can’t create a unique key via hashcode(), you’ll have to requery. Of course there may be other scenarios in which you need to consider returning the “right” primary key, especially if your container is aware of the relationships. This solution should work for most applications.


Q. I agree with your assessment in a previous issue (JDJ, Vol. 6, issue 11) that there’s no runtime overhead in using java.util.* instead of java.util.Vector. However, at least in the case of the equivalent construct in Ada (“use” instead of “import”), there could be considerable compile-time overhead involved in using java.util.*.

The reasoning on Ada is analogous to this: suppose the code has import java.util.*; and a whole lot of other import calls as well, then the compiler comes across a line of code like:

Vector v = new Vector();

Even if the compiler quickly finds Vector in the java.util package, it can’t quit there. It has to look through all the other packages to see if any of them also have a Vector class. If they do, it must issue an error message. Otherwise it’ll use the Vector from java.util. Since all this checking has to be done for every reference, it can be time-consuming.

I don’t know if the same reasoning applies to Java compilers, but it seems it might. I agree with your recommendation to use “single type imports.” In fact, for readability’s sake, the Ada community consensus was that in many cases you shouldn’t use import (“use”) at all. If you were doing a lot of math from a math package, then it would be okay to say: 

import xxx.math.*;

If you’re using only one thing from some obscure place, it makes the code more readable to fully qualify where the names come from. But readability is a separate issue.

A. I’m at a loss as I’ve never programmed in Ada. I used to program for Microsoft, and in the past I also programmed in PowerBuilder. I have a couple of thoughts I’d like to share: first, unless you are designing monolithic packages, you likely won’t notice the difference in compile times when using imports such as java.util.*. Any design with a lot of import statements in the class file should also be suspect. While the actual bytecode doesn’t have references to the import statements, having too many of them will make it difficult for those who need to maintain it after you’ve moved on to greener pastures.

Many of the Java development environments such as WebGain Studio have code analyzers that will immediately point out unused import statements. These tools should be a part of the quality assurance process of any development project.


Q. Java uses several distinct “listener” patterns throughout the language, including observer/observable, AWT event handling, and the beans approach. Which model do you recommend developers use?

A. The answer isn’t as obvious as it first appears. Let’s look at java.util.Observable first. Essentially, it can be used for applications that require “callback” type functionality. The majority of the heavy work is typically implemented within the Observable class. The Observable class has the responsibility of also notifying all observers by calling notify-
Observers(). Each Observer class calls its own update() method. The problem with this approach is that Observable is a class, which means you have to subclass. This may not be practical in many situations.

AWT and beans actually use the same approach. Both implement change listeners and fire events as a notification mechanism. In this approach you’re not even required to implement a full-fledged bean to utilize the functionality. Events usually implement the java.util.EventListener interface, which doesn’t have the same limitations as the class approach.


Q. I have a simulated lift control system running through Java and I’ve run into a problem. I need to implement an emergency stop system. Each lift has its own thread. When one lift needs to be shut down immediately, a variable is changed in the lift class, which is a loop in the threads run() method. All current commands in that loop are handled and then the thread exits normally. It is re-created when the start command is entered.

Some of the lift actions (moving, stopping at floors) make use of the Thread.sleep() method. The main lift thread is paused using this, thus simulating a pause required for the lift operations to be simulated correctly. If an emergency stop is requested, the main thread must interrupt the lift thread if it happens to be “sleeping.” However, nothing I’ve tried works. Is there a better solution?

A. I love the English vocabulary. We Americans prefer the term elevator. Anyway, this question referred to using an event listener approach that may be better for your application. Each object could listen for start, stop, and pause events sent by other objects (security guard console, each floor’s button, and so on).

If each request for an elevator gets sent to a controller, the controller could use the wait/notify methods on the threads themselves and send all elevators to the ground floor. If you want to control a single elevator, then a better approach may be to “interrupt” the thread by using Thread.interrupt(). Calling interrupt will cause an InterruptedException to occur, which you can handle with a try/catch block to implement the emergency stop function.


Q. I would like to know how to use Java with IRC (Internet Relay Chat) to do some programmatic communication. Could you point me in the right direction?

A. On the surface this sounds a little dangerous, but I hope you won’t use this information to cause harm. If you’re looking to be a user and don’t require source, then you can check out JIRC (www.jpilot.com). For an open-source IRC client, visit https://sourceforge.net/projects/objircchat/ .

One of the more advanced uses of Java and IRC that I’ve run across to date is the Chattal project (http://sourceforge.net/projects/chattal/ ). Its goal is the development of an artificially intelligent Internet Relay Chat agent that mimics human interaction and provides an information repository for learned topics.


Q. My application has a properties file and I’d like to know if an end user tampers with it. How can I accomplish this?

A. You can take a couple of approaches. First you can inspect the date and time the file was last modified, but this may not give you an accurate picture, as the user could’ve restored the file from backup or some other way. You can always encrypt the file, but there may be situations where you need the information contained within the file to be human readable.

The simplest approach that comes to mind is to calculate a message digest (one-way hash). The following code snippet should point you in the right direction:

String filename = "doctorjava.properties";
MessageDigest md = MessageDigest.
getInstance("MD5");
FileInputStream fis = new FileInputStream(file name);
DigestInputStream dis = new DigestInputStream
(fis, md);
byte[] buffer = new byte[2048];
while (dis.read(buf) > 0)
...
byte[] digest = md.digest();
fis.close();

By creating and storing a digest along with a file, you can reload it and compare the values. If the digests are different, then you know someone has changed the contents.


Q. How do I compile a string containing Java code on the fly?

A. Whoa! I’ve got your prescription. The answer will require the use of reflection, the Sun community source (www.sun.com.tools package), and the writing of your own classloader. I can’t include the entire source required to implement this, but I can point you in the right direction.

Essentially, it would require a method that looks similar to:

Public stringCompile(String source, String file name) throws CompileException

Once you set up this method you can, of course, make defensive copies of the strings you have passed in, as well as create the appropriate exception class. The very first thing we need to do with this method is determine the current classpath. Java’s default is to load classes from the classpath. In our scenario we want to use a class on the fly. To determine the classpath, we would do the following:

ClassPath cp = new ClassPath(System.
getProperty("java.class.path"));

Next, from the sun.com.tools package, we’ll need to create the appropriate BatchEnviron-
ment() passing in the classpath and an OutputStream we’ll use later. We’ll need to create a new class (let’s call it MemoryClassFile) that we’ll pass to the BatchEnvironment.parse-
File() method. The method call will appear as follows:

BatchEnvironment be;
Be.parseFile(new MemoryClassFile(filename + ".java", source));

Once the source has been compiled, we’ll need to get an enumeration of all the classes. We can accomplish this with BatchEnvironment.getClasses(). We’ll also need to figure out which classes have already been compiled. We can determine this easily, as they’ll be an instance of BinaryClass.

We’ll take the OutputStream and convert it to a byte array; then we’ll need to create a class (let’s call it MemoryClassLoader) that’s derived from ClassLoader, as it is an abstract class. We’ll use MemoryClassLoader to load the compiled classes. The method defineClass will convert an array of bytes to an instance of the desired class. Your MemoryClassLoader class should look similar to:

Static class MemoryClassLoader extends ClassLoader {
public class getClassFromBytes(String filename, byte[] bytearray) {
Return defineClass(filename, b, 0,
bytearray.length);
}
}

Finally we’ll need to use reflection to determine which classes are available to the application and which methods they implement. I could see using this technique for spinning your own CASE tool or script language. I wish you well.


Conclusion
JDJ readers have been sending me some pretty tough questions. This was the most challenging column to date. I encourage you to keep sending in difficult questions.

I leave you with this quote by Douglas Adams:

“A common mistake that people make when trying to design something completely foolproof is to underestimate the ingenuity of complete fools.”

• • •

Send your questions, praise, comments, and admiration to doctorjava@sys-con.com.

• • •

Published letters will be edited for length and clarity. Any reference to third parties or third-party products should not be construed as an endorsement by Doctor Java or Java Developer’s Journal.

Author Bio
Doctor Java, aka James McGovern, works as an enterprise architect with Hartford Financial Services (www.thehartford.com), where he focuses on the architecture of high-availability and J2EE-based solution.

doctorjava@sys-con.com

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: info@sys-con.com

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.