Errata

Java Cookbook

Errata for Java Cookbook

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted By Date submitted Date corrected
Printed
Page 702
1st paragraph, code example

Dear Mr. Darwin,

first of all I would like to say that I like your book very much and I am using it frequently.

During my current project, I used it to step in to thread programming. After some programming, I think I have found a mistake in recipe 24.6 on page 702.

In the first code example, the lock.lock() method call is put into the try block. If an Exception is thrown from this method call, the lock.unlock() method call in the finally block will be executed anyway, which may lead to an IllegalMonitorStateException for example.

The API (http://java.sun.com/javase/6/docs/api/java/util/concurrent/locks/Lock.html) shows the lock() method call outside the try block, which solves this problem:

Lock l = ...;
l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();
}

I have marked this as a 'Serious technical mistake' because most times it is likely covered by overlying Exceptions and because it is hard to reproduce in a debugging environment.

If I missed something, please give me a short hint about it.

Please excuse my English, as it is not my native tongue.

With kind regards,

Christian Binder

Note from the Author or Editor:
Thanks for reporting this. I think I would classify it as a "minor technical mistake" because, in fact, the lock() method is unlikely to throw exceptions. However, I have changed it as you suggest in the online source code, and will change it in subsequent editions of the book; Publications can change it if they reprint the book meanwhile.

The fragment at the top of the page should change as follows:
(Pubs: print on wide paper, and interpret as "diff -u" output):

diff -u -r1.1 -r1.2
--- LockFragment.java 1 Apr 2005 19:03:09 -0000 1.1
+++ LockFragment.java 15 Nov 2008 15:42:38 -0000 1.2
@@ -4,11 +4,12 @@

public class LockFragment {

+ Lock theLock = null;
+
/** This file exists to hold the skeleton code at the top of Recipe 24.6 */
public void demo() {
- Lock theLock = null;
+ theLock.lock();
try {
- theLock.lock();
// do the work that is protected by the Lock
} finally {
theLock.unlock();


The code example, ReadersWriterDemo.java, should be changed as follows:

diff -u -r1.7 -r1.8
--- ReadersWriterDemo.java 10 Feb 2007 16:24:02 -0000 1.7
+++ ReadersWriterDemo.java 15 Nov 2008 15:42:38 -0000 1.8

@@ -45,16 +47,23 @@
for (int i = 0; i < NUM_READER_THREADS; i++) {
new Thread() {
public void run() {
- while(!done) {
- Iterator results = null;
+ while (!done) {
+ Iterator<BallotPosition> results = null;
+ lock.readLock().lock();
try {
- lock.readLock().lock();
results = theData.iterator();
} finally {
// Unlock in finally to be sure it gets done.
lock.readLock().unlock();
}

@@ -68,17 +77,19 @@
// Start one writer thread to simulate occasional voting
new Thread() {
public void run() {
- while(!done) {
+ while (!done) {
+ lock.writeLock().lock();
try {
- lock.writeLock().lock();
theData.voteFor(
- (((int)(Math.random()*
- theData.getCandidateCount()))));
+ // Vote for random candidate :-)
+ // Performance: should have one PRNG per thread.
+ (((int)(Math.random()*
+ theData.getCandidateCount()))));
} finally {
lock.writeLock().unlock();
}
try {
- Thread.sleep(((long)(Math.random()*1500)));
+ Thread.sleep(((long)(Math.random()*1000)));
} catch (InterruptedException ex) {
// nothing to do
}

Anonymous  Nov 15, 2008 
Printed
Page 1
9780596001704src/DBM/jdbm.c

one of the malloc()s incorrectly uses the k.dsize instead of the v.dsize to
allocate the size, causing the example to not work.

line 97:

is:
v.dptr = malloc(k.dsize); // XXX

should be:
v.dptr = malloc(v.dsize); // XXX

Note from the Author or Editor:
Code is not going to be in the 3rd Edition. Closed.

Anonymous   
Printed
Page 105
9780596001704/RE/BookRank.java line 21

There's a compiler error when trying to compile 9780596001704/RE/BookRank.java:
unclosed string literal:
public final static String QUERY = "
"http://www.quickbookshops.web/cgi-bin/search?isbn=";
The quote on line 21 should be removed:
public final static String QUERY =
"http://www.quickbookshops.web/cgi-bin/search?isbn=";

Anonymous   
Printed
Page 121
The floating point comparison (equals method) shown here works

fine for most ranges of numbers, but requires you to
specify the "epsilon" value. A reader has pointed out that
you can write this code such that it scales the epsilon,
at the cost of a few additional calls on the math library,
by promoting EPSILON to a field in the class, and writing
public static boolean equals(double a, double b) {
return Math.abs(a - b) <
EPSILON * Math.max(Math.abs(a), Math.abs(b));
}

Anonymous   
Printed
Page 213
The clone() method does not need a throws clause

for CloneNotSupportedException.

Anonymous   
Printed
Page 268
UnZip.java

The UnZip program has problems with some Zip files that don't have proper
directory entries, particularly on MS-Windows. A revision that is more
careful to pre-create the directories is available from the author's web
site - http://9780596001704.darwinsys.com/

Chapter 11, Serial IO.

Chapter 21, XML

Anonymous   
Printed
Page 309
PortChooser.java, at the end of the imports, the following line HAS BEEN ADDED

import com.darwinsys.util.WindowCloser;

Anonymous    Dec 01, 2003
Printed
Page 325

CommPortModem.java, the 8th line on this page, read:

String junk = os.readLine()

NOW READS:
String junk = is.readLine()

Anonymous    Dec 01, 2003
Printed
Page 624
IN PRINT: 'Discussion' section, first code snipped

"stmt.executeUpdate("select * from myTable");"

NOW READS:
"stmt.executeQuery("select * from myTable");"

Anonymous    Dec 01, 2003
Printed
Page 659
The doNode() method is not shown; it must process

whatever nodes you are interested in, and call doRecursive()
with others, to walk the entire tree. Changing the call
on doNode() to doRecursive() will print all the nodes.

Anonymous   
Printed
Page 674
In the code for the TickerServer interface, the code contains

//...code
public interface TickerServer extends java.rmi.Remote {
public static final String LOOKUP_NAME = "Ticker Service";
//...more code

On some implementations, a MalformedURLException is thrown because of
the space. Changing the constant String to "TickerService" will resolve
the problem.

Chapter 24, Threads

Anonymous   
Printed
Page 725
If you read 24.5 but not 24.6, you might get confused (as a

reviewer on Amazon.com apparently did) and think that
synchronization locks a method (or that I think this is the case).
In fact, the lock is an attribute of an object; a
synchronized method running in an object does lock
out all other synchronized methods running in the
same object (or synchronized blocks synchronized
on the object). This will be clarified in the next
edition.

Chapter 26, Using Java with Other Languages

Anonymous   
Printed
Page 796
Not shown in the book, but online in 9780596001704src/DBM/jdbm.c.

A call to malloc() incorrectly uses k.dsize instead of v.dsize to
allocate the size, causing the example to not work.

line 97:

is:
v.dptr = malloc(k.dsize); // XXX

should be:
v.dptr = malloc(v.dsize); // XXX

Anonymous   
Printed
Page 844
First line beneath "subclasses" in the index

abstract mehods and, 221

NOW READS:
abstract methods and, 221

Anonymous    Dec 01, 2003