0

I this is my code which adds elements to ArrayList

if(countries==null){
  countries = new ArrayList();
  for(int x = 0; x < data.getRowCount(); x++)
  {
      String shortName = data.getString(x,0);
      String code = data.getString(x,1);
      countries.add(x, new Country(code, shortName));
  }
}

And following is the iterator code

for( Iterator iter = countries.iterator(); iter.hasNext();)
{
   Country country = (Country)iter.next();
   Element optionselect = doc.createElement( "countryselect" );
   optionselect.setAttribute( "name", country.getShortName() );//Getting NULL Pointer Exception
   optionselect.setAttribute( "value", country.getCode() );
   countriesElement.appendChild( optionselect );
}

Now I am getting null pointer exception at line:

optionselect.setAttribute( "name", country.getShortName() );

PS: I cannot debug it as it is running on production and i cannot replicate it on local server

From the first look it looks like there is some value null in the ArrayList, but from code I cannot make out how it is possible.

Can someone shed some light on it(maybe a bug of Java 5).

EDIT: I am also getting null pointer with this code

List countryCodes = new ArrayList();
for (int x = 0; x < countries.size(); x++)
{
    Country c = (Country) countries.get(x);
    countryCodes.add(x, c.getCode());// Throwing Exception
}

This confirm one thing that there is somewhere null object in the countries List, but looking at the code I cannot see how is that possible

The stack traces are as follow:

Stack Trace:java.lang.NullPointerException
    at com.ilrn.controller.modules.Users.appendCountryList(Users.java:985)
    at com.ilrn.controller.modules.Users.setupCountries(Users.java:1348)
    at com.ilrn.controller.modules.Users.gen_add(Users.java:1329)
    at com.ilrn.controller.modules.Users.generate(Users.java:190)
    at com.ilrn.controller.ShellModule.generateShell(ShellModule.java:1958)

Users.java:985 is optionselect.setAttribute( "name", country.getShortName() );

Stack Trace(number 2):java.lang.NullPointerException
    at com.ilrn.controller.dto.IlrnCountriesDTO.getCountryCodes(IlrnCountriesDTO.java:45)
    at sun.reflect.GeneratedMethodAccessor471.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:592)

Where IlrnCountriesDTO.java:45 is countryCodes.add(x, c.getCode());

Also please note that countries List is loaded only once(when requested first time and countries is private)

After analyzing I think this is a multi threading issue. After looking at the ArrayList code I see it is not synchronized(so maybe size was incremented two time for same index)

 public void add(int index, E element) {
    if (index > size || index < 0)
      throw new IndexOutOfBoundsException(
      "Index: "+index+", Size: "+size);
  ensureCapacity(size+1);  // Increments modCount!!
  System.arraycopy(elementData, index, elementData, index + 1,
         size - index);
  elementData[index] = element;
  size++;
 }

this is the country class(snipet)

private String code_;
private String shortName_;

/**
 * Constructor sets code and short name.
 * 
 * @param code Specifies the code.
 * @param shortName Specifies the short name.
 */
public Country(String code, String shortName)
{
    code_ = code;
    shortName_ = shortName;
}
public String getCode() {
        return code_;
}

public String getShortName() {
        return shortName_;
}
15
  • Do not append things to a list while iterating over it! You append to countries while iterating over its values; this may result in bizarre exceptions, or even an infinite loop. It's hard to see how this code could possibly work in its current state. Commented Nov 16, 2012 at 6:58
  • THe check for !=null is leaking, you can try for an equal check and in the else part you can add your code Commented Nov 16, 2012 at 6:59
  • @SashiKant Leaking in what way? Commented Nov 16, 2012 at 7:01
  • 1
    There are two scenarios : either "(Country)iter.next()" returns null, either "doc.createElement( "countryselect" ). Commented Nov 16, 2012 at 7:16
  • 1
    Is countries initialization code 'accessible' by multiple threads? Commented Nov 16, 2012 at 7:39

1 Answer 1

1

Your adding code looks a little off... You have

if (countries != null){
    countries = new ArrayList();
    ...

but shouldn't it be:

if (countries == null){
    countries = new ArrayList();

Normally, we initialise if something is null, otherwise we'd be blowing away anything that was already there.

Sign up to request clarification or add additional context in comments.

1 Comment

I noted that too, but it can't cause the NPE OP is complaining about. Unless his line numbers are off and the NPE is on countries.iterator()

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.