Bug 730 - NullPointerExceptions and ArrayIndexOutOfBoundsExceptions used for normal program control
Summary: NullPointerExceptions and ArrayIndexOutOfBoundsExceptions used for normal pro...
Status: NEW
Alias: None
Product: Xerces-J
Classification: Unclassified
Component: Core (show other bugs)
Version: 1.3.0
Hardware: PC All
: P1 normal
Target Milestone: ---
Assignee: Xerces-J Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2001-02-27 09:30 UTC by John O'Malley
Modified: 2004-11-16 19:05 UTC (History)
1 user (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description John O'Malley 2001-02-27 09:30:48 UTC
Several methods called ensureCapacity exist in Xerces XML Parser packages.  All 
of these seem to use ArrayIndexOutOfBoundsExceptions and NullPointerExceptions 
as normal program flow control, presumably to simplify the code.  The example 
below comes from org.apache.xerces.util.StringPool.  This is a poor scheme, as 
it would be far more efficient to simply perform a few checks and resize the 
array if needed.  The increase in code complexity would be well worth the 
tradeoff.  

Also, this technique presents a problem when using Xerces in the IBM Visual Age 
for Java environment, which allows Exceptions to be caught by the debugger at 
the point which they are thrown.  A developer looking to uncover a legitimate 
bug must wade through the multitude of exceptions thrown by the ensureCapacity 
methods before he or she finds the real source of the trouble.

I hope you will consider refactoring this questionable implementation.

Thanks,
John O'Malley
SBC Communications
314.235.3969
jo2847@sbc.com

	private boolean ensureCapacity(int chunk, int index) {
		try {
			return fOffset[chunk][index] == 0;
		} catch (ArrayIndexOutOfBoundsException ex) {
			if (index == 0) {
				String[][] newString = new String[chunk * 2][];
				System.arraycopy(fString, 0, newString, 0, 
chunk);
				fString = newString;
				StringPool.StringProducer[][] newProducer = new 
StringPool.StringProducer[chunk * 2][];
				System.arraycopy(fStringProducer, 0, 
newProducer, 0, chunk);
				fStringProducer = newProducer;
				int[][] newInt = new int[chunk * 2][];
				System.arraycopy(fOffset, 0, newInt, 0, chunk);
				fOffset = newInt;
				newInt = new int[chunk * 2][];
				System.arraycopy(fLength, 0, newInt, 0, chunk);
				fLength = newInt;
				newInt = new int[chunk * 2][];
				System.arraycopy(fCharsOffset, 0, newInt, 0, 
chunk);
				fCharsOffset = newInt;
			} else {
				String[] newString = new String[index * 2];
				System.arraycopy(fString[chunk], 0, newString, 
0, index);
				fString[chunk] = newString;
				StringPool.StringProducer[] newProducer = new 
StringPool.StringProducer[index * 2];
				System.arraycopy(fStringProducer[chunk], 0, 
newProducer, 0, index);
				fStringProducer[chunk] = newProducer;
				int[] newInt = new int[index * 2];
				System.arraycopy(fOffset[chunk], 0, newInt, 0, 
index);
				fOffset[chunk] = newInt;
				newInt = new int[index * 2];
				System.arraycopy(fLength[chunk], 0, newInt, 0, 
index);
				fLength[chunk] = newInt;
				newInt = new int[index * 2];
				System.arraycopy(fCharsOffset[chunk], 0, 
newInt, 0, index);
				fCharsOffset[chunk] = newInt;
				return true;
			}
		} catch (NullPointerException ex) {
		}
		fString[chunk] = new String[INITIAL_CHUNK_SIZE];
		fStringProducer[chunk] = new StringPool.StringProducer
[INITIAL_CHUNK_SIZE];
		fOffset[chunk] = new int[INITIAL_CHUNK_SIZE];
		fLength[chunk] = new int[INITIAL_CHUNK_SIZE];
		fCharsOffset[chunk] = new int[INITIAL_CHUNK_SIZE];
		return true;
	}
Comment 1 Henry Zongaro 2001-08-01 06:48:25 UTC
I spoke with a JIT compiler developer on IBM's JDK's.  He indicated that (at 
least on IBM's JDK's), there were cases in which using try-catch could be more 
efficient than using the logically equivalent if-else, if exceptions didn't get 
thrown very often.

I've changed some instances in which if-else should be superior; in some cases 
in which try-catch would be better, I've instead tried to reduce the number of 
exceptions actually thrown, without increasing memory usage by too much.

The changes aren't complete, so I won't mark the bug as "FIXED", but I hope what 
I've done thus far improves the situation.  These changes are available in the 
Xerces-J 1.4.2.
Comment 2 JosepM 2003-12-29 12:29:34 UTC
.