You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-dev@xerces.apache.org by bu...@apache.org on 2001/02/27 18:30:49 UTC

[Bug 730] New - NullPointerExceptions and ArrayIndexOutOfBoundsExceptions used for normal program control

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=730

*** shadow/730	Tue Feb 27 09:30:49 2001
--- shadow/730.tmp.625	Tue Feb 27 09:30:49 2001
***************
*** 0 ****
--- 1,96 ----
+ +============================================================================+
+ | NullPointerExceptions and ArrayIndexOutOfBoundsExceptions used for normal  |
+ +----------------------------------------------------------------------------+
+ |        Bug #: 730                         Product: Xerces-J                |
+ |       Status: NEW                         Version: 1.3.0                   |
+ |   Resolution:                            Platform: PC                      |
+ |     Severity: Normal                   OS/Version:                         |
+ |     Priority:                           Component: Core                    |
+ +----------------------------------------------------------------------------+
+ |  Assigned To: xerces-j-dev@xml.apache.org                                  |
+ |  Reported By: jo2847@sbc.com                                               |
+ |      CC list: Cc:                                                          |
+ +----------------------------------------------------------------------------+
+ |          URL:                                                              |
+ +============================================================================+
+ |                              DESCRIPTION                                   |
+ 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;
+ 	}