Hi all,


I want to load a very large test case (> 3GB) into JMeter. However, a 
NegativeArraySizeException is thrown inside a BufferedInputStream while reading 
the file.*

In this mail, I describe the cause of the error, have a guess why JMeter works 
this way and suggest a patch.



Why does this occur?

1) JMeter's SaveService#readTree wraps the InputStream it receives in a 
BufferedInputStream (BIS).

2) It then tells the BIS to save all read data in memory up to a size of 
Integer.MAX_VALUE by calling reader.mark(Integer.MAX_VALUE).

3) XStream successfully reads in bytes from the BIS. As requested in 2), the 
BIS saves all the bytes read into an array buffer.

4) As the file is large, the BIS at some point calculates a buffer size 
exceeding the integer range. This integer is mapped to a negative value 
(integer overflow).

5) BIS tries to allocate a byte buffer with this negative size, yielding the 
error.



In my understanding of SaveService#readTree, the BIS wrapping was introduced to 
fall back to the old Avalon format: In case loading the .jmx failed, the BIS 
was reset to the beginning of the file and the OldSaveService tried loading the 
file. So the buffer was needed because a FileInputStream normally doesn't 
support marking.



Reading the JMeter 3.0 Changelist, the *.jtl import is dropped. XStream does 
not depend on the InputStream being a BIS. So I guess it is safe to remove the 
BIS wrapping avoiding the above bug. See the patch below for my suggestion.**



How should I proceed? Report a bug in Bugzilla?



Thanks,

Felix Draxler







*Java 8 will instead throw a OutOfMemoryError "Required array size too large" 
for very similar reasons, but later in the execution. In this mail, I describe 
the situation with Java 7.



**Possible patch for SaveService.java:

-        if (!reader.markSupported()) {

-             reader = new BufferedInputStream(reader);

-         }

-        reader.mark(Integer.MAX_VALUE);



Reply via email to