TomEE
  1. TomEE
  2. TOMEE-171

TomEE automatically directs embedded (@DataSourceDefinition) h2 datasource to hsqldb

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.0.0-beta-2
    • Fix Version/s: 1.5.0
    • Component/s: None
    • Labels:
      None
    • Environment:
      Mac OS X 10.6.8, JDK6u31, h2 1.3.161

      Description

      When trying to run an example CRUD application for Java EE 6 (see http://henk53.wordpress.com/2012/04/15/jsf2-primefaces3-ejb3-jpa2-integration-project) on TomEE beta 2, I noticed that the logs and data for the embedded h2 datasource end up as hsqldb equivalents in [TOMEE HOME]/data/hsqldb/.

      The datasource definition in web.xml is as follows:

      	<data-source>
      		<name>java:app/MyApp/myDS</name>
      		<class-name>org.h2.jdbcx.JdbcDataSource</class-name>
      		<url>jdbc:h2:~/mydb;DB_CLOSE_DELAY=-1</url>
      		<user>sa</user>
      		<password>sa</password>
      		<transactional>true</transactional>
      		<isolation-level>TRANSACTION_READ_COMMITTED</isolation-level>
      		<initial-pool-size>2</initial-pool-size>
      		<max-pool-size>10</max-pool-size>
      		<min-pool-size>5</min-pool-size>
      		<max-statements>0</max-statements>
      	</data-source>
      

      So clearly it should be using h2, and the DB should be created in my home as mydb. When I remove the h2 implementation jar from WEB-INF/lib, TomEE does complain, so it does try to do something with h2 for sure. Inspecting the log reveals it really are hsqldb log lines and not h2.

      What's happening here? Why is TomEE silently swapping one DB for the other?

        Activity

        Hide
        Romain Manni-Bucau added a comment -

        can you share your h2 url please? i use it in memory and don't see such an error

        Show
        Romain Manni-Bucau added a comment - can you share your h2 url please? i use it in memory and don't see such an error
        Hide
        Henk de Boer added a comment -

        You're welcome!

        My test was rather simple in scope: creating users, listing them, trying to create users with an id that already exists (to trigger DB exception). All seemed to work perfectly.

        There is one small thing though, but it's maybe a separate issue. When I shutdown TomEE, I get the following exception:

        06-29 23:05:55 database: close
        org.h2.message.DbException: General error: "java.lang.NoClassDefFoundError: org/h2/index/PageBtreeCursor"; SQL statement:
        SELECT ID FROM INFORMATION_SCHEMA.LOBS WHERE TABLE = ? [50000-161]
        at org.h2.message.DbException.convert(DbException.java:269)
        at org.h2.store.LobStorage.removeAllForTable(LobStorage.java:158)
        at org.h2.engine.Database.close(Database.java:1080)
        at org.h2.engine.DatabaseCloser.run(DatabaseCloser.java:80)
        Caused by: org.h2.jdbc.JdbcSQLException: General error: "java.lang.NoClassDefFoundError: org/h2/index/PageBtreeCursor"; SQL statement:
        SELECT ID FROM INFORMATION_SCHEMA.LOBS WHERE TABLE = ? [50000-161]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
        at org.h2.message.DbException.get(DbException.java:158)
        at org.h2.message.DbException.convert(DbException.java:277)
        at org.h2.command.Command.executeQuery(Command.java:189)
        at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:96)
        at org.h2.store.LobStorage.removeAllForTable(LobStorage.java:152)
        ... 2 more
        Caused by: java.lang.NoClassDefFoundError: org/h2/index/PageBtreeCursor
        at org.h2.index.PageBtreeIndex.find(PageBtreeIndex.java:186)
        at org.h2.index.PageBtreeIndex.find(PageBtreeIndex.java:178)
        at org.h2.index.BaseIndex.find(BaseIndex.java:102)
        at org.h2.index.IndexCursor.find(IndexCursor.java:145)
        at org.h2.table.TableFilter.next(TableFilter.java:321)
        at org.h2.command.dml.Select.queryFlat(Select.java:512)
        at org.h2.command.dml.Select.queryWithoutCache(Select.java:617)
        at org.h2.command.dml.Query.query(Query.java:298)
        at org.h2.command.dml.Query.query(Query.java:268)
        at org.h2.command.dml.Query.query(Query.java:37)
        at org.h2.command.CommandContainer.query(CommandContainer.java:82)
        at org.h2.command.Command.executeQuery(Command.java:185)
        ... 4 more
        Caused by: java.lang.ClassNotFoundException: org.h2.index.PageBtreeCursor
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1711)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)
        ... 16 more
        06-29 23:05:55 database: close
        java.lang.NoClassDefFoundError: org/h2/store/PageStreamTrunk$Iterator
        at org.h2.store.PageLog.free(PageLog.java:208)
        at org.h2.store.PageStore.compact(PageStore.java:468)
        at org.h2.engine.Database.closeOpenFilesAndUnlock(Database.java:1169)
        at org.h2.engine.Database.close(Database.java:1119)
        at org.h2.engine.DatabaseCloser.run(DatabaseCloser.java:80)
        Caused by: java.lang.ClassNotFoundException: org.h2.store.PageStreamTrunk$Iterator
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1711)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556)
        ... 5 more

        My guess is that the war is unloaded before this hook of the H2 DB comes into effect, so there's probably nothing TomEE can do about this. But just wanted to let you know, just in case.

        Show
        Henk de Boer added a comment - You're welcome! My test was rather simple in scope: creating users, listing them, trying to create users with an id that already exists (to trigger DB exception). All seemed to work perfectly. There is one small thing though, but it's maybe a separate issue. When I shutdown TomEE, I get the following exception: 06-29 23:05:55 database: close org.h2.message.DbException: General error: "java.lang.NoClassDefFoundError: org/h2/index/PageBtreeCursor"; SQL statement: SELECT ID FROM INFORMATION_SCHEMA.LOBS WHERE TABLE = ? [50000-161] at org.h2.message.DbException.convert(DbException.java:269) at org.h2.store.LobStorage.removeAllForTable(LobStorage.java:158) at org.h2.engine.Database.close(Database.java:1080) at org.h2.engine.DatabaseCloser.run(DatabaseCloser.java:80) Caused by: org.h2.jdbc.JdbcSQLException: General error: "java.lang.NoClassDefFoundError: org/h2/index/PageBtreeCursor"; SQL statement: SELECT ID FROM INFORMATION_SCHEMA.LOBS WHERE TABLE = ? [50000-161] at org.h2.message.DbException.getJdbcSQLException(DbException.java:329) at org.h2.message.DbException.get(DbException.java:158) at org.h2.message.DbException.convert(DbException.java:277) at org.h2.command.Command.executeQuery(Command.java:189) at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:96) at org.h2.store.LobStorage.removeAllForTable(LobStorage.java:152) ... 2 more Caused by: java.lang.NoClassDefFoundError: org/h2/index/PageBtreeCursor at org.h2.index.PageBtreeIndex.find(PageBtreeIndex.java:186) at org.h2.index.PageBtreeIndex.find(PageBtreeIndex.java:178) at org.h2.index.BaseIndex.find(BaseIndex.java:102) at org.h2.index.IndexCursor.find(IndexCursor.java:145) at org.h2.table.TableFilter.next(TableFilter.java:321) at org.h2.command.dml.Select.queryFlat(Select.java:512) at org.h2.command.dml.Select.queryWithoutCache(Select.java:617) at org.h2.command.dml.Query.query(Query.java:298) at org.h2.command.dml.Query.query(Query.java:268) at org.h2.command.dml.Query.query(Query.java:37) at org.h2.command.CommandContainer.query(CommandContainer.java:82) at org.h2.command.Command.executeQuery(Command.java:185) ... 4 more Caused by: java.lang.ClassNotFoundException: org.h2.index.PageBtreeCursor at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1711) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556) ... 16 more 06-29 23:05:55 database: close java.lang.NoClassDefFoundError: org/h2/store/PageStreamTrunk$Iterator at org.h2.store.PageLog.free(PageLog.java:208) at org.h2.store.PageStore.compact(PageStore.java:468) at org.h2.engine.Database.closeOpenFilesAndUnlock(Database.java:1169) at org.h2.engine.Database.close(Database.java:1119) at org.h2.engine.DatabaseCloser.run(DatabaseCloser.java:80) Caused by: java.lang.ClassNotFoundException: org.h2.store.PageStreamTrunk$Iterator at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1711) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1556) ... 5 more My guess is that the war is unloaded before this hook of the H2 DB comes into effect, so there's probably nothing TomEE can do about this. But just wanted to let you know, just in case.
        Hide
        Romain Manni-Bucau added a comment -

        great so i'll close this issue, please reopen it if you see your tests was not complete

        thank for your time and your report

        Show
        Romain Manni-Bucau added a comment - great so i'll close this issue, please reopen it if you see your tests was not complete thank for your time and your report
        Hide
        Henk de Boer added a comment -

        I think it actually works Romain! You did it

        I tried https://repository.apache.org/content/repositories/snapshots/org/apache/openejb/apache-tomee/1.1.0-SNAPSHOT/apache-tomee-1.1.0-20120628.041334-43-webprofile.zip and the aforementioned application with the configuration given in the description of this ticket.

        There's no more [tomee home]/hsqldb/hsqldb.log file being generated, and instead a mydb.h2.db appears in my home. The application works as expected!

        Show
        Henk de Boer added a comment - I think it actually works Romain! You did it I tried https://repository.apache.org/content/repositories/snapshots/org/apache/openejb/apache-tomee/1.1.0-SNAPSHOT/apache-tomee-1.1.0-20120628.041334-43-webprofile.zip and the aforementioned application with the configuration given in the description of this ticket. There's no more [tomee home] /hsqldb/hsqldb.log file being generated, and instead a mydb.h2.db appears in my home. The application works as expected!
        Hide
        Romain Manni-Bucau added a comment -

        I think so

        Show
        Romain Manni-Bucau added a comment - I think so
        Hide
        Henk de Boer added a comment -

        I'll look at https://repository.apache.org/content/repositories/snapshots/org/apache/openejb/apache-tomee/1.1.0-SNAPSHOT/ then.

        Just so that I know where to concentrate my tests on, is java:/app now supposed to work? Thanks!

        Show
        Henk de Boer added a comment - I'll look at https://repository.apache.org/content/repositories/snapshots/org/apache/openejb/apache-tomee/1.1.0-SNAPSHOT/ then. Just so that I know where to concentrate my tests on, is java:/app now supposed to work? Thanks!
        Hide
        Romain Manni-Bucau added a comment -

        hmm, probably forgot to mention you can test , sorry

        Show
        Romain Manni-Bucau added a comment - hmm, probably forgot to mention you can test , sorry
        Hide
        Henk de Boer added a comment -

        Romain, just curious, is there any progress to report? If you have any questions or if I can test anything, please let me know.

        Show
        Henk de Boer added a comment - Romain, just curious, is there any progress to report? If you have any questions or if I can test anything, please let me know.
        Hide
        Romain Manni-Bucau added a comment -

        you are right, was just the current behavior

        i hacked a bit on it, i didnt try with JPA but at least injections work

        Show
        Romain Manni-Bucau added a comment - you are right, was just the current behavior i hacked a bit on it, i didnt try with JPA but at least injections work
        Hide
        Henk de Boer added a comment -

        Romain, java:/global and java:/app mapping to the same thing would be rather troublesome. It's very important that they are different namespaces.

        java:/global is a namespace that's global for the entire AS. This means that if I deploy 2 individual wars to the same TomEE instance, they both see this.

        java:/app is relative to a single war. This means only the war that declared this name can see it.

        Put differently, if two wars both declare a java:/global/foo resource, they will conflict. But if both wars declare a java:/app/foo resource, they both will see their own version. That's why especially for embedded datasources java:/app is such an important namespace, but the others should be supported too.

        See this for more details about this: https://blogs.oracle.com/MaheshKannan/entry/portable_global_jndi_names

        (sorry in advance if I didn't understood your question correctly and explained something obvious to you)

        Show
        Henk de Boer added a comment - Romain, java:/global and java:/app mapping to the same thing would be rather troublesome. It's very important that they are different namespaces. java:/global is a namespace that's global for the entire AS. This means that if I deploy 2 individual wars to the same TomEE instance, they both see this. java:/app is relative to a single war. This means only the war that declared this name can see it. Put differently, if two wars both declare a java:/global/foo resource, they will conflict. But if both wars declare a java:/app/foo resource, they both will see their own version. That's why especially for embedded datasources java:/app is such an important namespace, but the others should be supported too. See this for more details about this: https://blogs.oracle.com/MaheshKannan/entry/portable_global_jndi_names (sorry in advance if I didn't understood your question correctly and explained something obvious to you)
        Hide
        Romain Manni-Bucau added a comment -

        currently java:global, java:app, ... are treated the same way. I thin kthat's the way you think when you speak about java:app.

        Show
        Romain Manni-Bucau added a comment - currently java:global, java:app, ... are treated the same way. I thin kthat's the way you think when you speak about java:app.
        Hide
        Henk de Boer added a comment -

        >Yes from a packaging point of view but notfrom a deployment one

        I guess that's more difficult indeed. But what do you think, will TomEE be able to support java:/app?

        Show
        Henk de Boer added a comment - >Yes from a packaging point of view but notfrom a deployment one I guess that's more difficult indeed. But what do you think, will TomEE be able to support java:/app?
        Hide
        Romain Manni-Bucau added a comment -

        Yes from a packaging point of view but notfrom a deployment one

        Show
        Romain Manni-Bucau added a comment - Yes from a packaging point of view but notfrom a deployment one
        Hide
        Henk de Boer added a comment -

        >Persistence module are not in the ejb-jar module

        Do you mean persistence.xml and a JPA persistence unit? These can be in the ejb-jar module of course.

        Or do you mean the driver file? This cannot be in the ejb-jar module indeed, but the ejb-jar has access to all the class loaders of its parent EAR. So a java:module definition could theoretically be in the ejb-jar, which then loads the driver from the parent ear. The spec says the driver needs to be available on the classpath, but not restricts the driver to be available only to the same module.

        Is that what you meant?

        Show
        Henk de Boer added a comment - >Persistence module are not in the ejb-jar module Do you mean persistence.xml and a JPA persistence unit? These can be in the ejb-jar module of course. Or do you mean the driver file? This cannot be in the ejb-jar module indeed, but the ejb-jar has access to all the class loaders of its parent EAR. So a java:module definition could theoretically be in the ejb-jar, which then loads the driver from the parent ear. The spec says the driver needs to be available on the classpath, but not restricts the driver to be available only to the same module. Is that what you meant?
        Hide
        Romain Manni-Bucau added a comment -

        Persistence module are not in the ejb-jar module so java:module doesnt work. Then what you said work, you can inject the datasource with the java:... name. I thought too it was clear but that's clearly not.

        Show
        Romain Manni-Bucau added a comment - Persistence module are not in the ejb-jar module so java:module doesnt work. Then what you said work, you can inject the datasource with the java:... name. I thought too it was clear but that's clearly not.
        Hide
        Henk de Boer added a comment -

        >generally in app server java:... is not supported and the server puts the datasource where it wants...i know that's far to be perfect

        For the propriety datasource files (JBoss' -ds.xml, WebLogic's -jdbc.xml) this indeed seemed to be mostly the case, just as before Java EE 6, the AS could put EJBs where it wants.

        But it seems the spec is somewhat clear that for @DataSourceDefinition/web.xml/ejb-jar.xml/application.xml the java: namespace should be supported (at least the portable ones as defined for EJB).

        JSR 316 in EE.5.17 gives the java:/app example, while the related JSR 250 (Common Annotations) in 2.13 uses an example with java:global. The description of the "name" field in JSR 250 is: "JNDI name by which the data source will be registered"

        Show
        Henk de Boer added a comment - >generally in app server java:... is not supported and the server puts the datasource where it wants...i know that's far to be perfect For the propriety datasource files (JBoss' -ds.xml, WebLogic's -jdbc.xml) this indeed seemed to be mostly the case, just as before Java EE 6, the AS could put EJBs where it wants. But it seems the spec is somewhat clear that for @DataSourceDefinition/web.xml/ejb-jar.xml/application.xml the java: namespace should be supported (at least the portable ones as defined for EJB). JSR 316 in EE.5.17 gives the java:/app example, while the related JSR 250 (Common Annotations) in 2.13 uses an example with java:global. The description of the "name" field in JSR 250 is: "JNDI name by which the data source will be registered"
        Hide
        Romain Manni-Bucau added a comment -

        generally in app server java:... is not supported and the server puts the datasource where it wants...i know that's far to be perfect

        Show
        Romain Manni-Bucau added a comment - generally in app server java:... is not supported and the server puts the datasource where it wants...i know that's far to be perfect
        Hide
        Henk de Boer added a comment -

        >weird since at least as doesnt support it, deltaspike project talked about it and absolute path is not supported in general in application servers (and that's not in the spec)

        Romain, what do you mean exactly by that? java:app/ is strictly speaking a relative path, as it's relative to the application in question. java:module/ is also relative. It seems logical that if someone would use java:module/, then the datasource would only be available/visible in the module that declared it. E.g. if it's in web.xml, then only the web module to which that web.xml belongs would see it and not any of the EJB modules in the same EAR (if an EAR is used at all).

        java:global/ is an absolute path for sure. This might be problematic to support if the driver is inside the application, but might be doable if it's globally available to the AS.

        Show
        Henk de Boer added a comment - >weird since at least as doesnt support it, deltaspike project talked about it and absolute path is not supported in general in application servers (and that's not in the spec) Romain, what do you mean exactly by that? java:app/ is strictly speaking a relative path, as it's relative to the application in question. java:module/ is also relative. It seems logical that if someone would use java:module/, then the datasource would only be available/visible in the module that declared it. E.g. if it's in web.xml, then only the web module to which that web.xml belongs would see it and not any of the EJB modules in the same EAR (if an EAR is used at all). java:global/ is an absolute path for sure. This might be problematic to support if the driver is inside the application, but might be doable if it's globally available to the AS.
        Hide
        Romain Manni-Bucau added a comment -

        weird since at least as doesnt support it, deltaspike project talked about it and absolute path is not supported in general in application servers (and that's not in the spec)

        we hope it will be fixed in jee7

        Show
        Romain Manni-Bucau added a comment - weird since at least as doesnt support it, deltaspike project talked about it and absolute path is not supported in general in application servers (and that's not in the spec) we hope it will be fixed in jee7
        Hide
        Henk de Boer added a comment -

        in tomee we add the app name before the datasource name in jndi that's why you need to add it in your persistence.xml (but that's not mandatory injecting the datasource normally)

        That might be the issue. Indeed, many of the proprietary xml files for many servers have something like this. E.g. specify datasource FooDS in WebLogic's *-jdbc.xml as JNDI name, and you'll have to reference it by java:app/FooDS.

        Nevertheless, for the name in @DataSourceDefinition and web.xml, it seems to be agreed that if you ask for java:app/MyApp/myDS, that you can refer to it via exactly that; java:app/MyApp/myDS. In EE.5.17 the Java EE 6 spec gives an example using exactly this scope. The other servers that I tested (JBoss AS 7.1.1, GlassFish 3.1.2, WebLogic 12c) all do follow this.

        trunk should manage it more correctly

        Looking forward again to testing that, will a snap shot of this be made soon? Otherwise I can try building trunk from source. Thanks again for your efforts!

        Show
        Henk de Boer added a comment - in tomee we add the app name before the datasource name in jndi that's why you need to add it in your persistence.xml (but that's not mandatory injecting the datasource normally) That might be the issue. Indeed, many of the proprietary xml files for many servers have something like this. E.g. specify datasource FooDS in WebLogic's *-jdbc.xml as JNDI name, and you'll have to reference it by java:app/FooDS. Nevertheless, for the name in @DataSourceDefinition and web.xml, it seems to be agreed that if you ask for java:app/MyApp/myDS, that you can refer to it via exactly that; java:app/MyApp/myDS. In EE.5.17 the Java EE 6 spec gives an example using exactly this scope. The other servers that I tested (JBoss AS 7.1.1, GlassFish 3.1.2, WebLogic 12c) all do follow this. trunk should manage it more correctly Looking forward again to testing that, will a snap shot of this be made soon? Otherwise I can try building trunk from source. Thanks again for your efforts!
        Hide
        Romain Manni-Bucau added a comment -

        trunk should manage it more correctly

        Show
        Romain Manni-Bucau added a comment - trunk should manage it more correctly
        Hide
        Romain Manni-Bucau added a comment -

        in persistence.xml use <jta-data-source>jsf_ejb_jpa/myDS</jta-data-source> and in web.xml <name>myDS</name> (another note is default password is empty) and it should work.

        @DataSourceDefinition or the web.xml datasource is not very well specified actually :s

        in tomee we add the app name before the datasource name in jndi that's why you need to add it in your persistence.xml (but that's not mandatory injecting the datasource normally)

        i'll have a quick look to see if we can do better

        Show
        Romain Manni-Bucau added a comment - in persistence.xml use <jta-data-source>jsf_ejb_jpa/myDS</jta-data-source> and in web.xml <name>myDS</name> (another note is default password is empty) and it should work. @DataSourceDefinition or the web.xml datasource is not very well specified actually :s in tomee we add the app name before the datasource name in jndi that's why you need to add it in your persistence.xml (but that's not mandatory injecting the datasource normally) i'll have a quick look to see if we can do better
        Hide
        Henk de Boer added a comment -

        With beta 3 we're one step further as injection is working again, but unfortunately persistence is still being done in the hsqldb,.

        I deployed the CRUD app to TomEE and persisted two users. Afterwards the [tomee home]/hsqldb/hsqldb.log contained the followed content:

        /C2/SET SCHEMA PUBLIC
        DISCONNECT
        /C4/SET SCHEMA PUBLIC
        DISCONNECT
        /C5/SET SCHEMA PUBLIC
        CREATE TABLE User (id INTEGER NOT NULL, name VARCHAR(255), surname VARCHAR(255), PRIMARY KEY (id))
        /C3/SET SCHEMA PUBLIC
        INSERT INTO USER VALUES(0,'ddddddd','ffffffff')
        COMMIT
        INSERT INTO USER VALUES(1,'ddddddd','gggggg')
        COMMIT

        So it seems it's still using the default hsqldb and not the h2 DB that I defined in web.xml. The exact TomEE download I tried is https://repository.apache.org/content/repositories/snapshots/org/apache/openejb/apache-tomee/1.0.0-beta-3-SNAPSHOT/apache-tomee-1.0.0-beta-3-20120506.041222-119-plus.tar.gz

        I tried with both h2 on disk (jdbc:h2:~/mydb;DB_CLOSE_DELAY=-1) and in-memory (jdbc:h2:mem:test;DB_CLOSE_DELAY=-1). In case of the on-disk version, there is nothing at all being created in my home (no locks, logs, nothing) which seems to be indicative of h2 not even being touched.

        Show
        Henk de Boer added a comment - With beta 3 we're one step further as injection is working again, but unfortunately persistence is still being done in the hsqldb,. I deployed the CRUD app to TomEE and persisted two users. Afterwards the [tomee home] /hsqldb/hsqldb.log contained the followed content: / C2 /SET SCHEMA PUBLIC DISCONNECT / C4 /SET SCHEMA PUBLIC DISCONNECT / C5 /SET SCHEMA PUBLIC CREATE TABLE User (id INTEGER NOT NULL, name VARCHAR(255), surname VARCHAR(255), PRIMARY KEY (id)) / C3 /SET SCHEMA PUBLIC INSERT INTO USER VALUES(0,'ddddddd','ffffffff') COMMIT INSERT INTO USER VALUES(1,'ddddddd','gggggg') COMMIT So it seems it's still using the default hsqldb and not the h2 DB that I defined in web.xml. The exact TomEE download I tried is https://repository.apache.org/content/repositories/snapshots/org/apache/openejb/apache-tomee/1.0.0-beta-3-SNAPSHOT/apache-tomee-1.0.0-beta-3-20120506.041222-119-plus.tar.gz I tried with both h2 on disk (jdbc:h2:~/mydb;DB_CLOSE_DELAY=-1) and in-memory (jdbc:h2:mem:test;DB_CLOSE_DELAY=-1). In case of the on-disk version, there is nothing at all being created in my home (no locks, logs, nothing) which seems to be indicative of h2 not even being touched.
        Show
        Romain Manni-Bucau added a comment - did you try https://repository.apache.org/content/repositories/snapshots/org/apache/openejb/apache-tomee/1.0.0-beta-3-SNAPSHOT/?
        Hide
        Henk de Boer added a comment -

        Sorry to bother again, but any news here? Did I do something wrong, or was the wrong version of TomEE released as 1.0?

        Show
        Henk de Boer added a comment - Sorry to bother again, but any news here? Did I do something wrong, or was the wrong version of TomEE released as 1.0?
        Hide
        Henk de Boer added a comment -

        I've waited a few days, but unfortunately it seems the maven repo doesn't get updated anymore. It's stuck at 27 April.

        Maybe worse, the TomEE I downloaded from the official download page at http://openejb.apache.org/downloads.html is a version seemingly from 26 April and doesn't have the JSF injections.

        I'm looking forward to test again, but I can't seem to get the latest version I'm afraid.

        Show
        Henk de Boer added a comment - I've waited a few days, but unfortunately it seems the maven repo doesn't get updated anymore. It's stuck at 27 April. Maybe worse, the TomEE I downloaded from the official download page at http://openejb.apache.org/downloads.html is a version seemingly from 26 April and doesn't have the JSF injections. I'm looking forward to test again, but I can't seem to get the latest version I'm afraid.
        Hide
        Henk de Boer added a comment -

        Thanks for the quick fix! I'll try the snapshot tomorrow then and report back how it went. You being able to persist a user sounds very promising already

        Show
        Henk de Boer added a comment - Thanks for the quick fix! I'll try the snapshot tomorrow then and report back how it went. You being able to persist a user sounds very promising already
        Hide
        Romain Manni-Bucau added a comment -

        well for the 1.0.0 one thing we optimized was to avoid to scan multiple times (one for jsf, one for ejb, one for cdi...) but for jsf classes a part was missing (the part allowing injections).

        normally i fixed it on trunk if you can build tomee from sources (mvn clean install -Dmaven.test.skip=true -pl tomee/apache-tomee -am) or wait a bit (tomorrow i guess) to get our snapshot to give a try, it should work (i persisted a user with your app)

        Show
        Romain Manni-Bucau added a comment - well for the 1.0.0 one thing we optimized was to avoid to scan multiple times (one for jsf, one for ejb, one for cdi...) but for jsf classes a part was missing (the part allowing injections). normally i fixed it on trunk if you can build tomee from sources (mvn clean install -Dmaven.test.skip=true -pl tomee/apache-tomee -am) or wait a bit (tomorrow i guess) to get our snapshot to give a try, it should work (i persisted a user with your app)
        Hide
        Henk de Boer added a comment -

        I also tried TomEE+ from the same repo (http://repo1.maven.org/maven2/org/apache/openejb/apache-tomee/1.0.0/apache-tomee-1.0.0-plus.tar.gz), but here too the injection fails.

        Show
        Henk de Boer added a comment - I also tried TomEE+ from the same repo ( http://repo1.maven.org/maven2/org/apache/openejb/apache-tomee/1.0.0/apache-tomee-1.0.0-plus.tar.gz ), but here too the injection fails.
        Hide
        Henk de Boer added a comment -

        I immediately tried the 1.0.0 release, but it seems it doesn't work at all now. EJB injection in managed beans doesn't happen anymore. Specially, the following code fragment now throws a NPE at the first line of addUser():

        @ViewScoped
        @ManagedBean
        public class IndexBacking {

        private User user = new User();

        @EJB
        private UserDAO userDAO;

        /**

        • Adds a user to persistent storage
        • @return String - navigation to the success page
          */
          public String addUser() { userDAO.add(user); return "success?faces-redirect=true"; }

        I deployed the same app to TomEE beta 2 again (and as cross-check to JBoss AS 7.1.1) and there it works. (I tried http://repo1.maven.org/maven2/org/apache/openejb/apache-tomee/1.0.0/apache-tomee-1.0.0-webprofile.zip)

        Show
        Henk de Boer added a comment - I immediately tried the 1.0.0 release, but it seems it doesn't work at all now. EJB injection in managed beans doesn't happen anymore. Specially, the following code fragment now throws a NPE at the first line of addUser(): @ViewScoped @ManagedBean public class IndexBacking { private User user = new User(); @EJB private UserDAO userDAO; /** Adds a user to persistent storage @return String - navigation to the success page */ public String addUser() { userDAO.add(user); return "success?faces-redirect=true"; } I deployed the same app to TomEE beta 2 again (and as cross-check to JBoss AS 7.1.1) and there it works. (I tried http://repo1.maven.org/maven2/org/apache/openejb/apache-tomee/1.0.0/apache-tomee-1.0.0-webprofile.zip )
        Hide
        Romain Manni-Bucau added a comment -

        just added a sample: http://svn.apache.org/repos/asf/openejb/trunk/openejb/examples/datasource-definition/

        it seems it works fine on trunk

        we just released the 1.0.0 of tomee (available on repo1 of maven: http://repo1.maven.org/maven2/org/apache/openejb/apache-tomee/1.0.0/) can you have a try please?

        Show
        Romain Manni-Bucau added a comment - just added a sample: http://svn.apache.org/repos/asf/openejb/trunk/openejb/examples/datasource-definition/ it seems it works fine on trunk we just released the 1.0.0 of tomee (available on repo1 of maven: http://repo1.maven.org/maven2/org/apache/openejb/apache-tomee/1.0.0/ ) can you have a try please?
        Hide
        Henk de Boer added a comment -

        Thanks for your opinion, I appreciate it.

        Item 1) is indeed a fiercely debated item. Some people want to keep database configuration external others want to be able to ship self-contained wars. In that debate, a data-source in web.xml isn't really different from META-INF/context.xml (and from JBoss' *-ds.xml, and from oracle-jdbc.xml, etc etc). It's exactly like those, but just with standardized syntax.

        When writing applications that already contain their own embedded DB (derby, h2, etc) it's rather clear that their configuration should be embedded as well. However, for regular databases, it also makes sense when deploying to a small amount of internal application servers, especially when deployment descriptors are configurable with placeholders (as might happen for Java EE 7).

        Thanks again for looking into this. If there's anything else I can test, let me know.

        Show
        Henk de Boer added a comment - Thanks for your opinion, I appreciate it. Item 1) is indeed a fiercely debated item. Some people want to keep database configuration external others want to be able to ship self-contained wars. In that debate, a data-source in web.xml isn't really different from META-INF/context.xml (and from JBoss' *-ds.xml, and from oracle-jdbc.xml, etc etc). It's exactly like those, but just with standardized syntax. When writing applications that already contain their own embedded DB (derby, h2, etc) it's rather clear that their configuration should be embedded as well. However, for regular databases, it also makes sense when deploying to a small amount of internal application servers, especially when deployment descriptors are configurable with placeholders (as might happen for Java EE 7). Thanks again for looking into this. If there's anything else I can test, let me know.
        Hide
        Romain Manni-Bucau added a comment -

        I agree but let me give you some more info (and a bit my opinion):

        1) datasource connection info shouldnt be in the app so external config is fine (for me the spec is not relevant on this, thats just my opinion)
        2) it is easy to wrap but that's not done and we don't want to add as many datasource type as driver
        3) what you suggest will more or less be the fix i'll do

        Show
        Romain Manni-Bucau added a comment - I agree but let me give you some more info (and a bit my opinion): 1) datasource connection info shouldnt be in the app so external config is fine (for me the spec is not relevant on this, thats just my opinion) 2) it is easy to wrap but that's not done and we don't want to add as many datasource type as driver 3) what you suggest will more or less be the fix i'll do
        Hide
        Henk de Boer added a comment -

        For the property: i know it is in the annotation so i guess it is in the xml (didnt check)

        They should mirror each other exactly, so this should be the case. However, if it's in the properties section it is a vendor specific setting (in this case thus TomEE specific). See http://docs.oracle.com/javaee/6/api/javax/annotation/sql/DataSourceDefinition.html

        That's already a bit better than a vendor specific configuration file, but since this concerns a fairly basic setting I would say it's not exactly in the spirit of the spec to require for this for the JDBC driver. It would be like vendors requiring the "data-source" in persistence.xml to be in the properties section.

        Moreover we use commons dbcp and that's mandatory

        Are you specifically referring to BasicDataSource (http://commons.apache.org/dbcp/apidocs/org/apache/commons/dbcp/BasicDataSource.html)?

        Long time ago I looked at it, but if I remember correctly it should be rather trivial to wrap an instance of the DataSource class in a Driver. Additionally, for its XA functionality even Commons DBCP uses a DataSource and not a Driver (see http://commons.apache.org/dbcp/apidocs/org/apache/commons/dbcp/managed/DataSourceXAConnectionFactory.html).

        Show
        Henk de Boer added a comment - For the property: i know it is in the annotation so i guess it is in the xml (didnt check) They should mirror each other exactly, so this should be the case. However, if it's in the properties section it is a vendor specific setting (in this case thus TomEE specific). See http://docs.oracle.com/javaee/6/api/javax/annotation/sql/DataSourceDefinition.html That's already a bit better than a vendor specific configuration file, but since this concerns a fairly basic setting I would say it's not exactly in the spirit of the spec to require for this for the JDBC driver. It would be like vendors requiring the "data-source" in persistence.xml to be in the properties section. Moreover we use commons dbcp and that's mandatory Are you specifically referring to BasicDataSource ( http://commons.apache.org/dbcp/apidocs/org/apache/commons/dbcp/BasicDataSource.html)? Long time ago I looked at it, but if I remember correctly it should be rather trivial to wrap an instance of the DataSource class in a Driver. Additionally, for its XA functionality even Commons DBCP uses a DataSource and not a Driver (see http://commons.apache.org/dbcp/apidocs/org/apache/commons/dbcp/managed/DataSourceXAConnectionFactory.html ).
        Hide
        Romain Manni-Bucau added a comment -

        For the property: i know it is in the annotation so i guess it is in the xml (didnt check)

        for "why do we need a driver": because that's the way it currently works for a lot of datasource impl. Moreover we use commons dbcp and that's mandatory

        Show
        Romain Manni-Bucau added a comment - For the property: i know it is in the annotation so i guess it is in the xml (didnt check) for "why do we need a driver": because that's the way it currently works for a lot of datasource impl. Moreover we use commons dbcp and that's mandatory
        Hide
        Henk de Boer added a comment -

        >we create a pool and not just a datasource from the specified class. for this reason we need a jdbc driver.

        I wonder if you really need the JDBC driver class. There is a similar discussion currently on the JBoss JIRA (their web.xml data-source/persistence.xml combo also didn't work correctly, see https://issues.jboss.org/browse/AS7-4552)

        To crosspost a relevant part of my reply from there:

        "A plain javax.sql.DataSource that's provided by the DB vendor is a direct alternative for java.sql.Driver. In fact, it's the more modern and preferable version. Such DataSource shouldn't do much if any connection management and certainly shouldn't do any pooling.

        This DataSource typically calls the DriverManager (java.sql.DriverManager), which on its turn calls the Driver.connect method. java.sql.Driver#connect can take extra properties, but apart from "user" and "password" these are DB specific. The DataSource implementation can be configured with the same kind of DB specific properties.

        So, in my understanding, the differences between java.sql.Driver and javax.sql.DataSource are rather small and they eventually end up at the same point.

        [...]

        Other AS implementations, like GlassFish, do all their magic with a javax.sql.DataSource (or XA variant) instead of a Driver."

        Can you try adding the property JdbcDriver=xxx please?

        I'll certainly try this. To be clear, this is a property for the data-source element in web.xml?

        Show
        Henk de Boer added a comment - >we create a pool and not just a datasource from the specified class. for this reason we need a jdbc driver. I wonder if you really need the JDBC driver class. There is a similar discussion currently on the JBoss JIRA (their web.xml data-source/persistence.xml combo also didn't work correctly, see https://issues.jboss.org/browse/AS7-4552 ) To crosspost a relevant part of my reply from there: "A plain javax.sql.DataSource that's provided by the DB vendor is a direct alternative for java.sql.Driver. In fact, it's the more modern and preferable version. Such DataSource shouldn't do much if any connection management and certainly shouldn't do any pooling. This DataSource typically calls the DriverManager (java.sql.DriverManager), which on its turn calls the Driver.connect method. java.sql.Driver#connect can take extra properties, but apart from "user" and "password" these are DB specific. The DataSource implementation can be configured with the same kind of DB specific properties. So, in my understanding, the differences between java.sql.Driver and javax.sql.DataSource are rather small and they eventually end up at the same point. [...] Other AS implementations, like GlassFish, do all their magic with a javax.sql.DataSource (or XA variant) instead of a Driver." Can you try adding the property JdbcDriver=xxx please? I'll certainly try this. To be clear, this is a property for the data-source element in web.xml?
        Hide
        Romain Manni-Bucau added a comment -

        Can you try adding the property JdbcDriver=xxx please?

        Show
        Romain Manni-Bucau added a comment - Can you try adding the property JdbcDriver=xxx please?
        Hide
        Romain Manni-Bucau added a comment -

        we create a pool and not just a datasource from the specified class. for this reason we need a jdbc driver. But ill hack on it and find a solution. dont worry.

        Show
        Romain Manni-Bucau added a comment - we create a pool and not just a datasource from the specified class. for this reason we need a jdbc driver. But ill hack on it and find a solution. dont worry.
        Hide
        Henk de Boer added a comment -

        Thanks for looking into it.

        I do wonder, how can the code explicitly support specific databases? Shouldn't you be just looking at javax.sql.DataSource? I mean, you can never possibly anticipate all possible databases in advance, can you?

        Show
        Henk de Boer added a comment - Thanks for looking into it. I do wonder, how can the code explicitly support specific databases? Shouldn't you be just looking at javax.sql.DataSource? I mean, you can never possibly anticipate all possible databases in advance, can you?
        Hide
        Romain Manni-Bucau added a comment -

        I just checked. We only support derby and hsqddb (default) for datasource definition. I'll enhance it next week if i find some time. Thanks for the report

        Show
        Romain Manni-Bucau added a comment - I just checked. We only support derby and hsqddb (default) for datasource definition. I'll enhance it next week if i find some time. Thanks for the report
        Hide
        Henk de Boer added a comment -

        Could maybe the fact that OPENEJB-1665 is not resolved yet be related to this?

        Show
        Henk de Boer added a comment - Could maybe the fact that OPENEJB-1665 is not resolved yet be related to this?
        Hide
        Henk de Boer added a comment -

        The problem is however that META-INF/resources.xml is Tomcat/TomEE specific. The entire purpose of the data-source element in web.xml is to be portable.

        Show
        Henk de Boer added a comment - The problem is however that META-INF/resources.xml is Tomcat/TomEE specific. The entire purpose of the data-source element in web.xml is to be portable.
        Hide
        Romain Manni-Bucau added a comment -

        It can be done providing a meta-inf/resources.xml file containing the same datasource definition than in openejb.xml.

        Show
        Romain Manni-Bucau added a comment - It can be done providing a meta-inf/resources.xml file containing the same datasource definition than in openejb.xml.
        Hide
        Henk de Boer added a comment -

        I'm used to use it but i define my datasource in openejb.xml (or tomee.xml).

        Thanks for the quick reply. I noticed that option, but the entire point of the exercise was to use/test the standard Java EE 6 data-source/@DataSourceDefinition.

        Another point is i think you need to define the h2 driver (the default one is hsql in tomee that's why you get this behavior).

        I see. An outright fail (like in GlassFish) or some warning that another driver is being used might be in place here.

        Incidentally, supporting loading the driver from WEB-INF/lib for app scoped datasources might not be such a bad idea (JBoss AS 7.1 can do this), but if TomEE is not capable of doing this now then I guess this would be a new feature request.

        Show
        Henk de Boer added a comment - I'm used to use it but i define my datasource in openejb.xml (or tomee.xml). Thanks for the quick reply. I noticed that option, but the entire point of the exercise was to use/test the standard Java EE 6 data-source/@DataSourceDefinition. Another point is i think you need to define the h2 driver (the default one is hsql in tomee that's why you get this behavior). I see. An outright fail (like in GlassFish) or some warning that another driver is being used might be in place here. Incidentally, supporting loading the driver from WEB-INF/lib for app scoped datasources might not be such a bad idea (JBoss AS 7.1 can do this), but if TomEE is not capable of doing this now then I guess this would be a new feature request.
        Hide
        Henk de Boer added a comment -

        Eclipse WTP project file for example app. Uses JBoss AS 7.1 runtime for Java EE 6 library dependencies.

        Show
        Henk de Boer added a comment - Eclipse WTP project file for example app. Uses JBoss AS 7.1 runtime for Java EE 6 library dependencies.
        Hide
        Romain Manni-Bucau added a comment -

        Hi,

        I'm used to use it but i define my datasource in openejb.xml (or tomee.xml).

        Another point is i think you need to define the h2 driver (the default one is hsql in tomee that's why you get this behavior).

        Romain

        Show
        Romain Manni-Bucau added a comment - Hi, I'm used to use it but i define my datasource in openejb.xml (or tomee.xml). Another point is i think you need to define the h2 driver (the default one is hsql in tomee that's why you get this behavior). Romain

          People

          • Assignee:
            Unassigned
            Reporter:
            Henk de Boer
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development