10 Replies Latest reply on Jun 20, 2008 7:01 AM by bikerzon

    Problem getting JDBC datasource from JBOSS

    bikerzon

      Hi,

      Hope someone can help me out here. I'm using JPA(EJB3) with Hibernate and MySQL in my J2EE apps. The problem is that I'm trying to get the datasource from the JNDI. I think I configured the JNDI and datasource correctly as I follow the JBOSS Server_COnfiguration_Guide.pdf properly and the JMX console even shows the JNDI Datasource. I copied mysql-ds.xml from the example and just modified the database properties and put it under "deploy" directories.

      Here's my mysql-ds.xml :

      <datasources>
       <local-tx-datasource>
       <jndi-name>MySqlDS</jndi-name>
       <connection-url>jdbc:mysql://localhost:3306/test_db</connection-url>
       <driver-class>com.mysql.jdbc.Driver</driver-class>
       <user-name>abc</user-name>
       <password>abc</password>
       <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
       <!-- should only be used on drivers after 3.22.1 with "ping" support
       <valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name>
       -->
       <!-- sql to call when connection is created
       <new-connection-sql>some arbitrary sql</new-connection-sql>
       -->
       <!-- sql to call on an existing pooled connection when it is obtained from pool - MySQLValidConnectionChecker is preferred for newer drivers
       <check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql>
       -->
      
       <!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml -->
       <metadata>
       <type-mapping>mySQL</type-mapping>
       </metadata>
       </local-tx-datasource>
      </datasources>
      


      My web project includes a JPA Project that uses Hibernate. When I ran my project I got this error:
      11:38:27,640 INFO [ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=MySqlDS' to JNDI name 'java:MySqlDS'
      11:38:27,718 INFO [TomcatDeployer] deploy, ctxPath=/jmx-console, warUrl=.../deploy/jmx-console.war/
      11:38:29,125 INFO [EARDeployer] Init J2EE application: file:/C:/jboss-4.2.2.GA/server/default/deploy/jboss_jpa_web_all_in_oneEAR.ear
      11:38:34,734 INFO [TomcatDeployer] deploy, ctxPath=/jboss_jpa_web_all_in_one, warUrl=.../tmp/deploy/tmp41843jboss_jpa_web_all_in_oneEAR.ear-contents/jboss_jpa_web_all_in_one-exp.war/
      11:38:36,562 INFO [EARDeployer] Started J2EE application: file:/C:/jboss-4.2.2.GA/server/default/deploy/jboss_jpa_web_all_in_oneEAR.ear
      11:38:36,734 INFO [Http11Protocol] Starting Coyote HTTP/1.1 on http-127.0.0.1-8080
      11:38:36,765 INFO [AjpProtocol] Starting Coyote AJP/1.3 on ajp-127.0.0.1-8009
      11:38:36,765 INFO [Server] JBoss (MX MicroKernel) [4.2.2.GA (build: SVNTag=JBoss_4_2_2_GA date=200710221139)] Started in 36s:328ms
      11:39:59,609 INFO [STDOUT] 11:39:59,609 INFO [Version] Hibernate Annotations 3.3.0.GA
      11:39:59,640 INFO [STDOUT] 11:39:59,640 INFO [Environment] Hibernate 3.2.6
      11:39:59,640 INFO [STDOUT] 11:39:59,640 INFO [Environment] hibernate.properties not found
      11:39:59,656 INFO [STDOUT] 11:39:59,656 INFO [Environment] Bytecode provider name : javassist
      11:39:59,656 INFO [STDOUT] 11:39:59,656 INFO [Environment] using JDK 1.4 java.sql.Timestamp handling
      11:39:59,812 INFO [STDOUT] 11:39:59,812 INFO [Version] Hibernate EntityManager 3.3.1.GA
      11:40:00,359 INFO [STDOUT] 11:40:00,359 INFO [AnnotationBinder] Binding entity from annotated class: com.hui.Person
      11:40:00,875 INFO [STDOUT] 11:40:00,875 INFO [EntityBinder] Bind entity com.hui.Person on table person_table
      11:40:00,953 INFO [STDOUT] 11:40:00,953 INFO [Version] Hibernate Validator 3.0.0.GA
      11:40:01,171 INFO [STDOUT] 11:40:01,171 INFO [NamingHelper] JNDI InitialContext properties:{java.naming.provider.url=jnp://localhost:1099, java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory}
      11:40:01,171 ERROR [STDERR] javax.persistence.PersistenceException: org.hibernate.HibernateException: Could not find datasource: java:MySqlDS
      11:40:01,171 ERROR [STDERR] at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:737)
      11:40:01,171 ERROR [STDERR] at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:121)
      11:40:01,171 ERROR [STDERR] at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:51)
      11:40:01,171 ERROR [STDERR] at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:33)
      11:40:01,171 ERROR [STDERR] at org.apache.jsp.jpa_005fimplementation_jsp._jspService(jpa_005fimplementation_jsp.java:74)
      11:40:01,171 ERROR [STDERR] at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
      11:40:01,171 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
      11:40:01,171 ERROR [STDERR] at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:373)
      11:40:01,171 ERROR [STDERR] at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:336)
      11:40:01,171 ERROR [STDERR] at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
      11:40:01,171 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
      11:40:01,171 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
      11:40:01,171 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      11:40:01,171 ERROR [STDERR] at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
      11:40:01,171 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
      11:40:01,171 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
      11:40:01,171 ERROR [STDERR] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
      11:40:01,171 ERROR [STDERR] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
      11:40:01,171 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
      11:40:01,171 ERROR [STDERR] at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
      11:40:01,171 ERROR [STDERR] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
      11:40:01,171 ERROR [STDERR] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
      11:40:01,171 ERROR [STDERR] at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
      11:40:01,171 ERROR [STDERR] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      11:40:01,171 ERROR [STDERR] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262)
      11:40:01,171 ERROR [STDERR] at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
      11:40:01,171 ERROR [STDERR] at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
      11:40:01,171 ERROR [STDERR] at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446)
      11:40:01,171 ERROR [STDERR] at java.lang.Thread.run(Unknown Source)
      11:40:01,171 ERROR [STDERR] Caused by: org.hibernate.HibernateException: Could not find datasource: java:MySqlDS
      11:40:01,171 ERROR [STDERR] at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:59)
      11:40:01,171 ERROR [STDERR] at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:124)
      11:40:01,171 ERROR [STDERR] at org.hibernate.ejb.InjectionSettingsFactory.createConnectionProvider(InjectionSettingsFactory.java:29)
      11:40:01,171 ERROR [STDERR] at org.hibernate.cfg.SettingsFactory.buildSettings(SettingsFactory.java:62)
      11:40:01,171 ERROR [STDERR] at org.hibernate.cfg.Configuration.buildSettings(Configuration.java:2073)
      11:40:01,171 ERROR [STDERR] at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1298)
      11:40:01,171 ERROR [STDERR] at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:915)
      11:40:01,171 ERROR [STDERR] at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:730)
      11:40:01,171 ERROR [STDERR] ... 28 more
      


      From the trace stack, it seems that I can't find the JNDI "java:MySqlDS". I checked the JMX console and found out that "java:MySqlDS" is there in the "java:" namespace as shown:
      java: Namespace
      
       +- XAConnectionFactory (class: org.jboss.mq.SpyXAConnectionFactory)
       +- DefaultDS (class: org.jboss.resource.adapter.jdbc.WrapperDataSource)
       +- SecurityProxyFactory (class: org.jboss.security.SubjectSecurityProxyFactory)
       +- DefaultJMSProvider (class: org.jboss.jms.jndi.JNDIProviderAdapter)
       +- MySqlDS (class: org.jboss.resource.adapter.jdbc.WrapperDataSource)
      


      To my surprise, its there. So I thought maybe my JNDI datasource name is wrong and change it to "java:/MySqlDS" (note that I added the forward slash).

      I tried with a very simple code just to test whether I can get the datasource out of the JNDI so I wrote this piece of code in my JSP:
      String dstr = "java:MySqlDS"; //[java:/MySqlDS][MySqlDS][/MySqlDS][java:/comp/MySqlDS]
       out.println("<br/>Datasource Name: " + dstr);
       InitialContext ic = new InitialContext();
       DataSource ds = (DataSource) ic.lookup(dstr);
       Connection conn = ds.getConnection();
       out.println("<br/>Catalogue : " + conn.getCatalog());
       out.println("<br/>Product Name: " + conn.getMetaData().getDatabaseProductName());
      
       if (!conn.isClosed()) {
       conn.close();
       out.println("<br/>DB Connection is closed. " + conn.toString());
       }
      
       } catch (Exception e) {
       out.println("<br/>Main Error: " + e.getMessage());
       out.println("<br/>Error Message: " + e.toString());
       }
      


      I tried the above code with few JNDI name just to make sure that I got the correct name:
      String dstr = "java:MySqlDS"; //[java:/MySqlDS][MySqlDS][/MySqlDS][java:/comp/MySqlDS]
      


      But all result in the same exception: NullPointerException.

      So I remove my JPA implementation(/src/META-INF/persistence.xml) and tried again with the above code, simply to test whether I can get the datasource straight from JBOSS; and I successfully get the datasource!
      (I tried it with "java:MySqlDS" and also "java:/MySqlDS")
      This really puzzle me!

      With JPA-Hibernate, I can't get the datasource and when I remove the JPA-Hibernate, I can get the datasource with the exact same JNDI name!!!

      So the I modified mysql-ds.xml and include <use-java-context> and set it to false so that the jndi will be move to Global namespace and I can manage to get the datasource this way. (using "MySqlDS" jndi name).

      Here's my persistence.xml :
      <?xml version="1.0" encoding="UTF-8"?>
      <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
       <persistence-unit name="jboss_jpa_web_all_in_one"
       transaction-type="RESOURCE_LOCAL">
       <provider>org.hibernate.ejb.HibernatePersistence</provider>
       <non-jta-data-source>java:MySqlDS</non-jta-data-source>
       <mapping-file>META-INF/orm.xml</mapping-file>
       <class>com.hui.Person</class>
       <properties>
       <property name="hibernate.connection.datasource" value="java:MySqlDS" />
       <property name="hibernate.jndi.url" value="jnp://localhost:1099" />
       <property name="hibernate.jndi.class" value="org.jnp.interfaces.NamingContextFactory" />
       <property name="hibernate.connection.release_mode" value="after_transaction" />
       <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
       <property name="hibernate.hbm2ddl.auto" value="create" />
       <property name="hibernate.cache.use_query_cache" value="false" />
       <property name="hibernate.show_sql" value="true" />
       </properties>
       </persistence-unit>
      </persistence>
      


      But according to documentation, I should be able to get the datasource within "java:" namespace right? The JPA is running in the same JVM but when I tried to get the datasource from "java:" it returns null but when I move the jndi to global namespace I can get the datasource.

      But I would like to get the datasource from "java:" as I am running in the same JVM.

      Can someone help me out here?

      Thank you very much.

        • 1. Re: Problem getting JDBC datasource from JBOSS
          jaikiran

           

          <property name="hibernate.connection.datasource" value="java:MySqlDS" />
           <property name="hibernate.jndi.url" value="jnp://localhost:1099" />
           <property name="hibernate.jndi.class" value="org.jnp.interfaces.NamingContextFactory" />

          Try removing these entries from the persistence.xml. I also see that you are using a non-jta-datasource and persitence type RESOURCE_LOCAL. For container managed entity manager, this should have been a jta-datasource and the (default) persistence type JTA

          • 2. Re: Problem getting JDBC datasource from JBOSS
            bikerzon

            I'm still getting the same error.

            Error:org.hibernate.HibernateException: Could not find datasource: java:MySqlDS
            Error Detail: javax.persistence.PersistenceException: org.hibernate.HibernateException: Could not find datasource: java:MySqlDS
            


            I've also tried to enumerate the jndi naming list, to my surprise I get MySqlDS(org.jboss.resource.adapter.jdbc.WrapperDataSource) when I list out "java:" namespace, but when I try to get "java:MySqlDS" it just return null.

            Is this a bug in JBOSS 4.2.2?

            • 3. Re: Problem getting JDBC datasource from JBOSS
              jaikiran

              Can you post the final persistence.xml file(after the modifications) that you are using? Also have you changed anything in the JBoss installation after downloading it? And can you reproduce this behaviour without your application deployed and only the datasource deployed? Finally do you have any jndi.properties packaged in your application?

              • 4. Re: Problem getting JDBC datasource from JBOSS
                jaikiran

                One more observation, you seem to be creating the entity manager using the entity manager factory. Maybe there might be a problem there. But that does not explain why, the simple lookup of the datasource through a jsp returns null. Try this from a very simple jsp in your application:


                <%
                Properties props = new Properties();
                props.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
                props.put(Context.PROVIDER_URL,"jnp://localhost:1099");
                props.put(Context.URL_PKG_PREFIXES,"org.jboss.naming.jnp.interfaces");
                Context ctx = new InitialContext(props);
                
                Object obj = ctx.lookup("java:MySqlDS");
                
                System.out.println("DS is = " + obj);
                
                %>


                I am suspecting that for some reason maybe the context properties are either not being picked up right or something else is going on.


                • 5. Re: Problem getting JDBC datasource from JBOSS
                  bikerzon

                  Here's my final persistence.xml :

                  <?xml version="1.0" encoding="UTF-8"?>
                  <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
                   <persistence-unit name="jboss_jpa_web_all_in_one">
                   <provider>org.hibernate.ejb.HibernatePersistence</provider>
                   <mapping-file>META-INF/orm.xml</mapping-file>
                   <class>com.hui.Person</class>
                   <properties>
                   <property name="hibernate.connection.datasource" value="java:MySqlDS" />
                   <property name="hibernate.connection.release_mode" value="after_transaction" />
                   <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
                   <property name="hibernate.hbm2ddl.auto" value="create" />
                   <property name="hibernate.cache.use_query_cache" value="false" />
                   <property name="hibernate.show_sql" value="true" />
                   </properties>
                   </persistence-unit>
                  </persistence>
                  
                  


                  I initiate the context with the jndi environment directly from my code, and also I did package the jndi.properties with my apps.

                  The results is also the same - NullPointerException - the return object is null from jndi lookup.

                  But from the JMX console I do see the
                  java:MySqlDS


                  This is too weird.

                  • 6. Re: Problem getting JDBC datasource from JBOSS
                    bikerzon

                    OK here's my last try - :

                    1) I change my persistence.xml to use java:DefaultDS as my datasource - since it is the default datasource come with JBOSS.

                    2) The default database is started (I've checked the log/trace)

                    3) Result - still the same - NullPointerException - even from JBOSS default database.

                    • 7. Re: Problem getting JDBC datasource from JBOSS
                      jaikiran

                      What does this print out when you run this code from the place where you instantiating the entity manager:

                      Properties hibProps = org.hibernate.cfg.Environment.getProperties();
                      props.list(System.out);
                      


                      • 8. Re: Problem getting JDBC datasource from JBOSS
                        jaikiran

                         

                        and also I did package the jndi.properties with my apps.


                        See if removing that file from the application is going to help.


                        • 9. Re: Problem getting JDBC datasource from JBOSS
                          jaikiran

                           

                          11:39:59,609 INFO [STDOUT] 11:39:59,609 INFO [Version] Hibernate Annotations 3.3.0.GA
                          11:39:59,640 INFO [STDOUT] 11:39:59,640 INFO [Environment] Hibernate 3.2.6
                          11:39:59,640 INFO [STDOUT] 11:39:59,640 INFO [Environment] hibernate.properties not found
                          11:39:59,656 INFO [STDOUT] 11:39:59,656 INFO [Environment] Bytecode provider name : javassist
                          11:39:59,656 INFO [STDOUT] 11:39:59,656 INFO [Environment] using JDK 1.4 java.sql.Timestamp handli
                          ng
                          11:39:59,812 INFO [STDOUT] 11:39:59,812 INFO [Version] Hibernate EntityManager 3.3.1.GA
                          11:40:00,359 INFO [STDOUT] 11:40:00,359 INFO [AnnotationBinder] Binding entity from annotated clas
                          s: com.hui.Person
                          11:40:00,875 INFO [STDOUT] 11:40:00,875 INFO [EntityBinder] Bind entity com.hui.Person on table pe
                          rson_table
                          11:40:00,953 INFO [STDOUT] 11:40:00,953 INFO [Version] Hibernate Validator 3.0.0.GA
                          11:40:01,171 INFO [STDOUT] 11:40:01,171 INFO [NamingHelper] JNDI InitialContext properties:{java.n
                          aming.provider.url=jnp://localhost:1099, java.naming.factory.initial=org.jnp.interfaces.NamingContex
                          tFactory}


                          Looks like you are packaging your own version of Hibernate with your application. JBoss-4.2.2GA does not ship with this version of Hibernate. It comes with:

                          15:46:45,666 INFO [main] [Version] Hibernate EntityManager 3.2.1.GA
                          15:46:45,760 INFO [main] [Version] Hibernate Annotations 3.2.1.GA
                          15:46:45,791 INFO [main] [Environment] Hibernate 3.2.4.sp1


                          Try removing Hibernate related jars from your application. Let's see if this is a classloader related issue. Furthermore, are you packaging any jboss related jars too? If you have the list of jars that are packaged and deployed in your application then post them here. And what does your jboss-app.xml look like?

                          • 10. Re: Problem getting JDBC datasource from JBOSS
                            bikerzon

                            Here's the print out :

                            java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
                            java.naming.provider.url=localhost:1099
                            java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

                            I tried to run it without jndi.properties, same error.

                            Is JBOSS4.2.2 not compatible with Hibernate 3.3? I'm getting the latest one.