1 2 3 4 Previous Next 47 Replies Latest reply on Sep 8, 2005 7:17 PM by Scott Stark

    HARDeployer removal proposal

    Steve Ebersole Apprentice

      So as requested in http://jira.jboss.com/jira/browse/JBAS-2000, lets discuss this.

      So basically what you are saying regarding the extraction of URLs to use is that I would simply internalize that into the org.jboss.hibernate.jmx.Hibernate.startService() method rather than a deployer being needed to inject that value. I actually really like that since it will also give the added benefit of the HAR archive not necessarily needing the hbm.xml files nor the domain classes to be included at the root of the HAR archive itself; users could actually jar it seperately and just include the jar into the har since those bundled jars should then be available on the classloader you are talking about. Can I use that AbstractWebContainer.getClassLoaderURLs() method here? Or do I need to duplicate that logic over to my MBean?

        • 1. Re: HARDeployer removal proposal
          Steve Ebersole Apprentice

          Follow-on question:

          Does this neccessarily need to happen from The Hibernate MBean's startService()? Specifically, the Thread.currentThread().getContextClassLoader() part...

          The MBean gives the user a managed operation to rebuild the SessionFactory; both this and the startService() go through an internal method named buildSessionFactory(). Would it be safe to have the Thread.currentThread().getContextClassLoader() call in that method, such that rebuilding the session factory could potentially "notice" added/removed domain classes? I guess this would depend upon whether subsequent calls into the MBean (aka, the rebuildSessionFactory() managed operation) would be executed on a thread which has the same "URL visibility" as the one from startService(); is this always the case (at least as long as the request is made through the JMX container)?

          • 2. Re: HARDeployer removal proposal
            Adrian Brock Master

            My understanding is that you only need the deployer to get the urls to search
            from the DeploymentInfo.

            If you use code like the
            AbstractWebContainer.getClassLoaderURLs()
            you don't need the deployment info.

            I'm not saying use the above method as is, which will give you ALL urls of
            all classloaders in the loader repository.

            Rather you just need the urls of the mbean's context classloader
            (the TCL during startService or whatever it invokes),
            i.e. the sar, ejb, ear, etc. urls from the deployment it is a part of.

            • 3. Re: HARDeployer removal proposal
              Adrian Brock Master

              I don't understand the added/removed domain classes stuff.
              JBoss does not currently support classloader dependencies
              or hot deployment of single classes inside a deployment (other than what the jvm provides for hotswap when debugging)

              • 4. Re: HARDeployer removal proposal
                Steve Ebersole Apprentice

                *** OK actually formatted :) ***

                what i mean is this; currently the .har format is:

                .har/
                 meta-inf/
                 hibernate-service.xml
                 MyMapping.hbm.xml
                 org/
                 myproject/
                 MyMapping.class
                 ehcache.jar
                 myotherjars.jar
                


                So, the .har itself is added to the deployment classloader. The HARDeployer, then marks any nested jars as deployable (mimicing the behavior of SARDeployer).

                However, what would be nice, and people have asked for, is to instead be able to do this:

                .har/
                 meta-inf/
                 hibernate-service.xml
                 mydomainclassesandmappings.jar
                 ehcache.jar
                 myotherjars.jar
                

                such that mydomainclassesandmappings.jar contains the domain classes as well as their mappings. Then later, say I (assuming .har is exploded) drop in "myextendeddomainclassesandmappings.jar" which contains further domain classes and mappings.

                I understand JBoss will not handle this automatically in terms of forcing a redploy of the mbean/deployment. I am talking about the information available to me when the user does the above mentioned "drop" and then performs the "rebuildSessionFactory()" managed operation.

                • 5. Re: HARDeployer removal proposal
                  Steve Ebersole Apprentice

                   

                  "adrian@jboss.org" wrote:
                  Rather you just need the urls of the mbean's context classloader
                  (the TCL during startService or whatever it invokes),
                  i.e. the sar, ejb, ear, etc. urls from the deployment it is a part of.


                  Well, that's an important distinction ;)

                  Yes, I am only interested in the URL pertaining to the deployment (as well as anything "under" it). What I am uncertain of is exactly how to get that information from inside the mbean.

                  • 6. Re: HARDeployer removal proposal
                    Adrian Brock Master

                    Yes, and what I'm saying is you could have

                    myejbs.jar/
                     META-INF/
                     ejb-jar.xml
                     mydomainclassesandmappings.jar
                     ehcache.jar
                     myotherjars.jar
                     hibernate-service.xml
                    


                    When the MBean in hibernate-service.xml is deployed, it will ask the classloader
                    for the urls in the TCL and get all four jar urls (the main jar and the embedded jars)
                    as possibilities to search.

                    See:
                    http://docs.jboss.org/jbossas/javadoc/4.0.2/org/jboss/mx/loading/RepositoryClassLoader.html#getAllURLs()

                    • 7. Re: HARDeployer removal proposal
                      Steve Ebersole Apprentice

                      Yes, we are saying the same thing in terms of the capaibilities.

                      I am just uncertain how the MBean would

                      "adrian@jboss.org" wrote:
                      ask the classloader
                      for the urls in the TCL and get all four jar urls (the main jar and the embedded jars)
                      as possibilities to search.


                      I'll take a look at that link and see if that helps me see the light.

                      • 8. Re: HARDeployer removal proposal
                        Adrian Brock Master

                        Actually, I posted the wrong link:
                        http://docs.jboss.org/jbossas/javadoc/4.0.2/org/jboss/mx/loading/RepositoryClassLoader.html#getClasspath()

                        You would want to use code like:

                        URL[] urls = null;
                        ClassLoader cl = Thread.currentThread().getContextClassLoader();
                        if (cl instanceof RepositoryClassLoader)
                         urls = ((RepositoryClassLoader) cl).getClassPath();
                        else if (cl instanceof URLClassLoader)
                         urls = ((URLClassLoader) cl).getURLs();
                        else
                         throw new DeploymentException("Unable to determine urls for classloader " + cl);
                        // Use the urls here
                        



                        • 9. Re: HARDeployer removal proposal
                          Steve Ebersole Apprentice

                          So coded up this solution and it seems to be working fine.

                          However, I did run into one thing I found initially puzzling, but which might actually be problematic later.

                          So first I need to point out that I am running my initial tests using a locally modified HARDeployer, which simply never injects a "HarUrl". Maybe what I am seeing is a result of that, and all will be good once I switch over to allowing the other deployers to pick this up.

                          Anyway...

                          My testsuite deployment is an ear that looks like:

                          test.ear/
                           test-ejb.jar
                           test.har
                          

                          So given this, the classpath entries my code is checking are:
                          1) the ear itself
                          2) the har
                          3) the har file's hibernate-service.xml
                          4) the ejb-jar

                          The potentially problematic piece is say that I have two SARs bundled into the same top-level deployable, each defining a Hibernate MBean. So basically, each of the two session factories will know about all the classes from his SAR but also about all the classes from the other SAR.

                          Envision a scenario where an enterprise app needs to talk to two different databases. In Hibernate that explicitly means two seperate session factories, which means I'll need two different mbeans defined. The problem is that there is no way to segment which portions of deployment pertain to DB1 access vs which pertain to DB2 access, because it's just a classpath.

                          Thoughts?

                          • 10. Re: HARDeployer removal proposal
                            Adrian Brock Master

                            How is this situation dealt with in a standalone java application where everything
                            is also in the same classpath?

                            • 11. Re: HARDeployer removal proposal
                              Steve Ebersole Apprentice

                              Well, you explicit list the mappings to use :)

                              • 12. Re: HARDeployer removal proposal
                                Steve Ebersole Apprentice

                                One other thing that has to happen if we do go down this path: we need to add .har as a standard recognized archive extension, so that we don't leave existing users out-to-dry.

                                There have been numerous discussions about attaching listeners/aspects to service lifecycle. A long time ago, one such discussion was to also remove the need for a HARDeployer by simply having a generic way for services to "know about" there deployment url. What ever happened with those discussions? Personally, I think that is a more viable approach simply because it does allow this ability to still have multiple session factories defined within a single deployment (provided each is within it own nested deployment bundle).

                                Short-term couldn't we just introduce an interface like:

                                public interface DeploymentURLAware {
                                 public void setDeploymentUrl(URL deploymentURL);
                                }
                                

                                which services could optionally implement to be notified about its deployment url?

                                The question of course is what is responsible for notifying such mbeans. ServiceConfigurator seems the logical choice but it, unfortunately, knows nothing about DeploymentInfo or deployment urls. Guess it could be done in SubDeployerSupport.create(DI).

                                • 13. Re: HARDeployer removal proposal
                                  Steve Ebersole Apprentice

                                  So I guess something like this is not possible/desireable...

                                  I think we need to ditch this attempt to remove the HARDeployer by reading classpath info. Losing the ability to deploy multiple segmented SessionFactories from within the same top-level deployment is unacceptable.

                                  • 14. Re: HARDeployer removal proposal
                                    Steve Ebersole Apprentice

                                    So to be completely clear...

                                    I totally agree with you that it is completely silly having a ~400 line class (HARDeployer) whose sole resposibility is to set a single MBean attribute (just look at my comments in HARDeployer ;). If there were some other simple way for an MBean to know about the DeploymentInfo (or even just the DeploymentInfo.url) from whence it came, I'd be all for using that instead of a full deplyer. But in my limited knowledge of the AS internals, there does not seem to be such a simple alternate approach. Please, if I am wrong, correct me.

                                    In the end, I think the "aggresive scanning" of the deployment classpath entries is very, very good idea. But based on the previous discussion regarding multiple SessionFactoys, I think it makes sense as an option on the MBean rather than as the defacto way in which mappings are discovered.

                                    1 2 3 4 Previous Next