-
15. Re: JNDI binding/unbinding error in EAP 6.1.0.Alpha1
emmartins Apr 12, 2013 11:11 AM (in response to jaikiran)For subsystem related bindings which have no deployments involved, JNDI API is not used, example:
{code:java}
@Override
protected void performRuntime(OperationContext context, ModelNode operation, ModelNode model, ServiceVerificationHandler verificationHandler, List<ServiceController<?>> newControllers) throws OperationFailedException {
// creates binder service
final String bindValue = new Object();
final ContextNames.BindInfo bindInfo = ContextNames.bindInfoFor("java:jboss/BPELEngine");
final BinderService binderService = new BinderService(bindInfo.getBindName());
binderService.getManagedObjectInjector().inject(new ValueManagedReferenceFactory(new ImmediateValue<Object>(bindValue)));
// creates the service builder with dep to the parent jndi context
ServiceBuilder<ManagedReferenceFactory> builder = context.getServiceTarget().addService(bindInfo.getBinderServiceName(), binderService)
.addDependency(bindInfo.getParentContextServiceName(), ServiceBasedNamingStore.class, binderService.getNamingStoreInjector());
// installs the service
newControllers.add(builder.install());
}
{code}
-
16. Re: JNDI binding/unbinding error in EAP 6.1.0.Alpha1
jeff.yuchang Apr 14, 2013 6:02 AM (in response to emmartins)I am thinking that can we keep both ways. Like you still can register with the ServiceTarget, but you'll need to remember to unbind it properly.
The reason that I am asking this is: In my particular case, the BPEL component is part of the SwitchYard subsystem, so the BPEL component itself don't really extend the AbstractAddStepHandler, where you can override the performRuntime method to register your object in JNDI.
-
17. Re: JNDI binding/unbinding error in EAP 6.1.0.Alpha1
jeff.yuchang Apr 14, 2013 6:13 AM (in response to jeff.yuchang)Hi,
In SwitchYard, when the BPEL component is started, it will add a service in the ServiceTarget as following:
{code:java}
final SwitchYardComponentService componentService = new SwitchYardComponentService(moduleId, model);
final ServiceBuilder<Component> componentServiceBuilder = context.getServiceTarget().addService(SwitchYardComponentService.SERVICE_NAME.append(moduleId), componentService);
componentServiceBuilder.addDependency(SwitchYardInjectorService.SERVICE_NAME, Map.class, componentService.getInjectedValues())
.addDependency(RA_REPOSITORY_SERVICE_NAME, ResourceAdapterRepository.class, componentService.getResourceAdapterRepository());
componentServiceBuilder.addDependency(WebSubsystemServices.JBOSS_WEB);
componentServiceBuilder.setInitialMode(Mode.ACTIVE);
newControllers.add(componentServiceBuilder.install());
{code}
So in the JndiRegistry class, I am using the SwitchYardComponentService.SERVICE_NAME.append(moduleId) as the deployment unit service name, and I am now seeing the following error:
Caused by: java.lang.NullPointerException
at org.jboss.as.naming.WritableServiceBasedNamingStore.bind(WritableServiceBasedNamingStore.java:81) [jboss-as-naming-7.2.0.Alpha1-redhat-4.jar:7.2.0.Alpha1-redhat-4]
I checked the code, it is:
{code:java}
final Set<ServiceName> duBindingReferences = (Set<ServiceName>) getServiceRegistry().getService(JndiNamingDependencyProcessor.serviceName(deploymentUnitServiceName)).getValue();
{code}
Essentially, the getServiceRegistry().getService(JndiNamingDependencyProcessor.serviceName(deploymentUnitServiceName)) returns 'null' as I debugged.
I guess I must mis-understood something or missed something here.
Thanks
Jeff
-
18. Re: JNDI binding/unbinding error in EAP 6.1.0.Alpha1
emmartins Apr 14, 2013 9:01 PM (in response to jeff.yuchang)That means Jaikiran suspicions were correct, there is no deployment involved, when that happens there is no JndiNamingDependencyProcessor available, so there is no solution using JNDI API, you must go for the non JNDI API solution in my post above, slighty changed to something like this:
public void bind(String name, Object value) throws NamingException { try { ServiceContainer serviceContainer = CurrentServiceContainer.getServiceContainer(); // creates binder service final ContextNames.BindInfo bindInfo = ContextNames.bindInfoFor(name); final BinderService binderService = new BinderService(bindInfo.getBindName()); binderService.getManagedObjectInjector().inject(new ValueManagedReferenceFactory(new ImmediateValue<Object>(value))); // creates the service builder with dep to the parent jndi context ServiceController<?> serviceController = serviceContainer.addService(bindInfo.getBinderServiceName(), binderService) .addDependency(bindInfo.getParentContextServiceName(), ServiceBasedNamingStore.class, binderService.getNamingStoreInjector()) .setInitialMode(ServiceController.Mode.ACTIVE) .install(); // wait for the service start final StabilityMonitor monitor = new StabilityMonitor(); monitor.addController(serviceController); try { monitor.awaitStability(); } finally { monitor.removeController(serviceController); } final Exception startException = serviceController.getStartException(); if (startException != null) { throw startException; } } catch (NamingException e) { throw e; } catch (Throwable e) { final NamingException ne = new NamingException("Failed to bind "+ value + " at location " + name); ne.setRootCause(e); throw ne; } } public void unbind(String name) throws NamingException { try { ServiceContainer serviceContainer = CurrentServiceContainer.getServiceContainer(); final ContextNames.BindInfo bindInfo = ContextNames.bindInfoFor(name); final ServiceController<?> serviceController = serviceContainer.getService(bindInfo.getBinderServiceName()); if (serviceController == null) { throw new NameNotFoundException(name); } serviceController.setMode(ServiceController.Mode.REMOVE); final StabilityMonitor monitor = new StabilityMonitor(); monitor.addController(serviceController); try { monitor.awaitStability(); } finally { monitor.removeController(serviceController); } } catch (NamingException e) { throw e; } catch (Throwable e) { final NamingException ne = new NamingException("Failed to unbind " + name); ne.setRootCause(e); throw ne; } }
Note that I did not test this code, I simply adapted WritableServiceBasedNamingStore's bind and unbind logic to your case. Also it would be better for you to use the Shipward's service target instead of the current service container. Please let me know if anything fails.
Now, looking at this particular use case, and the solution, I agree a simple API that do not requires working out with MSC is needed for subsystem/modules. Some options:
1) Allow the deployment service name to not be set through WritableServiceBasedNamingStore.pushOwner(), i.e. WritableServiceBasedNamingStorethis's bind() and unbind() would understand that if owner not set the op is related to a non managed bind. Like I said earlier, this could open the door for bugs based on developer forgetting to use pushOwner() when they should. A good thing of this solution is that code depends only on JNDI, and no particular properties need to be set, which means code could be easily ported to another container. No chance of defining a specific service target.
2) Provide an alternative JNDI context impl, available by passing config properties on new InitialContext(properties). No doors open for misusage, dependency only on JNDI api, but probably not portable code. No chance of defining a specific service target.
3) Provide a specific API that restores the missed functionality, something like WritableServiceBasedNamingStore.unmanagedBind(String name, Object value, ServiceTarget serviceTarget) and WritableServiceBasedNamingStore.unmanagedUnbind(String name, ServiceTarget serviceTarget). A solution that clearly defines the functionality with hard chance of misusage, which allows a specific service target to be used, but there is dependency on AS Naming.
From the AS Naming dev point of view I'm more into 3) anyway... Thoughts?
-
19. Re: JNDI binding/unbinding error in EAP 6.1.0.Alpha1
jeff.yuchang Apr 14, 2013 11:09 PM (in response to emmartins)I like the option 3 as well.
Regards
Jeff
-
20. Re: JNDI binding/unbinding error in EAP 6.1.0.Alpha1
jeff.yuchang Apr 14, 2013 11:18 PM (in response to emmartins)Hi Eduardo,
There is no StabilityMonitor class in the jboss-msc 1.0.4.GA version, which is going with the jboss-as-7.2.0-redhat-4. Do you know what the equivalent API for this is?
Thanks
Jeff
-
21. Re: JNDI binding/unbinding error in EAP 6.1.0.Alpha1
jeff.yuchang Apr 17, 2013 12:36 AM (in response to jeff.yuchang)With the Eduardo's guidance, I managed to get it working now, the complete source code can be found at: https://github.com/riftsaw/riftsaw/blob/master/engine/src/main/java/org/riftsaw/engine/jboss/JndiRegistry.java
Thanks
Jeff