Bug 59607 - JMeter crashes when reading large test plan (greater than 2g)
Summary: JMeter crashes when reading large test plan (greater than 2g)
Status: RESOLVED FIXED
Alias: None
Product: JMeter
Classification: Unclassified
Component: Main (show other bugs)
Version: 3.0
Hardware: All All
: P2 normal (vote)
Target Milestone: ---
Assignee: JMeter issues mailing list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-05-20 08:12 UTC by felix.draxler
Modified: 2016-06-10 08:09 UTC (History)
2 users (show)



Attachments
JMeter log file (12.59 KB, text/plain)
2016-05-20 08:12 UTC, felix.draxler
Details
Proposed patch (1.15 KB, patch)
2016-05-20 09:04 UTC, felix.draxler
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description felix.draxler 2016-05-20 08:12:25 UTC
Created attachment 33856 [details]
JMeter log file

Summary:
Loading a very large test case crashes JMeter.

Steps to reproduce:
1) Generate a very large test case (> Integer.MAX_VALUE bytes or > 2.15GB).
2) Load it with JMeter (it's faster in non-GUI mode).

Expected result:
JMeter loads the test case after some time, then executes it.

Current result:
JMeter crashes, throwing a NegativeArraySizeException in BufferedInputStream. See the appended jmeter.log file.
Comment 1 felix.draxler 2016-05-20 08:13:05 UTC
Error analysis:
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.
Comment 2 felix.draxler 2016-05-20 08:21:28 UTC
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.

Bug 59064 states that the OldSaveService is now removed from JMeter. Thus, there seems to be no need for the BufferedInputStream wrapping in SaveService#readTree anymore. Why?
- XStream's XStream#fromXML(InputStream input) doesn't require an input stream that supports jumping in the file (called 'marking').
- This appears just right: Thinking about the structure of the test plan file format, we never need to jump back in the file: It is simply a dump of a tree without cross-references.
Comment 3 felix.draxler 2016-05-20 09:04:20 UTC
Created attachment 33857 [details]
Proposed patch

Remove BufferedInputStream wrapper, JMeter can now load very large files.
Comment 4 Sebb 2016-05-20 09:16:22 UTC
Or maybe just remove the mark
Comment 5 felix.draxler 2016-05-20 09:18:19 UTC
Yes, that should also do it.
Comment 6 Philippe Mouawad 2016-05-30 19:42:45 UTC
Author: pmouawad
Date: Mon May 30 19:42:27 2016
New Revision: 1746175

URL: http://svn.apache.org/viewvc?rev=1746175&view=rev
Log:
Bug 59607 - JMeter crashes when reading large test plan (greater than 2g)
Bugzilla Id: 59607

Modified:
    jmeter/trunk/src/core/org/apache/jmeter/save/SaveService.java
    jmeter/trunk/xdocs/changes.xml
Comment 7 Philippe Mouawad 2016-05-30 19:52:20 UTC
Thanks for analysis.
Bug has been fixed in nightly build:
- http://jmeter.apache.org/nightly.html

If you can test and give feedback it would be nice.
Thanks
Comment 8 felix.draxler 2016-06-10 08:09:24 UTC
Yes, works. Thanks for including the fix!