13 Replies Latest reply on Aug 25, 2006 4:55 PM by Anil Saldanha

    Behavior with AbstractKernelController

    Anil Saldanha Master

      I have a usecase wherein a Service needs an attribute set to start correctly. So my testcase does the following:

      a) Start the service. (basically needs to fail)
      b) Set the required attribute and start the service.
      c) Service should start.

      There are issues I see:
      1) When the service fails to start, instead of throwing an exception for the following call:

      server.invoke(serviceOName,"start", new Object[0], new String[0]);

      the MC logs the error. So **no** exception is thrown.

      2) After the service has failed to start, then removal of the -service.xml from the deploy directory, does not remove the registration of the service (that was done through "create" step)
      Basically, what I am saying is that if for any reason, a service fails to "start" after a successful "create" step, then we can not deal with this service in a undeploy->redeploy situation (Mainly via a testsuite) Until the server bounce, this service is stuck.

      The test that can be used is "testAuthConf" of

      ant -Dtest=org.jboss.test.security.test.DynamicLoginConfigServiceUnitTestCase one-test

        • 1. Re: Behavior with AbstractKernelController
          Scott Stark Master

          The problem is that the start exception thrown by the DynamicLoginConfig.startService method is transititioning the ServiceControllerContext to an error state, but no exception is thrown from the ServiceController.start(ObjectName) method.

          ServiceControllerContext@256bf3{name=jboss:service=TestDynamicLoginConfig target=null state=**ERROR** mode=Manual requiredState=Installed depends=AbstractDependencyInfo@e2e2bf{idependOn=[]} error=java.lang.IllegalStateException: AuthConfig is defaulting to conf/login-config.xml. Please check your archive.
           at org.jboss.security.auth.login.DynamicLoginConfig.validateAuthConfigURL(DynamicLoginConfig.java:271)
           at org.jboss.security.auth.login.DynamicLoginConfig.startService(DynamicLoginConfig.java:219)
           at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:289)
           at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:245)
           at jrockit.reflect.VirtualNativeMethodInvoker.invoke(Ljava.lang.Object;[Ljava.lang.Object;)Ljava.lang.Object;(Unknown Source)
           at java.lang.reflect.Method.invoke(Ljava.lang.Object;[Ljava.lang.Object;I)Ljava.lang.Object;(Unknown Source)
           at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157)
           at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96)
           at org.jboss.mx.server.Invocation.invoke(Invocation.java:88)
           at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
           at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668)
           at org.jboss.system.microcontainer.ServiceProxy.invoke(ServiceProxy.java:167)
           at $Proxy0.start()V(Unknown Source)
           at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:42)
           at org.jboss.system.microcontainer.ServiceControllerContextAction.install(ServiceControllerContextAction.java:46)
           at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51)
           at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:226)
           at org.jboss.system.microcontainer.ServiceControllerContext.install(ServiceControllerContext.java:198)
           at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:709)
           at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:429)
           at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:538)
           at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:472)
           at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:320)
           at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:190)
           at org.jboss.system.ServiceController.doChange(ServiceController.java:632)
           at org.jboss.system.ServiceController.start(ServiceController.java:407)

          The test fails at this point because it was expecting an exception to be thrown from the start attempt.

          • 2. Re: Behavior with AbstractKernelController
            Anil Saldanha Master

            Additionally, the ServiceController, once reaches the "Error" state is shut off for a stop or undeploy or redeploy attempts, for the service in question.

            • 3. Re: Behavior with AbstractKernelController
              Scott Stark Master

              Right. I'll go through the jmx tests in the MC_VDF_WORK branch and create one that represents what needs to happen for this usage to be able to talk about what needs to be changed.

              • 4. Re: Behavior with AbstractKernelController
                Anil Saldanha Master

                Adran says:

                The behaviour is not "inconsistent".
                In fact, it is more consistent now.
                In the past, invoking "start" never actually guaranteed the service started. It would only actually do the
                start() if all the dependencies were satisfied.
                Later you might actually get the start when the correct dependency is added.
                In fact, the code you show didn't even work properly until less than 2 years ago when I made it redirect through the service controller (under the hood in ServiceMBeanSupport).
                Now with the introduction of the MC,
                everything is done consistently.
                Your code should be (and always should have been if you want things to work properly)
                followed by
                to check what state it is actually in,
                i.e. dependencies satisfied, the error/problem, etc.
                See the deployment tests, that I wrote when I was fixing all this a while ago, if you want to see the correct pattern in more detail.

                • 5. Re: Behavior with AbstractKernelController
                  Scott Stark Master

                  Ok, but the issue is what usage constructs that work today should continue to work? All of the usages that are now failing need to be documented in terms of tests and either resolved as invalid or support added to the JMX/MC integration layer.

                  • 6. Re: Behavior with AbstractKernelController
                    Anil Saldanha Master

                    I have updated the testcase to use the ServiceController to create/start/stop/destroy a service (and look into its ServiceContext to give me the state of the service at any time).

                    The test in question is:

                    ant -Dtest=org.jboss.test.security.test.DynamicLoginConfigServiceUnitTestCase one-test

                    Currently I see three issues:
                    a) I am unable to set an attribute on a service that has been created but failed to start (in FAILED state).
                    b) I cannot destroy a service that is in FAILED state but has been created.
                    b) Against a running JBoss instance, if you run the same test a second time, you will see issues because the previous run did not destroy the service.

                    • 7. Re: Behavior with AbstractKernelController
                      Scott Stark Master

                      The lack of an exception from the start attempt is a red-herring as this is not working anyway. The lack of an exception is masked by the catch(Throwable t) which is catching the junit fail call. If this is changed to:

                       server.invoke(serviceOName,"create", new Object[0], new String[0]);
                       server.invoke(serviceOName,"start", new Object[0], new String[0]);
                       fail("Service should not have started");
                       catch(Exception t)
                       log.debug("Service has rightly disagreed to start",t);

                      the test fails. The state of the service needs to be queried to ensure that is started rather than relying on getting an exception back.

                      • 8. Re: Behavior with AbstractKernelController
                        Anil Saldanha Master

                        Scott, my last post was after I had totally revamped the testcase to use the ServiceControllerMBean to do the deployment and query for the state of the service.

                        • 9. Re: Behavior with AbstractKernelController
                          Scott Stark Master

                          I was talking about the 4.0 branch version.

                          • 10. Re: Behavior with AbstractKernelController
                            Anil Saldanha Master

                            I synched up the 4.0 testcase also to use the ServiceController. Now the tests pass and I can run the test multiple times and it passes fine.

                            While the testcase in HEAD clearly shows that once the service has "failed" to start, I cannot "set an attribute" and I cannot "destroy" the service.

                            • 11. Re: Behavior with AbstractKernelController
                              Scott Stark Master

                              The test runs multiple times now in head, but fails at each point because of:

                              junit.framework.ComparisonFailure: state is Destroyed expected:<DESTROY...> but was:<FAIL...>
                               at junit.framework.Assert.assertEquals(Assert.java:81)
                               at org.jboss.test.security.test.DynamicLoginConfigServiceUnitTestCase.testAuthConf(DynamicLoginConfigServiceUnitTestCase.java:165)

                              There is a change in the ServiceController to ignore requests to destroy a service that is in a FAILED state. Previouly only requests for services in ServiceContext.DESTROYED or ServiceContext.NOTYETINSTALLED were ignored.

                              2006-08-25 12:01:26,641 DEBUG [org.jboss.system.ServiceController] destroying se
                              rvice: jboss:service=TestDynamicLoginConfig
                              2006-08-25 12:01:26,641 DEBUG [org.jboss.system.ServiceController] Ignoring dest
                              roy request for service: jboss:service=TestDynamicLoginConfig at state FAILED

                              If we want backward compatibility we need to define the service state machine diagram with all transitions and require the same under the mc. I'm doubtful that this would be useful as we really should not allow a service to go from an error state liked FAILED to DESTROYED. At this point the service state diagram needs to be defined along with the expected semantics and code updated to conform to it in my view.

                              • 12. Re: Behavior with AbstractKernelController
                                Anil Saldanha Master

                                What about deregistering the service from the MBeanServer if it has reached FAILED state?

                                In my testcase, the destroy is done to cleanup. I can change it to explicity deregister an mbean, because in my preparexxxx method, I do a register on a mbean with the server.

                                • 13. Re: Behavior with AbstractKernelController
                                  Anil Saldanha Master

                                  Thanks Scott for the testcase cleanup.