[Design of EJB 3.0] - Behavior difference in intra-AS EJB calls
by bstansberry@jboss.com
An FYI; not necessarily a problem.
I'm seeing a difference in behavior when a bean in one AS looks up a bean in another AS and then invokes on it.[1] Previously that call would go remote; now it stays local if the same bean is deployed locally.
This is because of the change in how proxy factories are created. Previously they were built on the server and downloaded. Now they are built on the client. Effect is IsLocalProxyFactoryInterceptor.isLocal() will *always* return true.
I don't know if this is an acceptable behavior change or not. I do think it should be overridable; for EJB2 beans I often see forum requests wanting to know how to override "local-preference". For EJB2 this can be overridden by writing a simple custom extension of a JBoss class, which can then be configured in on a per-bean basis. For EJB3 the equivalent override would be a bit more complex (customized IsLocalProxyFactoryInterceptor and extension of all the ObjectFactory impls to override createProxyFactoryProxy). But if that's done I don't see any way to configure the new classes on a per-bean basis. The JndiSessionRegistrarBase impls to use are hard coded.
[1] e.g.
| public VMID getVMIDFromRemoteLookup(String jndiURL, String name)
| throws NamingException
| {
| log.info("Looking up " + jndiURL + "/" + name);
| Properties env = new Properties();
| env.setProperty(Context.PROVIDER_URL, jndiURL);
| env.setProperty("jnp.disableDiscovery", "true");
| InitialContext ctx = new InitialContext(env);
| VMTester tester = (VMTester) ctx.lookup(name);
| return tester.getVMID();
| }
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4172041#4172041
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4172041
17 years, 7 months
[Design of EJB 3.0] - Cleanup problem with Ejb3Registrar and proxy factories
by bstansberry@jboss.com
This post is specifically about code in the proxy module, but I think it might point to a general issue with Ejb3McRegistrar. Cutting to the chase, it looks like Ejb3McRegistrar leaves no way to back out a failed bind() call.
I had a test with a misnamed deployment descriptor, which led to a failure in proxy factory registration:
| 2008-08-21 18:50:39,196 ERROR [org.jboss.kernel.plugins.dependency.AbstractKernelController] (RMI TCP Connection(18)-192.168.1.146) Error installing to Start: name=ProxyFactory/ClusteredStatefulRemote state=Create
| java.lang.IllegalStateException: Partition Ejb3IsLocalTestPartition not found
| at org.jboss.ha.framework.server.HAPartitionLocator.getHAPartition(HAPartitionLocator.java:124)
| at org.jboss.ejb3.proxy.clustered.registry.ProxyClusteringRegistry.registerClusteredBean(ProxyClusteringRegistry.java:114)
| at org.jboss.ejb3.proxy.clustered.factory.session.stateful.StatefulSessionClusteredProxyFactory.start(StatefulSessionClusteredProxyFactory.java:111)
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| .....
| at org.jboss.kernel.plugins.dependency.AbstractKernelController.install(AbstractKernelController.java:106)
| at org.jboss.ejb3.common.registrar.plugin.mc.Ejb3McRegistrar.install(Ejb3McRegistrar.java:309)
| at org.jboss.ejb3.common.registrar.plugin.mc.Ejb3McRegistrar.bind(Ejb3McRegistrar.java:163)
| at org.jboss.ejb3.proxy.jndiregistrar.JndiSessionRegistrarBase.registerProxyFactory(JndiSessionRegistrarBase.java:906)
| .....
|
That's fine; it was a bad deployment. But the problem is the undeploy didn't properly clean up:
| 2008-08-21 18:50:39,264 DEBUG [org.jboss.ejb3.stateful.StatefulContainer] (RMI TCP Connection(18)-192.168.1.146) Failed to cleanup after start() failure
| org.jboss.ejb3.common.registrar.spi.NotBoundException: Requested value bound at name "ProxyFactory/ClusteredStatefulRemote" is not bound.
| at org.jboss.ejb3.common.registrar.plugin.mc.Ejb3McRegistrar.lookup(Ejb3McRegistrar.java:91)
| at org.jboss.ejb3.proxy.jndiregistrar.JndiSessionRegistrarBase.deregisterProxyFactory(JndiSessionRegistrarBase.java:934)
| at org.jboss.ejb3.proxy.jndiregistrar.JndiSessionRegistrarBase.unbindEjb(JndiSessionRegistrarBase.java:477)
| at org.jboss.ejb3.session.SessionSpecContainer.lockedStop(SessionSpecContainer.java:732)
| at org.jboss.ejb3.stateful.StatefulContainer.lockedStop(StatefulContainer.java:324)
| at org.jboss.ejb3.stateful.StatefulContainer.lockedStart(StatefulContainer.java:308)
| at org.jboss.ejb3.EJBContainer.start(EJBContainer.java:855)
The effect of this is the "ProxyFactory/ClusteredStatefulRemote" bean was left registered in the MC, but not in an installed state. When later tests would deploy the same jar, they would all fail with "java.lang.IllegalStateException: ProxyFactory/ClusteredStatelessRemote is already installed". AFAICT, the only way to clean this up is to reboot the server.
There's a couple levels of issues here:
1) JndiSessionRegistrarBase.deregisterProxyFactory is doing a Ejb3Registrar.lookup before doing an unbind. It does this so it can make some assertions. Problem is Ejb3McRegistrar implements lookup by calling KernelController.getInstalledContext(). That will return null in this case, because "ProxyFactory/ClusteredStatefulRemote" never made it to ControllerState.INSTALLED. As a result, lookup() throws an exception.
2) If Ejb3McRegistrar.lookup() somehow was changed to get past that problem and find the ControllerContext, I believe it would still fail, because it checks ControllerContext.getError() and throws an exception if it finds one.
3) Even if the JndiSessionRegistrarBase.deregisterProxyFactory's call to Ejb3Registrar.lookup() were eliminated and the method went directly to Ejb3Registrar.unbind(), it would still fail because the first thing Ejb3McRegistrar.unbind() does is call lookup(). :-)
Bottom line, it looks like Ejb3McRegistrar leaves no way to back out a failed bind() call.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4171931#4171931
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4171931
17 years, 7 months