1 2 3 Previous Next 39 Replies Latest reply on Dec 19, 2005 11:23 AM by adrian.brock Go to original post
      • 15. Re: Conversation regarding JBoss MC and Nuts container betwe
        ajoo

         

        "adrian@jboss.org" wrote:



        Another concern I have is: there may be bean/service that's designed without the ability to "re-configure".


        We are talking about loosely coupled middleware, not tightly bound implementation detail.


        I guess my question is about the semantics. As a non-intrusive framework, we can't really require pojo to conform to a certain programming paramdiagm. And such non-reconfigurable pojo is certainly possible. And what is the strategy that Jboss mc takes to re-configure such non-reconfigurable service?

        Or, maybe you are saying that jboss mc isn't really for _any_ pojo. It is just for reconfigurable java beans?

        • 16. Re: Conversation regarding JBoss MC and Nuts container betwe
          ajoo

           

          "adrian@jboss.org" wrote:


          Dependency semantics from other frameworks require an adapter
          to have notification of availability and unavailability. This then fires state change
          events for newly satisfied and unsatisfied dependencies.

          You'll never convince me that a piece of xml is going to solve the problem,
          and certainly not anything that assumes a procedure/script.

          It is an event not a process. :-)

          I'm trying to understand the problem, not trying to convince anybody. ;-)

          Since the solutions I came up with all missed the point, can you give a use case and the Jboss mc solution? I guess when I see the use case, I'll feel like:"Oh! That's what he's talking about".


          • 17. Re: Conversation regarding JBoss MC and Nuts container betwe
            ajoo

             

            "adrian@jboss.org" wrote:
            I never understood why software developers are so adverse to state machines?

            State machine complicates things. Stateless is always simpler than stateful. As you said, general scripting is not gonna work with state machine. And also, requiring user to specify dependency explicitly isn't gonna make the product easy to use, I suspect?

            I'm not so adverse to state machine, but I'm trying to understand the reason that state machine is a must, which I think a use case can easily convince me.

            • 18. Re: Conversation regarding JBoss MC and Nuts container betwe
              ajoo

              I've been thinking about the "valve" concept these two days.

              One question I found we may not be on the same page is:

              How does Jboss mc expect itself to be used by the client?

              Is it designed to be some kind of super-duper name server/registry/service locator kind of thing so that clients still call "registry.getBean(bean_name)" to "pull" each bean?

              Or is it a dependency injection framework where client code is not aware of the framework at all and dependencies are simply pushed to these components?

              The "valve" concept is a bit hard to understand in the case of "push", because once a dependency is injected into components, there doesn't look like any chance for the framework to "reconfigure" this dependency. The semantics of such "reconfiguration" is generally undefined. Client code may not even know to read the re-configured value or the dependency is simply not reconfigurable at aLL.

              It is however easy to understand in the case of "pull" approach, because we can add "valve" logic to the "getBean(bean_name)" function so that when the bean is being reconfigured, we just throw exception or wait.

              Hopefully I'm not adding more confusion. :-)

              • 19. Re: Conversation regarding JBoss MC and Nuts container betwe
                bill.burke

                You want some use-cases for why we need a state machine for our IoC container? Here's two. One is within the app server, the other is outside.

                Inside app server:

                Take Java EE 5 .ear file. There is no more application.xml file. You have Entity beans, a jboss datasource, and EJBs that reference each other and the entity beans. Entities depend on datasource, EJBs depend on Entity Manager. Deployer has no knowledge that datasource must be deployed 1st, entity beans second, EJBs third. Also, maybe the user forgot to declare a datasource binding? Since services, components, etc. may be able to be deployed in separate jars and and reusable packages, the simple Spring case doesn't filter over.

                This is even worse in out of the container:
                With Embeddable EJB3 we search java.class.path system property to search for all jars. You get the list of these jars in no predefined order. You have the same dependency problems as above, but since the java.class.path can be jumbled, you have no hints that the .ear packaging structure gives you.

                Is that enough of a usecase for you? You not only have to handle cross-package dependencies, but you also want to notify to the user when they may have forgotten to configure/declare something in their classpath or .ear file.

                • 20. Re: Conversation regarding JBoss MC and Nuts container betwe

                   

                  "ajoo" wrote:


                  I guess my question is about the semantics. As a non-intrusive framework, we can't really require pojo to conform to a certain programming paramdiagm. And such non-reconfigurable pojo is certainly possible. And what is the strategy that Jboss mc takes to re-configure such non-reconfigurable service?

                  Or, maybe you are saying that jboss mc isn't really for _any_ pojo. It is just for reconfigurable java beans?


                  No. These features are adding by decorators, not by modifying the POJO.
                  See this for how to use "AOP" to "introduce" new behaviour without modifying existing code.
                  http://wiki.jboss.org/wiki/Wiki.jsp?page=GOFObservable

                  My point was that aren't going to "suspend service" on a "java.lang.String"
                  or even an internal pool or cache. You do it at the service level or entry point.
                  But the MC needs to know what those are (by decorating them) and what
                  that service uses.

                  And there is a difference between changing a config parameter (that doesn't requre
                  a restart - e.g. pool size) and changing a configurable plugin (that does require a suspension - e.g. the pool implemenation for a service).

                  • 21. Re: Conversation regarding JBoss MC and Nuts container betwe
                    ajoo

                    It took me several days to re-think and digest what you guys said. :-)

                    Now it appears somewhat more clear to me what the state machine is for. Thanks for spending all this time.

                    Bill, doesn't Java EE 5 ear file contain an "application deployment descriptor"? And if it is not present, "naming convention" is used to figure out the dependencies? (Just found it in the java EE 5 spec)

                    If so, once the deployer knows which is "ejb", which is "web", it sounds trivial to figure out the deployment order.

                    I do not know the embedded ejb case, but it still sounds to me like a module level dependency analysis. And dependency analysis on granularity of component/service level doesn't seem like a perfect fit.

                    What I mean is, module level dependency analysis should be simpler to implement. And it is also better to de-couple module dependency management from the container that manages individual components/services.

                    Overall, you gave two nice practical examples that need dependency anylysis and management, but they don't seem to justify component level dependency.

                    With that said, I guess I kinda get some idea of why "dependency" on component level is needed. Correct me if I'm wrong. As what Adian said, if we ever need to reconfigure/re-deploy an individual component, we need to know the components that depend on it in order to ripple reconfigurations/redeployments up the dependency chain.


                    Does that sound like I'm getting it?


                    • 22. Re: Conversation regarding JBoss MC and Nuts container betwe
                      ajoo

                      Adrian, let me summarize my understanding so far so you can easily see whereI am and what I'm mistaken about.


                      1. It is a required feature for JBoss MC to allow reconfigure/redeploy individual services.

                      2. "reconfiguration" means that a property of the service object is set to a different value.

                      3. "redeployment" means that the service object is replaced with a new service object by re-constructing it using the meta data.

                      4. When a service is "reconfigured", the services depending on it don't have to be changed.

                      5. When a service is "re-deployed", services whose property values are set to this redeployed guy, and services whose constructor/factory parameters were set to this redeployed guy, will be affected.

                      6. If service A is redeployed and service B's properties reference A, service B needs to be re-configured.

                      7. If service A is redeployed and service B's parameters reference A, service B needs to be re-deployed as well. (because there's no way to re-configure service B)

                      8. When a service needs to be re-configured, property setters are called and the work is done.

                      9. When a service needs to be re-deployed, the first step is to back out its state. If it is in "INSTALLED" state, state machine should walk it back to "UNINSTALLED" step by step.



                      That's all I can think of so far. Am I somehow getting the idea? or I'm still totally confused?



                      • 23. Re: Conversation regarding JBoss MC and Nuts container betwe

                         

                        "ajoo" wrote:
                        Adrian, let me summarize my understanding so far so you can easily see whereI am and what I'm mistaken about.

                        1. It is a required feature for JBoss MC to allow reconfigure/redeploy individual services.


                        Not required, but possible. It depends upon what the user wants to do.
                        Think of it as an optional plugin.


                        2. "reconfiguration" means that a property of the service object is set to a different value.

                        Correct.


                        3. "redeployment" means that the service object is replaced with a new service object by re-constructing it using the meta data.

                        Yes, and restoring its internal state from either some passivated version or pulling it from the cluster is an optional plugin.


                        4. When a service is "reconfigured", the services depending on it don't have to be changed.

                        Correct. Though technically they may still need to be suspened.
                        e.g. if you change the jndi name of the entry point.


                        5. When a service is "re-deployed", services whose property values are set to this redeployed guy, and services whose constructor/factory parameters were set to this redeployed guy, will be affected.

                        Not just the injected values, but the type system as well in some cases.
                        i.e. you have to reload the classes that are referencing the changed class.


                        6. If service A is redeployed and service B's properties reference A, service B needs to be re-configured.


                        This depends what you mean by redeployed. In some cases it is loosely coupled
                        so service is just suspended. In others the name changes or type system is affected,
                        etc.


                        7. If service A is redeployed and service B's parameters reference A, service B needs to be re-deployed as well. (because there's no way to re-configure service B)

                        Yes this is the difference between loosely coupled (by value) and tightly coupled (by reference).


                        8. When a service needs to be re-configured, property setters are called and the work is done.

                        Again it depends upon metadata attached to the property. In most cases a property
                        change doesn't require a restart. But sometimes it does. Another example
                        would be re-injecting a different reference to a DataSource.
                        You can't just swap the reference because there are ongoing transactions using
                        the old DataSource/connections.


                        9. When a service needs to be re-deployed, the first step is to back out its state. If it is in "INSTALLED" state, state machine should walk it back to "UNINSTALLED" step by step.



                        You back out the state as far as you need to go for that use case.
                        This could be nothing (property change) to a full redeploy (class change)


                        That's all I can think of so far. Am I somehow getting the idea? or I'm still totally confused?



                        • 24. Re: Conversation regarding JBoss MC and Nuts container betwe

                           

                          "ajoo" wrote:

                          If so, once the deployer knows which is "ejb", which is "web", it sounds trivial to figure out the deployment order.


                          The spec deployers are example of
                          spec deployment -> pojo deployment
                          mapping.

                          The spec deployments are "relatively trivial" since the metadata and classes
                          and even related entry points/applications are deployed together (e.g. in an ear).

                          It doesn't have to be done this way. e.g. the metadata can be "cross cutting".

                          • 25. Re: Conversation regarding JBoss MC and Nuts container betwe

                             

                            "adrian@jboss.org" wrote:

                            It doesn't have to be done this way. e.g. the metadata can be "cross cutting".


                            By which I mean, it is much easier for the user, but harder for the container ;-)
                            if you deploy your security in one file

                            <bean name="LdapSecurity/>
                            


                            What it means in another file:
                            for @SecuredPOJO
                            apply aspects
                            org.jboss.security.Authentication
                            org.jboss.security.Authorization
                            


                            Then have multiple applications link them together
                            @SecuredPOJO("LdapSecurity")
                            public class MyClass
                            {
                            }
                            
                            @SecuredPOJO("KerberosSecurity")
                            public class AnotherClass
                            {
                            }
                            
                            


                            It is then the container's job to understand this cross cutting dependency
                            and take appropriate actions when this configuration changes.


                            • 26. Re: Conversation regarding JBoss MC and Nuts container betwe
                              ajoo

                               

                              "adrian@jboss.org" wrote:
                              "ajoo" wrote:

                              1. It is a required feature for JBoss MC to allow reconfigure/redeploy individual services.


                              Not required, but possible. It depends upon what the user wants to do.
                              Think of it as an optional plugin.

                              Maybe better call it a "mandatory" feature because we don't even need the state machine at all if this feature is not required.


                              "adrian@jboss.org" wrote:


                              5. When a service is "re-deployed", services whose property values are set to this redeployed guy, and services whose constructor/factory parameters were set to this redeployed guy, will be affected.

                              Not just the injected values, but the type system as well in some cases.
                              i.e. you have to reload the classes that are referencing the changed class.

                              Classes are dynamically loaded anyway. It may be only necessary if the static initializers used the changed class. Is this the "classloader dependency" you talked about?


                              "adrian@jboss.org" wrote:


                              6. If service A is redeployed and service B's properties reference A, service B needs to be re-configured.


                              This depends what you mean by redeployed. In some cases it is loosely coupled
                              so service is just suspended. In others the name changes or type system is affected,
                              etc.

                              I defined "reconfigure" and "redeploy" in 2 and 3. "redeploy" means that the object of B needs to be re-constructed, not just a state mutation.



                              "adrian@jboss.org" wrote:


                              7. If service A is redeployed and service B's parameters reference A, service B needs to be re-deployed as well. (because there's no way to re-configure service B)

                              Yes this is the difference between loosely coupled (by value) and tightly coupled (by reference).

                              Hm. What does that mean?
                              "b = new B(a)" is also by reference. Yet, b has to be re-constructed when a is re-constructed.
                              While in case of "b = new B(); b.setA(a);", b does not have to be re-constructed. We just invoke "b.setA(a)" again.

                              "adrian@jboss.org" wrote:


                              8. When a service needs to be re-configured, property setters are called and the work is done.

                              Again it depends upon metadata attached to the property. In most cases a property
                              change doesn't require a restart. But sometimes it does. Another example
                              would be re-injecting a different reference to a DataSource.
                              You can't just swap the reference because there are ongoing transactions using
                              the old DataSource/connections.

                              Even for a non DataSource thing, when you re-deploy a service, how do we know the object is not already obtained and kept as reference by a client? We have no way to tell the client to "re-obtain me" in such case.

                              "adrian@jboss.org" wrote:

                              You seem to be getting it. The redeploy/reconfigure is really a false dichotomy.
                              How much you have to unwind the state transitions depends upon the use case.

                              The really good implementations don't require any unwind/suspension
                              or nearly nothing (see the thread in the deployers forum about "transactional deployment") because they use additional tricks.


                              Confused again. I defined "reconfigure" as a state change of a service with the service object identity un-touched, while "re-deploy" as a re-construction of the service object using the meta data with the object identity changed. Do you mean this dichotomy is false?



                              • 27. Re: Conversation regarding JBoss MC and Nuts container betwe

                                Sorry. I am trying to take you through baby steps towards why a state machine
                                is necessary. :-)

                                We started with the ability to transparently recycle a "loosely coupled service".
                                In practice the implementation doesn't have to be dumb as my original description.
                                It depends upon what is being changed.

                                Some properties can be changed "on the fly", others have significant impact.
                                The difference is described in the metadata and the impact is handled
                                by the state machine. The class bytecode and its references is really just another
                                cross cutting property/dependency of the pojo even though it is a very signifant one. :-)

                                On your "definitions".

                                Read "Humpty Dumpty" by Lewis Carrol.
                                "When I use a word,' Humpty Dumpty said, in rather a scornful tone, `it means just what I choose it to mean -- neither more nor less."

                                The lesson being, don't get caught up on names. They are short cut to actually thinking. Think about the meaning of the sentance :-)

                                • 28. Re: Conversation regarding JBoss MC and Nuts container betwe
                                  ajoo

                                  The technique to detect class bytecode dependency is an interesting topic to me cuz I can't think of a good way of implementing it out of my head right now.

                                  But I think a more important question to keep asking again and again is:

                                  Even for a non DataSource thing, when we re-deploy a service, how do we know the object is not already obtained and kept as reference by a client? We have no way to tell the client to "re-obtain me" in such case.

                                  Let's say a client is designed as:

                                  class BankAccount{
                                   private A a;
                                   void f(){
                                   this. a = jboss_container.get("service A");
                                   }
                                  }


                                  Suppose the system is already running, and at a certain time in the past the "BankAccount.f()" executed. That caused "BankAccount" as a client of jboss container, obtained an instance of A from the container and kept it locally for future use.

                                  If we now choose to re-deploy "service A", how do we know that BankAccount keeps a local reference of the old A? I suppose we have no way to know that.
                                  But if we do not know, "BankAccount" will still hold a reference to the old A even after a new A is deployed. And that is not desirable.


                                  • 29. Re: Conversation regarding JBoss MC and Nuts container betwe

                                     

                                    "ajoo" wrote:

                                    "adrian@jboss.org" wrote:

                                    You seem to be getting it. The redeploy/reconfigure is really a false dichotomy.
                                    How much you have to unwind the state transitions depends upon the use case.

                                    The really good implementations don't require any unwind/suspension
                                    or nearly nothing (see the thread in the deployers forum about "transactional deployment") because they use additional tricks.


                                    Confused again. I defined "reconfigure" as a state change of a service with the service object identity un-touched, while "re-deploy" as a re-construction of the service object using the meta data with the object identity changed. Do you mean this dichotomy is false?


                                    There are two different identities. Think of it as the difference between
                                    == which is by reference
                                    .equals() which is by value
                                    though that still doesn't quite capture the important difference which is loose coupling.

                                    If things are hardwired by reference then they are tightly coupled.
                                    In middleware we try to remove these such that we can introduce extra behaviour.

                                    But just using "by value" or introducing a proxy/delegate doesn't necessarily solve the
                                    problem unless the microcontainer is aware of what the link means and how
                                    changes might affect the link.

                                    A dichotomy means you have two choices. In practice there are more options
                                    available if you implement it correctly (have loose coupling), you can have the benefits of
                                    "by reference" and still do the middleware.

                                    For the "tricks", here is a quick overview I gave someone from Novell in a different context. See the parts relating to Atomic deployments, etc.
                                    http://www.jboss.com/index.html?module=bb&op=viewtopic&t=63437

                                    This obviously only works in a middleware environment.
                                    Having two instances of somebody's singleton class in a tightly coupled
                                    application isn't a problem we need to solve.

                                    Or if we do, we redeploy everything that might be using the
                                    singleton behind suspended entry points rather than do a "quick flip".
                                    The examples of this in middleware are pretty fundamental, e.g.
                                    redeploying the transaction manager or security service.
                                    In this circumanstance, you're really not going to "hot deploy" anyway.
                                    You just reboot.