Hi BaseX team,

 

Using BaseX 7.7 in an embedded Java Application Server I’ve encountered the following reproducible error. The error occurs if the same query is issued the second time after the first has been successfully executed (after restarting the server the query will run again the first time ok and the second time with this error). This indicates a potential concurrency or non-closed cursor bug to me, but I don’t see the problem and surely we shouldn’t get an java.lang.ArrayIndexOutOfBoundsException even if with my bad code quality.

Could you please have a look and advise to improve my code, or fix a potential bug?

 

Many thanks in advance,

Bodo

 

Error stack trace:

 

WARNING 2013.11.19 23:00:36 Error while loading document: sqlQuery_ora_F30929C659D0CED7525C61A7D149E7D4C0301A18

org.basex.core.BaseXException: Improper use? Potential bug? Your feedback is welcome:

Contact: basex-talk@mailman.uni-konstanz.de

Version: BaseX 7.7

Java: Oracle Corporation, 1.7.0_15

OS: Windows 7, amd64

Stack Trace:

java.lang.ArrayIndexOutOfBoundsException: 2

                at org.basex.io.random.TableDiskAccess.flush(TableDiskAccess.java:124)

                at org.basex.data.DiskData.finishUpdate(DiskData.java:212)

                at org.basex.core.cmd.Add.run(Add.java:109)

                at org.basex.core.Command.run(Command.java:345)

                at org.basex.core.Command.exec(Command.java:321)

                at org.basex.core.Command.execute(Command.java:78)

                at org.basex.core.Command.execute(Command.java:90)

                at org.basex.server.ClientListener.execute(ClientListener.java:386)

                at org.basex.server.ClientListener.add(ClientListener.java:357)

                at org.basex.server.ClientListener.run(ClientListener.java:100)

 

                at org.basex.server.ClientSession.receive(ClientSession.java:259)

                at org.basex.server.ClientSession.send(ClientSession.java:246)

                at org.basex.server.ClientSession.send(ClientSession.java:284)

                at org.basex.server.ClientSession.add(ClientSession.java:134)

                at de.infabswissarmy.control.XMLDBManagerBaseX.putDoc(XMLDBManagerBaseX.java:252)

                at de.infabswissarmy.control.XMLDBManagerBaseX.putDoc(XMLDBManagerBaseX.java:56)

                at de.infabswissarmy.control.QueryTask.sqlQuery(QueryTask.java:258)

                at de.infabswissarmy.control.QueryTask.query(QueryTask.java:138)

                at de.infabswissarmy.control.QueryTask.run(QueryTask.java:283)

                at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

                at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

                at java.lang.Thread.run(Unknown Source)

org.basex.core.BaseXException: java.nio.channels.OverlappingFileLockException

                at org.basex.server.ClientQuery.cache(ClientQuery.java:81)

                at org.basex.server.Query.more(Query.java:74)

                at de.infabswissarmy.control.XMLDBManagerBaseX.query(XMLDBManagerBaseX.java:86)

                at de.infabswissarmy.control.XMLDBManagerBaseX.queryDoc(XMLDBManagerBaseX.java:131)

                at de.infabswissarmy.control.QueryTask.query(QueryTask.java:192)

                at de.infabswissarmy.control.QueryTask.run(QueryTask.java:283)

                at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

                at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

                at java.lang.Thread.run(Unknown Source)

 

Relevant source extract:

  private static void putDoc(String inContainerName, String inDocumentRef, byte[] inDocument){

       ClientSession mySession = null;

       try {

              mySession = getClientSession();

              // document already exists?

              if(existsDoc(inContainerName, inDocumentRef)){

                     // delete old document

                    mySession.execute(new Open(inContainerName));

                     mySession.execute(new Delete(inDocumentRef));

              }

              mySession.execute(new Open(inContainerName));

              // add new document

              mySession.add(inDocumentRef, new ByteArrayInputStream(inDocument));

             } catch (IOException e) {

                    logger.warning("Error while loading document: " + inDocumentRef);

                    e.printStackTrace();

             }finally {

                    if (mySession != null){

                           try {

                                  mySession.close();

                           } catch (IOException e) {}

                    }

              }

       }

 

public ArrayList<String> query(String inQuery, String[][] inArgs){

       ClientSession mySession = null;

       ClientQuery myQuery = null;

       ArrayList<String> tmpString = new ArrayList<String>();

             try {

                    mySession = getClientSession();

                    myQuery = mySession.query(inQuery);

      

                 // bind variable

                 if (inArgs != null){

                   for (int i=0; i < inArgs.length; i++){

                   myQuery.bind("$" + inArgs[i][0], inArgs[i][1]);

                   }

                 }

                

                 while (myQuery.more()){

                   tmpString.add(myQuery.next());

                 }

             } catch (IOException e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

             } finally {

                    if (myQuery != null){

                           try {

                                  myQuery.close();

                           } catch (BaseXException e) {

                                  // ignore

                           } catch (IOException e) {

                                  // TODO Auto-generated catch block

                                  e.printStackTrace();

                           }

                    }

                    if (mySession != null){

                           try {

                                  mySession.close();

                           } catch (BaseXException e){

                                  //ignore

                           } catch (IOException e){

                                  // TODO Auto-generated catch block

                                  e.printStackTrace();

                           }

                    }

             }

    return tmpString;

  }