Raj
Raj

Reputation: 21

org.h2.jdbc.JdbcSQLException: General error: "java.lang.StackOverflowError" [50000-176]

Stackoverflow error while using H2 database in Multi Threaded Environment

Our Application has service layer querying H2 database and retrieving the resultset.

The service layer connects to the h2 database using opensource clustering middleware "Sequoia" (that offers load balancing and transparent failover) and also manages database connections .

https://sourceforge.net/projects/sequoiadb/

Our service layer has 50 service methods and we have exposed the service methods as EJB's . While Invoking the EJB's we get the response from service (that includes H2 READ) with an average response time of 0.2 secs .

The DAO layer, query the database using Hibernate Criteria and we also use JPA2.0 entity manager to manage datasource.

For Load testing , We created a test class (with a main method) that invokes all the 50 EJB Methods .

50 threads were created and all the threads invoked the test class . The execution was Ok for first run and all the 50 threads succssfully completed invoking 50 EJB methods .

When we triggered the test class again , we encountered "stackoverflowerror".The Detailed stacktrace is shown below

org.h2.jdbc.JdbcSQLException: General error: "java.lang.StackOverflowError" [50000-176]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:344)
    at org.h2.message.DbException.get(DbException.java:167)
    at org.h2.message.DbException.convert(DbException.java:290)
    at org.h2.server.TcpServerThread.sendError(TcpServerThread.java:222)
    at org.h2.server.TcpServerThread.run(TcpServerThread.java:155)
    at java.lang.Thread.run(Thread.java:784)
Caused by: java.lang.StackOverflowError
    at java.lang.Character.digit(Character.java:4505)
    at java.lang.Integer.parseInt(Integer.java:458)
    at java.lang.Integer.parseInt(Integer.java:510)
    at java.text.MessageFormat.makeFormat(MessageFormat.java:1348)
    at java.text.MessageFormat.applyPattern(MessageFormat.java:469)
    at java.text.MessageFormat.<init>(MessageFormat.java:361)
    at java.text.MessageFormat.format(MessageFormat.java:822)
    at org.h2.message.DbException.translate(DbException.java:92)
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:343)
    at org.h2.message.DbException.get(DbException.java:167)
    at org.h2.message.DbException.convert(DbException.java:290)
    at org.h2.command.Command.executeUpdate(Command.java:262)
    at org.h2.jdbc.JdbcPreparedStatement.execute(JdbcPreparedStatement.java:199)
    at org.h2.server.TcpServer.addConnection(TcpServer.java:140)
    at org.h2.server.TcpServerThread.run(TcpServerThread.java:152)
    ... 1 more

    at org.h2.engine.SessionRemote.done(SessionRemote.java:606)
    at org.h2.engine.SessionRemote.initTransfer(SessionRemote.java:129)
    at org.h2.engine.SessionRemote.connectServer(SessionRemote.java:430)
    at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:311)
    at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:107)
    at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:91)
    at org.h2.Driver.connect(Driver.java:74)
    at org.continuent.sequoia.controller.connection.DriverManager.getConnectionForDriver(DriverManager.java:266)

We then even added a random thread sleep(10-25 secs) between EJB Invocation . The execution was successful thrice (all 50 EJB Invocation) and when we triggered for 4th time ,it failed with above error .

We get to see the above failure even with a thread count of 25 .

The Failure is random and there doesn't seems to be a pattern . Kindly let us know if we have missed any configuration .

Please let me know if you need any additional information . Thanks in Advance for any help .

Technology Stack :

1) Java 1.6

2) h2-1.3.176

3) Sequoia Middleware that manages DB Connection Open and Close.

-Variable Connection Pool Manager 

-init pool size 250

Upvotes: 1

Views: 1578

Answers (2)

Raj
Raj

Reputation: 21

Thanks Lance Java for your suggestions . Increasing stack size didnt help in our scenario for the following reasons (i.e additional stack helped only for few more executions).

  • In Our App , we are using Entity Manager (JPA) and the transaction attribute was not set . Hence each query to the database , created a thread carrying out execution . In JVisualVm , we observed the DB Threads, the Live Threads was equal to Total Threads Started .

Eventually our app created more than 30K threads and hence has resulted in Stackoverflow error .

Upon Setting the transaction attribute , the threads get killed after DB execution and all the transactions are then managed by only 25-30 threads.

The Issue is resolved now .

Upvotes: 1

lance-java
lance-java

Reputation: 27994

There's two main causes for a stack overflow error

  1. A bug containing a non-terminating recursive call
  2. The allocated stack size for the jvm isn't big enough

Looking at your stack trace it doesn't look recursive so I'm guessing you are running out of space. Have you set the -Xss flag for your JVM? You might need to increase this value.

Upvotes: 0

Related Questions