I have the following situation, in a client ear application there is CDI @ApplicationScoped
bean which performs a remote SLSB lookup on @PostConstruct
callback and caches the obtained proxy:
@ApplicationScoped
@Typed({ ServiceInterface.class })
public class RemoteServiceProxy implements ServiceInterface
{
/**
* Remote service.
*/
private RemoteService remoteService;
/**
* Default constructor.
*/
public RemoteServiceProxy()
{
super();
}
/**
* PostConstruct callback.
*
* @throws RuntimeException
* Error while looking up remote proxy
*/
@PostConstruct
protected void onPostConstruct()
{
try
{
remoteService = serviceLocator.lookup(ActivityRemoteEntityService.class);
Properties jndiProps = new Properties();
jndiProps.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
jndiProps.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
jndiProps.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProps.put("jboss.naming.client.ejb.context", "true");
Context context = new InitialContext(jndiProps);
remoteService = (RemoteService) context.lookup(
"application.backend/application.backend-service//RemoteServiceImpl!com.application.remote.RemoteService");
} catch (NamingException e)
{
throw new RuntimeException(e);
}
}
...
}
I would like to know if the cached proxy in the field remoteService
is thread-safe, so the RemoteServiceProxy
can be annotated with @ApplicationScoped
, or I have to perform a new proxy lookup for each invocation? Or is a best to use @Stateless
?
Thanks in advance
The EJB 3.2 Specification has the following to say:
3.4.9 Concurrent Access to Session Bean References
It is permissible to acquire a session bean reference and attempt to invoke the same reference object concurrently from multiple threads. However, the resulting client behavior on each thread depends on the concurrency semantics of the target bean. See Section 4.3.13 and Section 4.8.5 for details of the concurrency behavior for session beans.
§4.3.13 basically says that concurrent calls to session beans will be serialised by the container.
§4.8.5 describes the semantics around concurrent access to Singleton Session beans.
Therefore, to be compliant a remote proxy would need to be inherently thread safe as it must follow the semantics required for a "session bean reference".
That said, if you store such a reference in a @Singleton
EJB, then this reference will only ever be able to concurrently handle a single method call at a time (because such calls are "serialized"). This will likely result in an undesirable bottleneck in your application.