Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

H2 server suspends while debugging

I have a Spring application that starts the following in memory H2 database for JUnit tests:

db.jdbc.driver=org.h2.Driver
db.jdbc.url=jdbc:h2:mem:sampledb
db.jdbc.username=
db.jdbc.password=
hibernate.dialect=org.hibernate.dialect.H2Dialect

I would like to easily debug when my JUnit tests are running and meantime browse database state, so before test suite I start H2 Server:

org.h2.tools.Server.createTcpServer("-tcpPort", "9092", "-tcpAllowOthers").start();

Unfortunately when I put any breakpoint that suspends all threads it also suspends H2 server thread, so I am not able to connect. I cannot start H2 server in different process because in memory database is not accessible from outside VM.

I understand that I can use other type of breakpoint (that suspends only current thread) but it's a kind of limitation. Have you found other solutions for such problem?

like image 496
Konrad Avatar asked Dec 15 '22 12:12

Konrad


2 Answers

Kind of an old question, but for those who happen to stumble over this thread and are looking for an easy answer:

Basically, you can set debugger breakpoints to either suspend all threads (in which case the H2 server will suspend too) or only the current thread - with this being the setting you are looking for, the H2 server will continue running.

E.g. if you are using IntelliJ, you right-click the break point (or Ctrl + Shift + F8 to open the "Breakpoints" dialog window) and set "Suspend Thread"

like image 185
Pawel Os. Avatar answered Dec 21 '22 11:12

Pawel Os.


Starting the tcp server will not help here, as you're creating a memory database.

I would suggest starting a console instead in a thread, and in the same piece of code (using jdbc for example) open a connection to this database but do not close/release it.

Do this with this snippet: please add options like allow others according to H2 documentation (I suggest leaving this as it is for now)

org.h2.tools.Server.createWebServer().start();

Opening the database in a 2nd thread with jdbc/jooq will look like this (this is in Nashorn javascript but can be easily adapted to java):

var conn = (new org.h2.Driver()).connect('jdbc:h2:mem:sampledb',new java.util.Properties());
var DB = org.jooq.impl.DSL.using(conn, org.jooq.SQLDialect.H2);

Like this, the memory based database will not be accidentally closed and you'll be able to access it remotely. Putting it in a thread hopefully will guard you from breakpoints.

Updates: Based on discussion with original author of this question, the best solution is to open the memory based H2 in a separate process and provide a tcp server on it. This solves the issue, but is in a separate process.

Here's how to start the separate process:

java -jar h2-1.4.188.jar -tcp -tcpPort 9092 -baseDir mem:mydb

Here's the JDBC url to use: jdbc:h2:tcp://localhost:9092/mem:mydb

IMPORTANT NOTE: If all connections on this memory based db are closed, the content will disappear. So this method is to be used with caution. If you need persistence through your tests, please use a standard file-based H2 DB.

like image 20
Christian MICHON Avatar answered Dec 21 '22 11:12

Christian MICHON