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

Unlike the doctor that works for your HMO, Doctor Java is here to help you with all of your Java problems. The good Doc will not require a copayment for each visit nor ask you to fill out long arduous forms. The Doctor is here to help the readers of Java Developer's Journal find a cure for their Java system ills.

How can I synchronize method access across two different classes?
The synchronized modifier is used to control access to critical code in multithreaded programs. When a method is declared synchronized, you're instructing the program to obtain a lock (monitor) on the object that has the method. If you call another synchronized method on the same object, you don't lose the lock and other threads don't have access until the lock is freed.

This, however, does not work across objects. The best way to solve this problem is not to declare your methods as synchronized but to use a synchronized block. First, we'll look at typical code that does not lock across methods:

public synchronized void
increasePaycheck(int empId, int percent) {
...
}

public synchronized void
givePromotion(int empId, String newTitle) {
...
}

Let's consider doing something like this:

public void increasePaycheck(int percent) {
synchronized(this);
...
}

This would be considered a noble effort but unfortunately it does not do the trick. The main problem with this is that you are still trying to acquire a lock on this. What we really need is an alternative object to lock. Let's restructure our code and see how this can be realized.

public HRObject {
private static Object lock = new Object();

public static void doIncreasePromotion
(int empID, int percent,
String newTitle) {

HRIncrease hr1 = new HRIncrease();
HRPromotion hr2 = new HRPromotion();

synchronized(lock) {
hr1.increasePaycheck(int empId, int percent);
hr2.givePromotion(int empId, String newTitle);
}
}
}

The preceding code example is the prescription for your woes. We basically used an "impartial" object as the basis for acquiring a lock. This approach requires that you always use the same lock object and methods similar in their approach to synchronization. We could have alternatively created a static method in a class that is synchronized and have this method make all the other method calls on your behalf.

I am building a JSP/JDBC site with an ISP that never allows a dsn type connection. The database I want to use is access. How do I do a dsn-less connection?
The doctor recommends seriously changing your diet and eliminating Microsoft Access as a database for use with Java and migrating to something that will scale a little better and is supportable. With that being said, let's dive into the solution to your problem. Let's say that you have an ODBC connection with the following configuration:

[ODBC]
DRIVER=Microsoft Access Driver (*.mdb)
UID=admin
UserCommitSync=Yes
Threads=4
SafeTransactions=0
PageTimeout=5
MaxScanRows=8
MaxBufferSize=2048
FIL=MS Access
DriverId=25
DefaultDir=c:\
DBQ=c:\doctorjava.mdb

To talk to an ODBC data source you will need to utilize a JDBC to ODBC bridge. Sun recommends using the bridge in situations where no native JDBC driver exists. Merant is a company that provides JDBC drivers that can connect to many disparate databases. To utilize the bridge, your code would look similar to:

try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

Connection conn =
DriverManager.getConnection("jdbc:odbc:
DRIVER=Microsoft Access Driver
(*.mdb);" +
"DBQ=c:\\doctorjava.mdb");
...
}

The ODBC connection strings may vary in syntax depending upon the actual database and language you are connecting to.

I would like to see all of the elements in the request header in my JSP for debugging purposes. Could you point me in the right direction?
The doctor loves it when readers ask questions that can be answered quickly. To solve your problem we can take advantage of the java.util.Enumeration object. We can loop through the requests and display them to the screen. Let's take a look at some sample code.

<html>
<head><title>Show Headers</title></head>
<body>
<%
java.util.Enumeration e=
request.getHeaderNames():
for (e; e.hasMoreElements();) {
String header=
(String)e.nextElement();
out.print(header + " = " +
request.getHeader(header) + "
");
}
%>
</body>
</html>

The doctor assumes the reason you have the need for such code is because you are having a problem related to types not being set properly on your Web server.

How do I delete a cookie within a JSP page?
Let's take a look at your code and see why it doesn't perform as expected.

Cookie killCookie = new Cookie("uid", null);
killCookie.setMaxAge(0);

The code removes a cookie from the browser once the browser is closed. This approach does not work in all instances. Many browsers keep it in memory and will not actually destroy the cookie until the browser instance is shut down. Let's take it one step further. In some scenarios, it may be useful to have the cookie destroyed without shutting down the browser. To realize this goal, you need to change your code slightly as follows:

Cookie killCookie = new Cookie("uid", null);
killCookie.setMaxAge(0);
killCookie.setPath("/");
response.addCookie(killCookie);

This should do the trick nicely.

When should I use the singleton pattern in my java application?
The Singleton pattern reminds me of one of my girlfriends in high school. At first, I found that she was the only thing I wanted but later she proved to be very problematic. The Singleton pattern is useful in situations where you only want to have a single instance of a particular object. The second use for Singletons is to provide a global viewpoint of common functionality. Typically, Singletons will be used for log managers, reference services, and similar functionality.

Singletons can be problematic, like the girlfriend in high school They're typically implemented with synchronized blocks. Many threads will fight to obtain a lock on your Singleton causing a big performance bottleneck. The Singleton pattern can be problematic in a cluster as you will want more than one instance. The other problem with this pattern is that you need to make sure that its access is completely hidden from the outside world, or else it is essentially a big fat global variable.

The other thought I have is that it's always easier to make something a Singleton than to unmake something a Singleton. In my mind, this is a red flag that needs serious architectural thinking.

Letters to Doctor Java:
Send your questions, comments, and praise to [email protected]. Published letters will be edited for length and clarity.

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

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.