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.