1 Reply Latest reply on Jun 20, 2008 2:11 AM by jaikiran

    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.