24

I am trying to add a object to a ArrayList and its throwing ArrayIndexOutOfBoundsException Following is the code

private void populateInboxResultHolder(List inboxErrors){
    inboxList = new ArrayList();
    try{                
        inboxHolder = new InboxResultHolder();
        //Lots of Code
        inboxList.add(inboxHolder);
    }catch(Exception e){
        e.printStackTrace();
    }
}

And the exception is

[3/7/12 15:41:26:715 UTC] 00000045 SystemErr     R java.lang.ArrayIndexOutOfBoundsException
[3/7/12 15:41:26:721 UTC] 00000045 SystemErr     R      at java.util.ArrayList.add(ArrayList.java:378)
[3/7/12 15:41:26:721 UTC] 00000045 SystemErr     R      at com.ml.fusion.ui.common.web.bean.inbox.InboxSearchBean.populateInboxResultHolder(InboxSearchBean.java:388)    
[3/7/12 15:41:26:721 UTC] 00000045 SystemErr     R      at com.ml.fusion.ui.common.web.bean.inbox.InboxSearchBean.searchInboxErrors(InboxSearchBean.java:197)
[3/7/12 15:41:26:721 UTC] 00000045 SystemErr     R      at com.ml.fusion.ui.common.web.bean.inbox.InboxSearchBean.viewInbox(InboxSearchBean.java:207)

But according to the signature of ArrayList.add it should not throw this exception. Please help.

wattostudios
  • 8,666
  • 13
  • 43
  • 57
mavrav
  • 550
  • 2
  • 6
  • 13
  • 2
    Well, since IndexOutOfBoundsException is a RuntimeException, it can be thrown without being mentionned in the method signature. – Jerome Mar 09 '12 at 10:25
  • 2
    `ArrayIndexOutOfBoundsException` is a runtime exception, not a checked exception, so it doesn't necessarily show up in the signature of the methods that throw it. – Giulio Piancastelli Mar 09 '12 at 10:25
  • thats right.But if you look at the add method itself there is no possibility of this exception getting thrown – mavrav Mar 09 '12 at 10:29

2 Answers2

42

ArrayList.add() should never throw an ArrayIndexOutOfBoundsException if used "properly" so it seems that you're using your ArrayList in a way which it does not support.

It's hard to tell from just the code you've posted but my guess is that you're accessing your ArrayList from multiple threads.

ArrayList isn't synchronised and so isn't thread safe. If this is the problem you can fix it by wrapping your List using Collections.synchronizedList().

Changing your code to the following should resolve the problem:

private void populateInboxResultHolder(List inboxErrors){
    List inboxList = Collections.synchronizedList(new ArrayList());
    try{                
        inboxHolder = new InboxResultHolder();
        //Lots of Code
        inboxList.add(inboxHolder);
    }catch(Exception e){
        e.printStackTrace();
    }
}
Soren Stoutner
  • 1,413
  • 15
  • 21
David Webb
  • 190,537
  • 57
  • 313
  • 299
  • I did think in that angle.But even in that case it should not throw that exception as we are doing add and not add(index,Obj). – mavrav Mar 09 '12 at 10:28
  • 5
    If you are accessing the `ArrayList` from multiple threads without synchronising it, it **will** break. What I think is happening is that two threads are trying to modify the `Array` which underlies the `ArrayList` at the same time, so it is not the correct size when one of the threads tries to add a new value. – David Webb Mar 09 '12 at 10:31
  • Shouldnt that throw ConcurrentModificationException? – mavrav Mar 09 '12 at 10:33
  • 2
    No. If you use something outside its contract it's behaviour becomes undefined. This means you can expect it to throw any `RuntimeException` or corrupt your data or do anything at all. The documentation is clear that `ArrayList` is not supported in multiple threads so will not have any defined behaviour in that case. – David Webb Mar 09 '12 at 10:35
  • I am not sure about that.Are you suggesting that it threw this exception becuase it couldnt get any other exception at the time? Even if it is concurrently accessed it should not be throwing this particular exception because we are not mentioning the index anywhere. – mavrav Mar 09 '12 at 10:41
  • 1
    It threw this Exception because it tried to add something to an `Array` with an index that was too big. The `ArrayList` stores its data in an `Array` and maintains the size of that `Array` automatically. But if you access an `ArrayList` from multiple threads simultaneously the `Array` maintaining code is not always run in the "correct order" and so you get your `ArrayIndexOutOfBoundsException`. Consider yourself lucky that you got an Exception and not just some corrupt or lost data. **If you are accessing your `ArrayList` from multiple threads this is definitely the source of your problem.** – David Webb Mar 09 '12 at 10:47
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/8704/discussion-between-mavrav-and-dave-webb) – mavrav Mar 09 '12 at 10:49
  • 1
    No thanks. There is nothing to discuss unless you have tried using `Collections.synchronisedList()` and that has not fixed the problem. – David Webb Mar 09 '12 at 10:50
  • when Jason Bourne says nothing to discuss, there is nothing to discuss :) – n00bc0der Jul 18 '23 at 01:42
-4

The code you posted will not throw ArrayIndexOutOfBoundsException.

The exception you get is thrown in the part you omitted. Take a look at your stacktrace. Its InboxSearchBean that causes the exception. Most likely it performs a get(index) on the list with an invalid index.

Durandal
  • 19,919
  • 4
  • 36
  • 70