7 Replies Latest reply on Jul 14, 2004 12:21 AM by Adrian Brock

    ClassCastException retrieving DataSource on JNDI lookup

    natebowler Newbie

      This is a little frustrating because I've seen this question asked several times on forums, but none of the threads end with any resolution.

      This is my problem:

      I have set up a DataSource for MS SQL, and I can look it up successfully via:

      Context iniCtx = new InitialContext();
      Object o = iniCtx.lookup("java:testDS");

      The object coming back is of type (org.jboss.resource.adapter.jdbc.WrapperDataSource). This object implements javax.sql.DataSource.

      However, whenever I try to cast this objecft to javax.sql.DataSource (or use it as a parameter to a method expecting such), I get a ClassCastException.

      BTW, "o instanceof javax.sql.DataSource" and "javax.sql.DataSource.class.isAssignableFrom( org.jboss.resource.adapter.jdbc.WrapperDataSource.class))" both return FALSE.

      So. I understand this is a ClassLoader issue. BUT WHAT IS THE FIX!

      My mssql-ds.xml file is in the /deploy directoy. I am accessing this DS from inside an EJB packaged in an EAR file.

      Can someone make a post to this thread that contains a resolution???

      Nate

        • 1. Re: ClassCastException retrieving DataSource on JNDI lookup
          Adrian Brock Master

          Run this small program

          System.out.println("DataSource from " + DataSource.class.getClassLoader());
          
          Class[] interfaces = WrapperDataSource.class.getInterfaces();
          for (int x = 0; x < interfaces.length; ++x)
           System.out.println(interfaces[ x ] + " from " + interfaces[ x ].getClassLoader();
          


          then remove the duplicate class(es).

          • 2. Re: ClassCastException retrieving DataSource on JNDI lookup
            natebowler Newbie

            OK. I only had it in 2 other places..:)

            Thanks,

            Nate

            • 3. Re: ClassCastException retrieving DataSource on JNDI lookup
              Eduardo Gouvea Newbie

              We use jboss-app.xml in META-INF folder of EAR file to
              restrict classes to be loaded only by the application's
              ClassLoader.

              Like this:

              <jboss-app>
               <loader-repository>mypackage:loader=myapp.ear</loader-repository>
              </jboss-app>


              It works fine in Jboss 3.0.x. But we had a ClassCastException problem on
              looking up the configured DataSource from JNDI context.

              We had the problem when trying to cast the reference within a Delegate's method
              placed in a JAR on WEB-INF/lib directory of the web application and also
              within a Session Bean in the EJB container.


              After a few debugging tests, we came up with the fact that ClassLoaders
              for javax.sql.DataSource.class were different for the reference coming from
              JNDI context and that which was collocated to the Delegate or Session Bean.


              Debugging output looked like this:

              javax.sql.DataSource.class.getClassLoader():
              org.jboss.mx.loading.UnifiedClassLoader3@1b94ea2{
              url=file:/C:/jboss3.2.3/server/default/tmp/deploy/tmp40857myapp.ear ,addedOrder=37}

              ds.getClass().getClassLoader():
              org.jboss.mx.loading.UnifiedClassLoader3@3b1d04{
              url=file:/C:/jboss3.2.3/server/default/tmp/deploy/tmp40781jboss-service.xml ,addedOrder=2}


              We deleted <loader-repository> element from META-INF/jboss-app.xml so the lookup and casting both
              succeeded.

              But we need the jboss-app.xml configuration in order to isolate legacy applications
              we developed and deployed on the same app server with different versions of the
              same class.


              Is there anything we can do? Is it a bug or an expected behaviour of JBoss ClassLoader
              architeture?


              Thanks,
              Eduardo Gouvea.

              • 4. Re: ClassCastException retrieving DataSource on JNDI lookup
                Adrian Brock Master

                It is expected, why do you need javax.sql in your deployment?

                If you really do want isolation, you would have to copy the entire infrastructure
                (jboss rar, jdbc driver) into the ear, otherwise you will get all sorts of class confusion.

                • 5. Re: ClassCastException retrieving DataSource on JNDI lookup
                  Eduardo Gouvea Newbie

                  I need javax.sql.DataSource in my deployment in order to assembly a list of Value Objects
                  via JDBC instead of query the database through EJB-QL.

                  I also need certain degree of isolation because our deployment lives with legacy releases
                  of our application in the same container.

                  We never had problem in JBoss 3.0.3, but we have in JBoss 3.2.3.

                  I don't want any javax.* inside my EAR, neither does my system administrator because
                  of extra replicated megabytes of infrastruture stuff.

                  Don't you think would be better practice to share common infrastructure resources through
                  ClassLoaders?


                  Thanks,
                  Eduardo Gouvea.

                  • 6. Re: ClassCastException retrieving DataSource on JNDI lookup
                    101 Newbie

                    I have a very similar problem. I'm using ear scooped loader repositories, too, with Jboss 3.2.3.

                    My problem is that when I have a *-ds.xml (hibernate stuff) in the ear, and jboss processes the xml, then it's not using the ear scooped loader repository but instead the standard one (probably the one that loaded hibernate.rar).

                    This prevents the datasource from proper operation, because my user classes needed by hibernate are isolated inside the loader repository.

                    To overcome this i have to add hibernate.rar into the ear, but then i have another problem: i have two ear's and one depending on the other. Both need hibernate.rar but i can't put hibernate.rar in both ear's because jboss fails with an already registered resource adapter error.

                    So i'm stuck... the only solution would be if JBoss would use the classloader that loaded the *-ds.xml to initialize the datasource. If i understand everything, then it could work because an ear scooped loader repository sees the stuff coming from the deploy directory, too. (So both ears would see hibernate classes coming from the hibernate.rar)

                    If it doesn't work, then maybe jboss could tolerate duplicate rar registrations coming from isolated ears.

                    Any opinions, Ardian?

                    Thanks in advance,

                    - 101



                    • 7. Re: ClassCastException retrieving DataSource on JNDI lookup
                      Adrian Brock Master

                      Moderated: HIJACK - start a new thread. My answer solves the stated problem.