Connection is closed Caused by: java.io.EOFException

#1

I am getting this exception on a regular basis, after a period of time of repeating the same code execution.  I don't understand why.  I restart the DB server and my code works again for another period of time until same exception is encountered again.  I cannot pin down a pattern e.g. after a certain period of time,  because the time  periods between exceptions are not regular, although frequent.  Any test case  I use will pass most of the time but will fail after an undetermined period.

Caused by: com.objectdb.o.UserException: Connection is closed
        at com.objectdb.o.MSG.d(MSG.java:74)
        at com.objectdb.o.CLS.Q(CLS.java:317)
        at com.objectdb.o.CLS.P(CLS.java:281)
        at com.objectdb.o.CLS.M(CLS.java:173)
        at com.objectdb.o.CLS.L(CLS.java:142)
        at com.objectdb.o.CST.<init>(CST.java:65)
        at com.objectdb.o.CSF.UH(CSF.java:88)
        at com.objectdb.o.OMF.ai(OMF.java:725)
        at com.objectdb.jpa.EMF.ai(EMF.java:143)
        at com.objectdb.o.OMF.ah(OMF.java:681)
        at com.objectdb.jpa.EMF.createEntityManager(EMF.java:160)
        ... 39 more
Caused by: java.io.EOFException
        at com.objectdb.o.NTS.z(NTS.java:317)
        at com.objectdb.o.NTS.y(NTS.java:274)
        at com.objectdb.o.CLS.R(CLS.java:327)
        at com.objectdb.o.CLS.P(CLS.java:274)

 

It appears to happen when the database is creating an EntityManager.   I have checked throughout my code to ensure that  all instances of EntityManager that I create are closed immediately after use in a finally{} clause 

Have I run out of connections? Or is there something obvious that I am not seeing?

I am using objectdb-2.2.6_03  on Windows XP Professional SP2  with jdk1.6.0_17

My conf is close to the default

<objectdb>

<general>
  <temp path="$temp/ObjectDB" threshold="64mb" />
  <network inactivity-timeout="0" />
  <log path="$objectdb/log/" max="8mb" stdout="false" stderr="false" />
  <log-archive path="$objectdb/log/archive/" retain="90" />
  <logger name="*" level="info" />
</general>

<database>
  <size initial="256kb" resize="256kb" page="2kb" />
  <recovery enabled="true" sync="false" path="." max="128mb" />
  <recording enabled="false" sync="false" path="." mode="write" />
  <locking version-check="true" />
  <processing cache="64mb" max-threads="10" />
  <query-cache results="32mb" programs="500" />
</database>

<entities>
  <enhancement agent="false" reflection="warning" />
  <cache ref="weak" level2="0" />
  <cascade-persist always="auto" on-persist="false" on-commit="true" />
  <dirty-tracking arrays="false" />
</entities>

<schema>
</schema>

<server>
  <connection port="6136" max="100" />
  <data path="$objectdb/db-files" />
  <!--
  <replication url="objectdb://localhost/test.odb;user=admin;password=admin" />
  -->
</server>

<users>
  <user username="admin" password="admin" ip="127.0.0.1" admin="true">
   <dir path="/" permissions="access,modify,create,delete" />
  </user>
  <user username="$default" password="$$$###">
   <dir path="/$user/" permissions="access,modify,create,delete">
    <quota directories="5" files="20" disk-space="5mb" />
   </dir>
  </user>
  <user username="user1" password="user1" />
</users>

<ssl enabled="false">
  <server-keystore path="$objectdb/ssl/server-kstore" password="pwd" />
  <client-truststore path="$objectdb/ssl/client-tstore" password="pwd" />
</ssl>

</objectdb>

 

What could be causing my ObjectDB server to stop ?

Of course, the exception encountered is a symptom of the real problem that the server has stopped!

#2

Actually, I was concentrating so much on my own logs that I neglected the ObjectDB logs!   The cause is more obvious from what is written there...

com.objectdb.o.UserException: Too many open connections (100)
at com.objectdb.o.MSG.d(MSG.java:61)
at com.objectdb.o.SMR.O(SMR.java:475)
at com.objectdb.o.SMR.N(SMR.java:412)
at com.objectdb.o.SMR.L(SMR.java:274)
at com.objectdb.o.SMR.n(SMR.java:166)
at com.objectdb.o.TOL.run(TOL.java:115)
at com.objectdb.Server.runCommand(Server.java:194)
at com.objectdb.Server.run(Server.java:107)
at com.objectdb.Server.main(Server.java:66)

So the maximum of 100 connections has been exceeded.  So do I need to explicitly close some connections?  Does the database not reassign them to the pool?

 

#3

Following the server side stack trace (in #2) - the exception could be easily reproduced:

import javax.persistence.*;

public final class Test {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory(
            "objectdb://localhost/test.odb;user=admin;password=admin");
        for (int i = 0; i < 1000; i++) {
            System.out.println(i);
            emf.createEntityManager();
        }
    }
}

Notice that the EntityManager instances above are never closed.

If they are closed, as demonstrated below - no exception is thrown:

import javax.persistence.*;

public final class Test {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory(
            "objectdb://localhost/test.odb;user=admin;password=admin");
        for (int i = 0; i < 1000; i++) {
            System.out.println(i);
            emf.createEntityManager().close();
        }
    }
}

Please check if your application might create EntityManager instances without closing them.

By the way, following your report the exception on the client side was changed, so starting next build it will be same as the more meaningful exception that you found in the ObjectDB server log.

ObjectDB Support
#4

I have discovered my problem.  Although I was closing all instance of EntityManager that I created,  I was not closing the EntityManagerFactory.  I have now added a method which I explicitly call  after I am finished with use of the Persistence Unit.

private EntityManagerFactory emf;

    public void closeConnection() {

        if(emf.isOpen())

            emf.close();
    }

 

Thanks for all your help!

#5

Yes, this is a good point. The EntityManagerFactory keeps at least one shared connection (and usually other connections in the pool), so it must be closed to release these connections.

By the way, usually a single EntityManagerFactory is sufficient to represent the database, so you may check if it is really essential to create so many EntityManagerFactory instances for the same database, since it might not be very efficient.

ObjectDB Support
#6

Yes, I am only creating one EntityManagerFactory.   The Persistence Unit is deployed in restful web service, so only a single instance per the life-cycle of the service request.  At each stateless request, the EntityManagerFactory would be created from the Persistence Unit,  and (as I now realise) needs to be closed before the service sends its response.

 

 

Reply