3 Replies Latest reply on Aug 31, 2012 8:55 AM by sbesada

    Module dependecy clashing

    sbesada

      Hi,

       

         We are trying to deploy an OSGi aplication in JBoss AS 7 which is working perfectly in an Equinox installation. We would like to leverage the capabilities of jboss-modules and jboss-osgi integration but it is indeed this kind of interaction what makes our aplication undeployable in JBoss AS 7.

       

         Our application uses JPA with hibernate for database persistence and has both, hibernate ( and hibernate-annotations ) and javax.persistence present as OSGi bundles. Our application expects javax.persistence API classes to be loaded by the OSGi container classloader to work properly, but what we think is happenning in JBoss AS 7 is that javax.persistence is being loaded by a jboss-module's ModuleClassLoader that it's outside of the OSGi container classloader. We could confirm this point debugging the javax.persistence interactions and found that its thread's classloader is the same classloader as the Jboss Modular Service Container  ( org.jboss.msc ) ...   Does this makes sense?

       

         Is there any way of avoiding sharing at least certain jboss-modules' modules with jboss-osgi running applications?   How can one priorize OSGi bundles over jboss-modules in a given installation?

       

       

      Greets,

        • 1. Re: Module dependecy clashing
          thomas.diesler

          The hibernate team is currently working on an OSGi enabled version of their stuff. In the context of AS7 we are looking at Enterprise OSGi JPA. Please monitor/vote on

          https://issues.jboss.org/browse/AS7-5405

           

          It's high on my priority list and the first approach will probably be to get this working with the OpenJPA provider. Later we will hopefully be able to use the Hibernate provider.

          • 2. Re: Module dependecy clashing
            sbesada

            Hi,

             

            I'm sending you a setup with two errors. The first one is one in which JBoss does't find the persistence context because the bundle javax.persistence uses Thread.currentThread().getContextClassLoader() to load the persistence provider but Thread.currentThread().getContextClassLoader() is null because Jboss sets to null this classLoader. To solve this problem in our example we have set the contextClassLoader to the bundles' classLoader in the bundle: telvent-tp-jboss-persistence, class:IPPersistenceServiceImpl, line 45 (Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader())). The bundle telvent-tp-jboss-persistence calls javax.persistence and now it properly finds the providers.

            This error, Thread.currentThread().getContextClassLoader() == null, happens in whatever bundle that make use of Thread.currentThread().getContextClassLoader().

             

            private static void findAllProviders() throws IOException {

                    ClassLoader loader = Thread.currentThread().getContextClassLoader();

                    Enumeration<URL> resources =

                        loader.getResources("META-INF/services/" + PersistenceProvider.class.getName());

                    Set<String> names = new HashSet<String>();

                    while (resources.hasMoreElements()) {

                        URL url = resources.nextElement();

                        InputStream is = url.openStream();

                        try {

                            names.addAll(providerNamesFromReader(new BufferedReader(new InputStreamReader(is))));

                        } finally {

                            is.close();

                        }

                    }

                    for (String s : names) {

                        try{

                            providers.add((PersistenceProvider)loader.loadClass(s).newInstance());

                        } catch (ClassNotFoundException exc){

                        } catch (InstantiationException exc){

                        } catch (IllegalAccessException exc){

                        }

                    }

                }

             

             

            The second error hst to do with logging. We are using the slf4-framework like jboss, but jboss-osgi loads in first place slf4j-module from its configured modules. For this reason, our bundles are forced to use the same log that jboss is using. Bundles that use Dynamic-Import use our log, along with jboss' log.      

            • 3. Re: Module dependecy clashing
              sbesada

              Hi,

               

              In the last example that I have send you, if you set the contextClassLoader to the bundles' classLoader in the bundle: telvent-tp-jboss-persistence, the example works properly but the provider has to be in the same bundle (telvent-tp-jboss-persistence)  because if you use a fragment, for instace, Jboss doesn't find the provider.