2

I am working on my code and getting "java.util.ConcurrentModificationException". I googled it and also know that such error comes only when you try to modify on-going iterative variable, which I don't feel in my case. Below is my code.

// This line is having an error
for(Statement s: _mConsumableStatements)
    {
        System.out.println("s:"+s);

        Boolean isConflict=false;
        Resource uri=s.getSubject();

        System.out.println("uri:"+uri);
        System.out.println("1");

        if(RepStatementsAsHash.containsKey(uri))
        {
            System.out.println("2");

            if(RepStatementsAsHash.get(uri).containsKey(RDFS.LABEL))
                RepStatementsAsHash.get(uri).remove(RDFS.LABEL);
            else if(RepStatementsAsHash.get(uri).containsKey(RDFS.SUBCLASSOF))
                RepStatementsAsHash.get(uri).remove(RDFS.SUBCLASSOF);
            else if(RepStatementsAsHash.get(uri).containsKey(RDFS.RANGE))
                RepStatementsAsHash.get(uri).remove(RDFS.RANGE);
            else if(RepStatementsAsHash.get(uri).containsKey(RDF.TYPE))
            {
                System.out.println("2.1");

                Value RepTypeObject=RepStatementsAsHash.get(uri).get(RDF.TYPE);
                Value ConsumableTypeObject=CStatements.get(uri).get(RDF.TYPE);

                if (RepTypeObject.stringValue().equals(OWL.CLASS) || RepTypeObject.stringValue().equals(RDFS.CLASS))
                {
                    if(ConsumableTypeObject.stringValue().equals(OWL.DATATYPEPROPERTY) || ConsumableTypeObject.stringValue().equals(OWL.OBJECTPROPERTY) || ConsumableTypeObject.stringValue().equals(RDF.PROPERTY))
                    {
                        isConflict=true;
                        //_mConflictingStatements.add(s);
                    }
                    else
                    {
                        RepStatementsAsHash.get(uri).remove(RepTypeObject);
                    }
                }
                else if(RepTypeObject.stringValue().equals(OWL.DATATYPEPROPERTY) || ConsumableTypeObject.stringValue().equals(OWL.OBJECTPROPERTY) || RepTypeObject.stringValue().equals(RDF.PROPERTY))
                {
                    if (ConsumableTypeObject.stringValue().equals(OWL.CLASS) || ConsumableTypeObject.stringValue().equals(RDFS.CLASS))
                    {
                        isConflict=true;
                        //_mConflictingStatements.add(s);
                    }
                    else
                    {

                    }
                }
                else
                {
                    if( !(RepTypeObject.stringValue().equals(OWL.DATATYPEPROPERTY) || ConsumableTypeObject.stringValue().equals(OWL.OBJECTPROPERTY) || RepTypeObject.stringValue().equals(RDF.PROPERTY) || ConsumableTypeObject.stringValue().equals(OWL.CLASS) || ConsumableTypeObject.stringValue().equals(RDFS.CLASS))  )
                    {
                        if(RepTypeObject.stringValue()!=ConsumableTypeObject.stringValue())
                        {
                            isConflict=true;
                        }

                    }
                }
                System.out.println("2.2");
                if(!isConflict)
                    {
                        addStatementsInRepository(uri.stringValue(),c_import);
                    }
            } // LABEL-TYPE 
        }
        else // No  URI Conflict
            addStatementsInRepository(uri.stringValue(),c_import);

        System.out.println("3");
    }

It is showing error something like :

11:13:24.405 ERROR - error while importing Sesame data:
java.util.ConcurrentModificationException: null
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859) ~[na:1.7.0_71]
    at java.util.ArrayList$Itr.next(ArrayList.java:831) ~[na:1.7.0_71]
    at org.apache.marmotta.platform.core.services.importer.rdf.RDFImporterImpl.importData2(RDFImporterImpl.java:433) [ulysses-core-1.0-alpha-2.jar:1.0-alpha-2]

How to resolve it?

Kalle Richter
  • 8,008
  • 26
  • 77
  • 177
Pratik
  • 367
  • 2
  • 4
  • 11

1 Answers1

1

On this line, like many others in your code: RepStatementsAsHash.get(uri).remove(RepTypeObject);, you are iterating through the loop, and removing it whilst iterating. You can use an Iterator to iterate through a list or map, and then remove elements using iterator.remove().

Example

Community
  • 1
  • 1
loafy
  • 105
  • 1
  • 11
  • But in that line I am removing "RepTypeObject" from another HashTable "RepStatementsAsHash" . How is it related to it? – Pratik Feb 16 '15 at 04:25
  • @Pratik You can iterate through a HashTable as you would with a HashMap. I provided an example in my answer. Instead of using a for each loop, use a while loop. – loafy Feb 16 '15 at 04:36
  • 1
    My question is why should I do like that? Cause I am not changing an on-going iterative variable. What you are suggesting is different HashTable . Please convince for your answer, I am not getting why you are suggesting for RepStatementsAsHash object. – Pratik Feb 16 '15 at 04:38
  • @Pratik using iterator.remove() will avoid a ConcurrentModificationException. It would be useful if you provided where you have defined "_mConsumableStatements", and some relevant code from RepTypeObject and RepStatementsAsHash. It's very hard to solve your problem with the little code that you have provided. – loafy Feb 16 '15 at 04:43
  • 1
    Anyways I got the reason. addStatementsInRepository() method was modifying the same iterator. – Pratik Feb 16 '15 at 04:49