7 Replies Latest reply on Jul 31, 2006 12:05 PM by Weston M. Price

    Can't connect to global namespace datasource from servlet

    Dolly D Newbie

      I just recently started playing with JBoss. I have been successful so far. But now I am stuck on a datasource issue. I need to access a MySQL DB from a servlet to read/write xml content.

      Here is what I have so far:

      mysql-ds.xml -

      <local-tx-datasource>
      <jndi-name>jdbc/MySqlDS</jndi-name>
      <use-java-context>false</use-java-context>
      <connection-url>jdbc:mysql://localhost:3306/proxyServletDB</connection-url>
      <driver-class>com.mysql.jdbc.Driver</driver-class>
      <user-name>root</user-name>
      pword
      <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>

      <type-mapping>mySQL</type-mapping>

      </local-tx-datasource>


      web.xml -
      <web-app>

      <!-- JDBC DataSources (java:comp/env/jdbc) -->
      <resource-ref>
      The default DS
      <res-ref-name>jdbc/MySqlDS</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
      </resource-ref>

      < ... >
      </web-app>

      jboss-web.xml -
      <jboss-web>
      <resource-ref>
      <res-ref-name>jdbc/MySqlDS</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <jndi-name>java:/MySqlDS</jndi-name>
      </resource-ref>
      </jboss-web>

      Servlet -
      Context ctx = new InitialContext();
      DataSource ds = (DataSource)ctx.lookup("java:/comp/env/jdbc/MySqlDS");

      I think these are the relevant files. I could access the datasource from the local jndi namespace by using lookup("java:/jdbc/MySqlDS"). But I need it to be global so that other servlets, from other machines can use it. Which is when I added: <use-java-context>false</use-java-context> to my mysql-ds.xml file so that the default, local java:/ namespace won't be used.
      But now whenever the servlet is invoked I get the error that says MySqlDS not bound (complete trace shown below).

      Error I get when I try to invoke the servlet :
      16:34:47,328 ERROR [STDERR] javax.naming.NamingException: Could not dereference object [Root exception is javax.naming.N
      ameNotFoundException: MySqlDS not bound]
      16:34:47,328 ERROR [STDERR] at org.jnp.interfaces.NamingContext.resolveLink(NamingContext.java:1067)
      16:34:47,328 ERROR [STDERR] at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:700)
      16:34:47,328 ERROR [STDERR] at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:716)
      16:34:47,328 ERROR [STDERR] at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:587)
      16:34:47,328 ERROR [STDERR] at javax.naming.InitialContext.lookup(InitialContext.java:351)
      16:34:47,328 ERROR [STDERR] at ReadServlet.doGet(ReadServlet.java:28)
      16:34:47,328 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
      16:34:47,328 ERROR [STDERR] at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
      16:34:47,328 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterCha
      in.java:252)
      16:34:47,328 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
      173)
      16:34:47,328 ERROR [STDERR] at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
      16:34:47,328 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterCha
      in.java:202)
      16:34:47,328 ERROR [STDERR] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:
      173)
      16:34:47,343 ERROR [STDERR] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
      16:34:47,343 ERROR [STDERR] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
      16:34:47,343 ERROR [STDERR] at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValv
      e.java:175)
      16:34:47,343 ERROR [STDERR] at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:74)
      16:34:47,343 ERROR [STDERR] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
      16:34:47,343 ERROR [STDERR] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
      16:34:47,343 ERROR [STDERR] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
      16:34:47,343 ERROR [STDERR] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
      16:34:47,343 ERROR [STDERR] at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
      16:34:47,343 ERROR [STDERR] at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection
      (Http11BaseProtocol.java:664)
      16:34:47,343 ERROR [STDERR] at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
      16:34:47,343 ERROR [STDERR] at org.apache.tomcat.util.net.MasterSlaveWorkerThread.run(MasterSlaveWorkerThread.java:1
      12)
      16:34:47,343 ERROR [STDERR] at java.lang.Thread.run(Thread.java:595)
      16:34:47,343 ERROR [STDERR] Caused by: javax.naming.NameNotFoundException: MySqlDS not bound
      16:34:47,343 ERROR [STDERR] at org.jnp.server.NamingServer.getBinding(NamingServer.java:529)
      16:34:47,343 ERROR [STDERR] at org.jnp.server.NamingServer.getBinding(NamingServer.java:537)
      16:34:47,343 ERROR [STDERR] at org.jnp.server.NamingServer.getObject(NamingServer.java:543)
      16:34:47,343 ERROR [STDERR] at org.jnp.server.NamingServer.lookup(NamingServer.java:296)
      16:34:47,343 ERROR [STDERR] at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:625)
      16:34:47,343 ERROR [STDERR] at org.jnp.interfaces.NamingContext.lookup(NamingContext.java:587)
      16:34:47,343 ERROR [STDERR] at javax.naming.InitialContext.lookup(InitialContext.java:351)
      16:34:47,343 ERROR [STDERR] at org.jnp.interfaces.NamingContext.resolveLink(NamingContext.java:1061)
      16:34:47,343 ERROR [STDERR] ... 25 more

      service=jndiview -

      Global JNDI Namespace

      +- jdbc (class: org.jnp.interfaces.NamingContext)
      | +- MySqlDS (class: javax.sql.DataSource)


      Any ideas/suggestions? I?ve been stuck on this thing for almost 3 days now.

      Thanks!

        • 1. Re: Can't connect to global namespace datasource from servle
          Weston Price Newbie

          Don't do

          <use-java-context>false</use-java-context>

          This doesn't have anything to do with Servlets, but rather, accessing the DS outside of the container. It's an experimental feature of JBoss, at best and something we encournage people NOT to use.

          This is why you are having a problem BTW.

          Remove that tag, and your code should work fine.



          • 2. Re: Can't connect to global namespace datasource from servle
            Dolly D Newbie

            I understand that. But if I delete that tag then the DS will come under java:/ local namespace.

            - If it is local then can servlets on other servers access it? What if it is a clustered environment?
            - If that tag is present then I can access the DS using java:/jdbc/MySqlDS, not using java:/comp/env/jdbc/MySqlDS. So I guess my question now is what is the actual difference between those namespaces?
            - Are these the only files I need to modify to make the DS available?

            Thanks for your help, wmprice!

            • 3. Re: Can't connect to global namespace datasource from servle
              Weston Price Newbie

              The local java namespace is used for ApplicationComponents (ie Servlets, EJB's) residing in the same application server. It is known as the ENC (environment naming context).


              - If it is local then can servlets on other servers access it?


              No.Using a datasource outside of the local container is discouraged. It was put in place solely for TCK compatiblity. From the Wiki:


              Note: JBoss does not recommend using this feature on a production environment. It requires accessing a connection pool remotely and this is an anti-pattern as connections are not serializable. Besides, transaction propagation is not supported and it could lead to connection leaks if the remote clients are unreliable (i.e crashes, network failure). If you do need to access a datasource remotely, JBoss recommends accessing it via a remote session bean facade.



              What if it is a clustered environment?


              Datasources are non-clusterable. Each datasource is particular to the node on which it resides.


              - If that tag is present then I can access the DS using java:/jdbc/MySqlDS, not using java:/comp/env/jdbc/MySqlDS.


              You could, but this would defeat the purpose of using an resource-ref. A resource-ref is a logical binding of a resource-ref name to an actual JNDI name. You could very well lookup the DataSource directly from JNDI, but if the JNDI name were to change, your code would have to change. The resource-ref shields you 'hard-coding' the JNDI name in your application.

              This is the purpose of the java:comp/env namespace. Basically it's a read-only JNDI namespace reserved for application components to store references to J2EE resources.


              - Are these the only files I need to modify to make the DS available?


              Yes.

              • 4. Re: Can't connect to global namespace datasource from servle
                Dolly D Newbie

                Okay, I guess I will create the session bean facade. But I still have a few questions to really make it clear. If I leave the datasource in the local namespace with jdbc/MySqlDS as JNDI name, I can't access it using java:comp/env/jdbc/MySqlDS; this throws an error that says:

                javax.naming.NamingException: Could not dereference object [Root exception is javax.naming.NameNotFoundException: MySqlDS not bound]

                Why so?
                Forgive me if I'm not understanding the basic point here. But I'd really like to know :)

                What is right syntax to access it? And so, does that mean anything in the global datasource cannot be accessed outside the app server? Or is it only for datasources?

                Thanks a bunch!

                • 5. Re: Can't connect to global namespace datasource from servle
                  Weston M. Price Master

                  The remaing issue is in your jboss-web.xml file you are binding the reference as

                  
                  <jboss-web>
                  <resource-ref>
                  <res-ref-name>jdbc/MySqlDS</res-ref-name>
                  <res-type>javax.sql.DataSource</res-type>
                  <jndi-name>java:/MySqlDS</jndi-name>
                  </resource-ref>
                  </jboss-web>
                  
                  



                  Yet, your datasource is bound as

                  <jndi-name>jdbc/MySqlDS</jndi-name>
                  
                  
                  I would suggest chaning the JNDI name in the *-ds.xml file to be just
                  
                  
                  <jndi-name>MySqlDS</jndi-name>
                  
                  
                  
                  The 'java:' prefix is appended automatically. Changing this, your lookup should work.
                  
                  
                  
                  


                  • 6. Re: Can't connect to global namespace datasource from servle
                    Dolly D Newbie

                    Yes, that did the trick.

                    Thanks, weston, for your patience and help! :)

                    BTW, why isn't there a universal doc that would teach beginners like me on how to do exactly what I got stuck on? That would really be helpful and would save many hours.

                    • 7. Re: Can't connect to global namespace datasource from servle
                      Weston M. Price Master

                      Datasource information can be found in a variety of places on our Wiki.

                      Start here:
                      http://wiki.jboss.org/wiki/Wiki.jsp?page=JBossJCA

                      Specific DS deployments
                      http://wiki.jboss.org/wiki/Wiki.jsp?page=DSdotXML