function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
mpolimpoli 

System.ListException: Split results in a list that exceeds limits

Hi, I'm trying to parse a large string (~6570 characters) in apex through splitting. Specifically, I have the whole string separated about evenly into 8 sections by pipe ('|') characters (so very roughly about 821 characters per list element).

These lists are split even further, but I have commented out that code, and I still receive the error

System.ListException: Split results in a list that exceeds limits

upon splitting the first, biggest string into just 8 segments.

I'm not sure if the big picture is needed, so I'll try to describe it as concisely as I can. In my visualforce page, the giant string is constructed in javascript, then sent through an actionFunction as a param to the apex code on the server side. The receiving method then sends the giant string to an asynchronous method that parses the string and updates approximately 150 records. It is in this function where the error occurs.

I do not understand what limit I am breaking, so I was hoping someone could please clarify. Has anyone else possibly run into the same or similar problem? Moreover, is there another method I can use to parse the string that would circumvent the issue? I'm still new to salesforce and apex/visualforce development, so I'm still learning these limitations and their corresponding workarounds.

Thank you.
Best Answer chosen by Admin (Salesforce Developers) 
ahab1372ahab1372

found it.

The problem is the | you are using to separate the strings. The split method also accepts regular expression, and in regExp | means OR. With | the split method tries to split into every single character.

 

You can verify in the system log:

 

string entireStr2 = 'abcd|defg|hjkl|lmnopqr|stu'; System.Debug(entireStr2); List<string> stringlist = entireStr2.split('|', 0); System.Debug(stringlist);

 

 from the log:

15:17:33 INFO - 20090821221733.758:AnonymousBlock: line 3, column 1: abcd|defg|hjkl|lmnopqr|stu 20090821221733.758:AnonymousBlock: line 5, column 1: (, a, b, c, d, |, d, e, f, g, ...)

 

 

 

You have to double escape the |, once for Apex and once for the regex I think. The following should work

 

 

string entireStr2 = 'abcd|defg|hjkl|lmnopqr|stu'; System.Debug(entireStr2); List<string> stringlist = entireStr2.split('\\|', 0); System.Debug(stringlist);

 

 

 

 

 

All Answers

mpolimpoli

Just to make sure (and in case anyone needed to know or was curious), I wrote some javascript that splits the entire string on the client side and outputs both the resulting array size, as well as the size of each of the elements:

Total size of the array = 8 elements
Size of element 1 = 546 characters
Size of element 2 = 838 characters
Size of element 3 = 859 characters
Size of element 4 = 912 characters
Size of element 5 = 859 characters
Size of element 6 = 782 characters
Size of element 7 = 966 characters
Size of element 8 = 801 characters

 

So it should definitely be able to handle objects of these sizes.

ahab1372ahab1372

can you post the relevant lines of code? It would help to understand how the giant string is parsed into the list.

Do I understand correctly that the list is supposed to hold the 8 substrings?

 

Arnt

mpolimpoli

Hi Ahab,

 

Here is the actionFunction in the beginning that sends the string to the server to be processed by the "save" method:

 

<apex:form >
<apex:actionFunction name="passData" action="{!save}" rerender="otherstuff">
<apex:param id="entireStr" name="entireStr" value="" assignTo="{!entireStr}" />
</apex:actionFunction>
</apex:form>

 

The following javascript extracts information from elements in the page and constructs a large string (~6570 characters). This string is sent to my Apex code when "passData" is called. Essentially, my goal in my apex code was to split on the '|' characters to separate organizations into groups by type (8 types). Then I'd split each of those groups into individual organizations on the '`' characters. Finally, I'd split each organization string on the '~' character to obtain field information. Note: the commented alert at the end was to make sure that the string was being constructed correctly.

 

// Construct entireStr
var parseList2 = function(ul, stage)
{
var out = "";
var items2 = ul.getElementsByTagName("li");
var i2;
for (i2 = 0; i2 < items2.length; i2 = i2 + 1)
{
var id = items2[i2].id;
var name = items2[i2].firstChild.innerHTML;
var high = items2[i2].firstChild.nextSibling.nextSibling.nextSibling.innerHTML;
var low = items2[i2].firstChild.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.innerHTML;
out += id + "~" + name + "~" + high.substring(1, high.length) + "~" + low.substring(1, low.length) + "~"

+ stage + "`";
}
return out.substring(0, out.length - 1); // Remove final '`'
};


