Accessing Enterprise JavaBeans in OSGi applications
There are alternative mechanisms we can use in a client bundle to access an enterprise bean in a service bundle. To maximize application availability during an update to a service bundle containing one or more enterprise beans, use OSGi service references to access the enterprise beans.
From an OSGi client bundle, we can access an enterprise bean in a service bundle in any of the following ways:
- Define a <reference> element, in the Blueprint XML file of the client bundle, that refers to the enterprise bean.
- Use an @EJB annotation.
- Define an EJB reference that is mapped to the JNDI name of the bean.
- Use an "osgi:service/" JNDI lookup.
The alternative ways of accessing an enterprise bean, and the corresponding differences in application behaviour during an update to the service bundle, are discussed in more detail in the remaining sections of this topic.
Use a <reference> element to access an enterprise bean
We can access an enterprise bean by defining a reference element for the bean in the Blueprint XML file of the client bundle; for more information, see References and the Blueprint Container.
The enterprise bean must be in the list specified by the Export-EJB header in the bundle manifest file of the service bundle, or the value of the Export-EJB header must be set to a single space character so that all enterprise beans in the bundle are exported; for more information, see the description of the Export-EJB header in the bundle manifest file.
To access the enterprise bean from a blueprint-managed bean, we can inject the enterprise bean through a property on the blueprint-managed bean; for details, see References and the Blueprint Container.
To access the enterprise bean from a component that is not blueprint-managed, such as a servlet, use a "blueprint:comp/" JNDI lookup; for details, see JNDI lookup for blueprint components.
If we subsequently update the service bundle, the client bundle does not have to be restarted. During the update operation, an end user might experience a brief delay, because the service reference is damped, so the client bundle waits for the update operation to complete, rather than a runtime exception being thrown.
Use an @EJB annotation or an EJB reference to access an enterprise bean
Create a reference to an enterprise bean in either of the following ways:
- Use an @EJB annotation in the source code of the client bundle.
- Define an EJB reference in an ejb-jar.xml or web.xml file and use a JNDI lookup in the source code.
In either case, you map the reference to the enterprise bean JNDI name in an ibm-ejb-jar-bnd.xml or ibm-web-bnd.xml file in the bundle, or in the WebSphere Application Server administrative console when we deploy the bundle.
WAS automatically generates an enterprise bean JNDI name and maps the enterprise bean to it. In addition, we can explicitly map the enterprise bean to a JNDI name in the ibm-ejb-jar-bnd.xml file in the service bundle, or in the WAS administrative console when we deploy the bundle.
If we explicitly map the enterprise bean, and we subsequently update the service bundle, the client does not have to be restarted, but the service bundle is briefly unavailable, during which time a runtime exception is thrown if the client bundle attempts to call a method on the enterprise bean.
If we do not explicitly map the enterprise bean, and we subsequently update the service bundle, the JNDI name changes. The EJB reference to the JNDI name in the client bundle is updated automatically and the client bundle is restarted, during which time the client bundle is unavailable. In addition, the service bundle is briefly unavailable during the update operation, and if the client bundle becomes available before the service bundle and attempts to call a method on the enterprise bean, a runtime exception is thrown.
Use an "osgi:service/" lookup to access an enterprise bean
We can access an enterprise bean using, in the source code of the client bundle, an "osgi:service/" lookup, in either of the following ways:
- Use a JNDI lookup with a URL of the following form:
osgi:service/interface_name/optional_filterFor example:try { InitialContext ic = new InitialContext(); return (BloggingService) ic.lookup("osgi:service/com.ibm.samples.websphere.osgi.blog.api.BloggingService"); } catch (NamingException e) { . . .- Inject a reference to the enterprise bean using an @Resource annotation of the following form:
@Resource(lookup="osgi:service/interface_name/optional_filter")For example:@Resource(lookup="osgi:service/com.ibm.samples.websphere.osgi.blog.api.BloggingService") BloggingService bloggingService;
If we subsequently update the service bundle, the client bundle continues to run without interruption, but a ServiceUnavailableException is thrown if the code attempts to use the service object while the service bundle is being updated, so the source code must be written to handle this situation.
For details of the OSGi URL scheme, see section 126.6 of the OSGi Service Platform Release 4 Version 4.2 Enterprise Specification.
Summary
The following table summarizes the degree of availability during an update to an OSGi application containing enterprise beans, depending on the enterprise bean access mechanism used:
Access mechanism Summary of application availability OSGi service reference The client bundle remains available. The service reference is damped, so client threads block until the EJB service becomes available again. @EJB annotation or EJB reference, with explicit JNDI name mapping The client bundle remains available. If the client bundle attempts to use the injected EJB, a runtime exception is thrown during the service bundle update. "osgi:service/" JNDI lookup or injected reference The client bundle remains available. If the client bundle attempts use the injected EJB, a runtime exception is thrown during the service bundle update. This behavior is similar to using an @EJB annotation or EJB reference with explicit JNDI name mapping, but more client code is required to achieve the same result. @EJB annotation or EJB reference, without explicit JNDI name mapping The client bundle is restarted. If the client bundle becomes available before the service bundle, attempts use the injected EJB will result in runtime exceptions being thrown until the service bundle update is complete.
Related:
Enterprise JavaBeans and OSGi Applications Update bundle versions in a deployed OSGi application EJB JNDI names [Settings] EJB references [Settings]
File name: was1519.html
prettyPrint();