EJBTHREE-1669 : @Service tutorial on JBoss-5.0 GA
jaikiran Jan 10, 2009 4:21 AMThe "service" tutorial fails against the JBossAS-5.0 GA server.
The @Service is almost on the lines of what we have in our testsuite, except for one difference. The one in the tutorial uses @Depends on a field/method to inject a application specific type object:
@Service(objectName = ServiceThree.OBJECT_NAME) @Management(ServiceThreeManagement.class) @Depends( {ServiceTwo.OBJECT_NAME, ServiceOne.OBJECT_NAME}) public class ServiceThree implements ServiceThreeManagement { /** * The ObjectName for {@link ServiceThree} */ public static final String OBJECT_NAME = "tutorial:service=ServiceThree"; // This one works - see the way this is handled in the Dependency*Injector @Depends(ServiceOne.OBJECT_NAME) public ObjectName serviceOneName; private ServiceTwoManagement service2; // Its this injection which causes problem @Depends(ServiceTwo.OBJECT_NAME) public void setServiceTwo(ServiceTwoManagement service2) { this.service2 = service2; } public String serviceOneHello() throws Exception { Object[] args = new Object[0]; String[] signature = new String[0]; System.out.println("ServiceThree - Calling ServiceOne.sayHello() via JMX server"); MBeanServer server = (MBeanServer) MBeanServerFactory.findMBeanServer(null).get(0); return (String) server.invoke(serviceOneName, "sayHello", args, signature); } public String serviceTwoHello() { System.out.println("ServiceThree - Calling ServiceTwo.sayHello() via MBean proxy"); return service2.sayHello(); }
And this is the logs that i see on the console:
14:31:39,435 INFO [JBossASKernel] Created KernelDeployment for: jboss-ejb3-tutorial-service.jar 14:31:39,435 INFO [JBossASKernel] installing bean: jboss.j2ee:jar=jboss-ejb3-tutorial-service.jar,name=ServiceOne,service=EJB3 14:31:39,435 INFO [JBossASKernel] with dependencies: 14:31:39,435 INFO [JBossASKernel] and demands: 14:31:39,435 INFO [JBossASKernel] jboss.ejb:service=EJBTimerService 14:31:39,435 INFO [JBossASKernel] and supplies: 14:31:39,435 INFO [JBossASKernel] Class:org.jboss.tutorial.service.bean.ServiceOneManagement 14:31:39,435 INFO [JBossASKernel] jndi:ServiceOne/remote 14:31:39,435 INFO [JBossASKernel] Class:org.jboss.tutorial.service.bean.ServiceOneLocal 14:31:39,435 INFO [JBossASKernel] jndi:ServiceOne/local-org.jboss.tutorial.service.bean.ServiceOneLocal 14:31:39,435 INFO [JBossASKernel] Class:org.jboss.tutorial.service.bean.ServiceOneRemote 14:31:39,435 INFO [JBossASKernel] jndi:ServiceOne/remote-org.jboss.tutorial.service.bean.ServiceOneRemote 14:31:39,435 INFO [JBossASKernel] jndi:ServiceOne/local 14:31:39,435 INFO [JBossASKernel] Added bean(jboss.j2ee:jar=jboss-ejb3-tutorial-service.jar,name=ServiceOne,service=EJB3) to KernelDeployment of: jboss-ejb3-tutorial-service.jar 14:31:39,436 INFO [JBossASKernel] installing bean: jboss.j2ee:jar=jboss-ejb3-tutorial-service.jar,name=ServiceThree,service=EJB3 14:31:39,436 INFO [JBossASKernel] with dependencies: 14:31:39,436 INFO [JBossASKernel] and demands: 14:31:39,436 INFO [JBossASKernel] tutorial:service=ServiceTwo 14:31:39,436 INFO [JBossASKernel] tutorial:service=ServiceOne 14:31:39,436 INFO [JBossASKernel] jboss.ejb:service=EJBTimerService 14:31:39,436 INFO [JBossASKernel] and supplies: 14:31:39,436 INFO [JBossASKernel] jndi:ServiceThree/remote 14:31:39,436 INFO [JBossASKernel] Class:org.jboss.tutorial.service.bean.ServiceThreeManagement 14:31:39,436 INFO [JBossASKernel] Added bean(jboss.j2ee:jar=jboss-ejb3-tutorial-service.jar,name=ServiceThree,service=EJB3) to KernelDeployment of: jboss-ejb3-tutorial-service.jar 14:31:39,437 INFO [JBossASKernel] installing bean: jboss.j2ee:jar=jboss-ejb3-tutorial-service.jar,name=ServiceTwo,service=EJB3 14:31:39,437 INFO [JBossASKernel] with dependencies: 14:31:39,437 INFO [JBossASKernel] and demands: 14:31:39,437 INFO [JBossASKernel] tutorial:service=ServiceOne 14:31:39,437 INFO [JBossASKernel] jboss.ejb:service=EJBTimerService 14:31:39,437 INFO [JBossASKernel] and supplies: 14:31:39,437 INFO [JBossASKernel] Class:org.jboss.tutorial.service.bean.ServiceTwoManagement 14:31:39,437 INFO [JBossASKernel] jndi:ServiceTwo/remote 14:31:39,437 INFO [JBossASKernel] Added bean(jboss.j2ee:jar=jboss-ejb3-tutorial-service.jar,name=ServiceTwo,service=EJB3) to KernelDeployment of: jboss-ejb3-tutorial-service.jar 14:31:39,486 INFO [EJBContainer] STARTED EJB: org.jboss.tutorial.service.bean.ServiceOne ejbName: ServiceOne 14:31:39,504 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI: ServiceOne/remote - EJB3.x Default Remote Business Interface ServiceOne/remote-org.jboss.tutorial.service.bean.ServiceOneRemote - EJB3.x Remote Business Interface ServiceOne/local - EJB3.x Default Local Business Interface ServiceOne/local-org.jboss.tutorial.service.bean.ServiceOneLocal - EJB3.x Local Business Interface 14:31:39,526 INFO [JBossASKernel] installing bean: tutorial:service=ServiceOne 14:31:39,526 INFO [JBossASKernel] with dependencies: 14:31:39,527 INFO [JBossASKernel] and demands: 14:31:39,527 INFO [JBossASKernel] jboss.ejb:service=EJBTimerService 14:31:39,527 INFO [JBossASKernel] and supplies: 14:31:39,527 INFO [JBossASKernel] Class:org.jboss.tutorial.service.bean.ServiceOneManagement 14:31:39,527 INFO [JBossASKernel] jndi:ServiceOne/remote 14:31:39,527 INFO [JBossASKernel] Class:org.jboss.tutorial.service.bean.ServiceOneLocal 14:31:39,527 INFO [JBossASKernel] jndi:ServiceOne/local-org.jboss.tutorial.service.bean.ServiceOneLocal 14:31:39,527 INFO [JBossASKernel] Class:org.jboss.tutorial.service.bean.ServiceOneRemote 14:31:39,527 INFO [JBossASKernel] jndi:ServiceOne/remote-org.jboss.tutorial.service.bean.ServiceOneRemote 14:31:39,527 INFO [JBossASKernel] jndi:ServiceOne/local 14:31:39,549 INFO [JBossASKernel] Installing bean(tutorial:service=ServiceOne) into kernel 14:31:39,578 INFO [STDOUT] ServiceOne - Creating 14:31:39,595 INFO [STDOUT] ServiceOne - Starting 14:31:39,667 INFO [EJBContainer] STARTED EJB: org.jboss.tutorial.service.bean.ServiceThree ejbName: ServiceThree 14:31:39,667 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI: 14:31:39,702 ERROR [ServiceContainer] Encountered an error in start of ServiceThree java.lang.RuntimeException: Error creating MBeanProxy: tutorial:service=ServiceTwo at org.jboss.mx.util.MBeanProxyExt.init(MBeanProxyExt.java:415) at org.jboss.mx.util.MBeanProxyExt.<init>(MBeanProxyExt.java:99) at org.jboss.mx.util.MBeanProxyExt.create(MBeanProxyExt.java:394) at org.jboss.mx.util.MBeanProxyExt.create(MBeanProxyExt.java:349) at org.jboss.injection.DependsMethodInjector.inject(DependsMethodInjector.java:67) at org.jboss.injection.DependsMethodInjector.inject(DependsMethodInjector.java:52) at org.jboss.ejb3.service.ServiceContainer.injectDependencies(ServiceContainer.java:594) at org.jboss.ejb3.service.ServiceContainer.lockedStart(ServiceContainer.java:296) at org.jboss.ejb3.EJBContainer.start(EJBContainer.java:879) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at org.jboss.reflect.plugins.introspection.ReflectionUtils.invoke(ReflectionUtils.java:59) at org.jboss.reflect.plugins.introspection.ReflectMethodInfoImpl.invoke(ReflectMethodInfoImpl.java:150) ..... at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:650) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:675) at java.lang.Thread.run(Thread.java:595) Caused by: javax.management.InstanceNotFoundException: tutorial:service=ServiceTwo is not registered. at org.jboss.mx.server.registry.BasicMBeanRegistry.get(BasicMBeanRegistry.java:529) at org.jboss.mx.server.MBeanServerImpl.getMBeanInfo(MBeanServerImpl.java:675) at org.jboss.mx.util.MBeanProxyExt.init(MBeanProxyExt.java:407) ... 61 more .... 14:31:39,797 INFO [EJBContainer] STARTED EJB: org.jboss.tutorial.service.bean.ServiceTwo ejbName: ServiceTwo 14:31:39,800 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI: 14:31:39,835 INFO [JBossASKernel] installing bean: tutorial:service=ServiceTwo 14:31:39,835 INFO [JBossASKernel] with dependencies: 14:31:39,835 INFO [JBossASKernel] and demands: 14:31:39,835 INFO [JBossASKernel] tutorial:service=ServiceOne 14:31:39,835 INFO [JBossASKernel] jboss.ejb:service=EJBTimerService 14:31:39,835 INFO [JBossASKernel] and supplies: 14:31:39,835 INFO [JBossASKernel] Class:org.jboss.tutorial.service.bean.ServiceTwoManagement 14:31:39,835 INFO [JBossASKernel] jndi:ServiceTwo/remote 14:31:39,840 INFO [JBossASKernel] Installing bean(tutorial:service=ServiceTwo) into kernel 14:31:39,847 INFO [STDOUT] ServiceTwo - Starting 14:31:39,875 WARN [HDScanner] Failed to process changes org.jboss.deployers.client.spi.IncompleteDeploymentException: Summary of incomplete deployments (SEE PREVIOUS ERRORS FOR DETAILS): *** CONTEXTS IN ERROR: Name -> Error
It's the DependsMethodInjector (and also the DependsFieldInjector) which has this code:
public void inject(Object instance) { Class clazz = method.getParameterTypes()[0]; Object value = null; if (clazz == ObjectName.class) { value = on; } else { // Fails here since the service with the specified ObjectName has not yet started MBeanServer server = MBeanServerLocator.locateJBoss(); value = MBeanProxyExt.create(clazz, on, server); } try { method.invoke(instance, value); }
As can be seen in the code, the inject method isn't aware that the service isn't yet registered.
Questions:
1) What does @Depends signify at a field/method level? I thought @Depends was more for specifying a dependency. But going by the code in the DependsMethodInjector/DependsFieldInjector, it seems to be doing injection.
2) Is this a valid use of @Depends? If yes, is there a way to make the injector(s) aware of the current state of the MBean, its trying to inject?
P.S: This tutorial is in a compiling state and i can commit it to our trunk (leaving it out from the parent pom to avoid my Hudson runs breaking), if you want to have a look at the complete example.