Download (direct link):
public Throwable Initializes the cause of this
initCause(Throwable c) throwable to the specified value. (The cause is the throwable that caused this throwable to get thrown.)
public Throwable(Throwable cause) Constructs a new throwable with the specified cause.
public Throwable(String message, Throwable cause) Constructs a new throwable with the specified detail message and cause.
Of course, java.lang.Exception and java.lang.Error are subclasses of Throwable, so now we can make minor adjustments to our code, passing in the cause of the exception to our new AccessException class. This is seen in Listing 4.3.
01 public boolean authenticate(String uname, String pw) throws AccessException
03 boolean result = false;
04 String dn = "uid=" + uname + ",ou=People,dc=pitfalls.org";
08 m_ld.authenticate( m_ldapversion, dn, pw );
09 result = true;
11 catch ( LDAPException e )
13 throw new AccessException(e);
15 return (result);
Listing 4.3 Modifying authenticate(), passing causality
When Information Hiding Hides Too Much 43
Listing 4.3 shows a simple way to handle our exception without losing information. Finally, Listing 4.4 shows the resulting class that replaces the listing in 4.1. As you can see in line 3 of Listing 4.4, we create a class that implements our iAccessControl interface, and we have modified our authenticate!) method to throw an AccessException, passing the causal exception to the constructor in lines 39 to 55.
01 package org.javapitfals.item4;
02 import netscape.ldap.*;
03 public class LDAPAccessControl implements iAccessControl
05 private String m_host = null;
06 private int m_port = 389;
07 private int m_ldapversion = 3;
08 private LDAPConnection m_ld = null;
11 public LDAPAccessControl(String hostname)
13 this(hostname, 389, 3);
16 public LDAPAccessControl(String hostname, int portnumber)
18 this(hostname, portnumber, 3);
20 public LDAPAccessControl(String hostname, int portnumber, int ldapversion)
22 m_host = hostname;
23 m_port = portnumber;
24 m_ldapversion = ldapversion;
26 private void createConnection() throws LDAPException
28 m_ld = new LDAPConnection();
29 m_ld.connect(m_host, m_port);
32 * The purpose of this function is to authenticate to
33 * the Directory Server with credentials.
35 * @param uname the user name
36 * @param pw the password
37 * ©return successful authentication
Listing 4.4 The better implementation (continued)
44 Item 5
39 public boolean authenticate(String uname, String pw)
40 throws AccessException
42 boolean result = false;
43 String dn = "uid=" + uname + ",ou=People,dc=pitfalls.org";
47 m_ld.authenticate( m_ldapversion, dn, pw );
48 result = true;
50 catch ( LDAPException e )
52 throw new AccessException(e);
54 return (result);
Listing 4.4 (continued)
This pitfall showed the traps that can present themselves when you try to hide the implementation details when creating an API for use by other developers. The key points that you should keep in mind are as follows:
¶¶ Take advantage of interfaces when hiding your implementation details.
¶¶ Be wary of not handling exceptions properly. Instead of returning a value from a method (such as false or null), think about the cause of your returning these values. If there could be multiple causes, throw an exception.
¶¶ Instead of taking some information from one exception and placing it a new exception, take advantage of the new JDK 1.4 changes to Throwable and add the original exception to your new exception.
Item 5: Avoiding Granularity Pitfalls in java.util.logging
The release of J2SDK 1.4 brought us a new logging APIójava.util.logging. For those of us who have been frustrated by our own implementations of logging over the years, this can be a powerful package that comes out of the box with the J2SE. An application can create a logger to log information, and several handlers (or objects that "log" the data) can send logging information to the outside world (over a network, to a file, to a console, etc.) Loggers and handlers can filter out information, and handlers can use Formatter objects to format the resulting output of the Handler object.
Avoiding Granularity Pitfalls in java.util.logging 45
Figure 5.1 Levels of granularity.
At first glance, adding a logging solution into your application looks incredibly easy and quite intuitive. When you start changing the granularity of logging, however, there are some potential pitfalls that lie in your path. Figure 5.1 shows the levels of granularity from the class java.util.logging.Level, with the lowest level of granularity being Level.FINEST. The key point to know is that when a logger is set to show messages at a level of granularity, it will show messages labeled at that level and above. For example, a logger set to the FINEST level of granularity will show all messages labeled Level.FINEST and above in Figure 5.1. When a logger is set to show messages at Level.INFO, it will show messages labeled Label.INFO, Label.WARNING, and Label.SEVERE. Of course, as Figure 5.1 shows, the Level class also includes "ALL" for logging all messages and "OFF" for logging no messages.