var entireStr = "";

var stagesLst = ("{!stagesStr}").split("|");
var numStages = {!numStages};
var y;
for (y = 1; y <= numStages; y++)
{
var ulx = Dom.get("ul" + y);
entireStr += parseList2(ulx, stagesLst[y - 1]) + "|";
}

//alert(entireStr.substring(0, entireStr.length - 1)); // Remove final '|'
passData(entireStr.substring(0, entireStr.length - 1)); // Remove final '|'

 

 In my controller, I need to hand off the string to an asynchronous method, since I plan to update over 140 records, so I call an asynchronous method from "save". At the moment, I've commented out all other code aside from the first split (which I've confirmed through javascript only splits into 8 elements), and this is where the limit is supposedly being reached:

 

public pageReference save()
{
save2(entireStr); // Call future method

// some commented code for now

return null;

}

@future
static void save2(String entireStr2)
{
for (String curString : entireStr2.split('|', 0))

{

// commented code for now

}

}

 

Please let me know if further clarification is needed, and thank you.

mpolimpoli
Oh, and yes, the split string currently should hold 8 substrings.
ahab1372ahab1372

have you tried analysing the string in the System log? Maybe the string created by Javascript is passed on several times or there are unexpected | in there.

Maybe you get more clues if you split to a dedicated list variable first before you use it in the for loop

 

 

System.Debug(entireStr2); List<string> stringlist = entireStr2.split('|', 0); System.Debug(stringlist);

 

 

 

mpolimpoli
Yes, I have tried using debug statements to examine the string being passed (as well as to confirm that it is only being sent once). In the debug log, the string has exactly 7 pipe characters. I've also tried various methods of splitting, including putting it into an explicitly-defined new list, as you suggested.
mpolimpoli

Update:

 

In order to isolate and duplicate the problem, I created a separate test page and controller. The code is as follows:

 

(Controller)

 

public with sharing class testSplitCon {

public String entireStr{get;set;}
public List<String> splitString{get;set;}

public testSplitCon()
{
entireStr = '...'; // entireString from before
// hard-coded in place of ...

splitString = entireStr.split('|', 0);
}

}

( Visualforce page)

 

<apex:page controller="testSplitCon">
<apex:repeat value="{!splitString}" var="s" id="theRepeat">
{!s}<br/>
</apex:repeat>
</apex:page>

 Running this generates the same error.

 

 

 

 

mpolimpoli

If anybody's curious or runs into the same problem, I implemented my own dumb little split function, and it worked just fine for my purposes.

 

Integer prevPos = 0; Integer index = 0; splitString = new List<String>(); while (index != -1 && prevPos < entireStr.length()) { index = entireStr.indexOf('|', prevPos); if (index != -1) { splitString.add(entireStr.substring(prevPos, index)); prevPos = index + 1; // Start next loop at character after pipe } } splitString.add(entireStr.substring(prevPos, entireStr.length())); // Add final element

 

Hope this helps.
ahab1372ahab1372

found it.

The problem is the | you are using to separate the strings. The split method also accepts regular expression, and in regExp | means OR. With | the split method tries to split into every single character.

 

You can verify in the system log:

 

string entireStr2 = 'abcd|defg|hjkl|lmnopqr|stu'; System.Debug(entireStr2); List<string> stringlist = entireStr2.split('|', 0); System.Debug(stringlist);

 

 from the log:

15:17:33 INFO - 20090821221733.758:AnonymousBlock: line 3, column 1: abcd|defg|hjkl|lmnopqr|stu 20090821221733.758:AnonymousBlock: line 5, column 1: (, a, b, c, d, |, d, e, f, g, ...)

 

 

 

You have to double escape the |, once for Apex and once for the regex I think. The following should work

 

 

string entireStr2 = 'abcd|defg|hjkl|lmnopqr|stu'; System.Debug(entireStr2); List<string> stringlist = entireStr2.split('\\|', 0); System.Debug(stringlist);

 

 

 

 

 

This was selected as the best answer
mpolimpoli
Haha wow. I totally missed that when I implemented it. Thanks so much!