Hi Evgenij, thank you for your answer.

I have been working on my project since you posted your answer and now I 
can say I have solved the problem by following your suggestion of creating 
the database in another process, with a local url.

The only modifications I needed from your code where the -tcpDaemon option, 
otherwise the exec-maven-plugin goal will be blocked in the execution, and 
the -tcpPassword option in the creation and shutting down of the server.

Actually the whole workflow was successful even without a TCP password, but 
the shutdown method "Server.shutdownTcpServer" would fail with this error 
if the used password is a blank String (""):
org.h2.jdbc.JdbcSQLInvalidAuthorizationSpecException: Wrong user name or 
password [28000-200]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:461)
at org.h2.message.DbException.getJdbcSQLException(DbException.java:429)
at org.h2.message.DbException.get(DbException.java:205)
at org.h2.message.DbException.get(DbException.java:181)
at org.h2.message.DbException.get(DbException.java:170)
at org.h2.engine.Engine.validateUserAndPassword(Engine.java:357)
at org.h2.engine.Engine.createSessionAndValidate(Engine.java:176)
at org.h2.engine.Engine.createSession(Engine.java:166)
at org.h2.server.TcpServerThread.run(TcpServerThread.java:168)
at java.lang.Thread.run(Thread.java:748)

at org.h2.message.DbException.getJdbcSQLException(DbException.java:461)
at org.h2.engine.SessionRemote.done(SessionRemote.java:611)
at org.h2.engine.SessionRemote.initTransfer(SessionRemote.java:147)
at org.h2.engine.SessionRemote.connectServer(SessionRemote.java:435)
at 
org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:321)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:173)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:152)
at org.h2.Driver.connect(Driver.java:69)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:247)
at org.h2.server.TcpServer.shutdown(TcpServer.java:466)
at org.h2.tools.Server.shutdownTcpServer(Server.java:381)
at it.unifi.dinfo.stlab.viola.backend.H2Manager.stopDB(H2Manager.java:49)
at it.unifi.dinfo.stlab.viola.backend.H2Manager.main(H2Manager.java:65)
at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:254)
at java.lang.Thread.run(Thread.java:748)

By specifying a password both at creation and at shutdown time, I was able 
to get rid of this error. Maybe this could be a bug?

Furthermore, I have removed the -tcpAllowOthers flag, as you suggested, 
because I actually did not need it. I originally added it as I thought it 
was madatory when using the TCP server.

For future referece I report here the approach which works for me to use H2 
as database in my integration servers using Arquillian. This assumes the 
need of testing a JEE REST application using Arquillian and JPA.

   - create a datasource to deploy inside Arquillian micro-deployment. This 
   uses the tcp url to the database
   - create a utility class to manage server creation and shut down. There 
   are some examples on StackOverflow (e.g. this answer 
   <https://stackoverflow.com/a/30455183>)
   - in the utility class, use the code by Evgenij (previous post) to 
   create the database with DriverManager.getConnection(...).close(). Here use 
   a local url (not involving tcp)
   - in the same class and method, just after creating the database, start 
   the server (with -tcpDaemon option)
   - configure exec-maven-plugin to run in pre-integration-test phase. It 
   should run your utility class method that creates the database and start 
   the server. Specify <cleanupDaemonThreads>false</cleanupDaemonThreads> in 
   the configuration of the plugin (e.g. this SO answer 
   <https://stackoverflow.com/a/16057845>)
   - configure exec-maven-plugin to run in post-integration-test phase. It 
   should run your utility class method that shuts down the tcp server
   - In your test case, create an EntityManagerFactory that uses a 
   persistence unit with a tcp url to the database created in the utility class


Now you should be able to use the EntityManager inside the test case to 
populate the database, and the same database is used by the war deployed on 
the Application Server by Arquillian.

Thank you again for your assistence.

Greetings,
Ivan

Il giorno mercoledì 10 giugno 2020 10:58:34 UTC+2, Evgenij Ryazanov ha 
scritto:
>
> Hello.
>
> Why you're using -tcpAllowOthers? Do you really need to connect to your 
> testing system from other hosts? Combination of this setting 
> with -ifNotExists effectively creates a remote security hole on your 
> system, -ifNotExists should not be normally used even for local 
> connections, local security hole is not as critical as remote one, but it 
> could be exploited in some cases anyway.
>
> Actually you should start a separate Java process with the following code:
>
> // Create a local database
> DriverManager.getConnection("jdbc:h2:mem:H2-db;DB_CLOSE_DELAY=-1", "user", 
> "password").close();
> // Create the TCP Server
> org.h2.tools.Server server = org.h2.tools.Server.createTcpServer(
> "-tcpPort", "9128");
> server.start();
>
> If you need to use -tcpAllowOthers, specify a strong password in this 
> connection.
>
> Other processes must use a remote URL instead 
> (jdbc:h2:tcp://localhost:9128/mem:H2-db).
>
> Another option is to start the H2 Server process and create a database in 
> it with H2 Console or from context menu of its tray icon.
>

-- 
You received this message because you are subscribed to the Google Groups "H2 
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/h2-database/d12554bf-359b-4b7d-8870-028cad68e8d8o%40googlegroups.com.

Reply via email to