SeamFramework.orgCommunity Documentation
Currently the Web Beans RI only runs in JBoss AS 5; integrating the RI into other EE environments (for example another application server like Glassfish), into a servlet container (like Tomcat), or with an Embedded EJB3.1 implementation is fairly easy. In this Appendix we will briefly discuss the steps needed.
It should be possible to run Web Beans in an SE environment, but you'll to do more work, adding your own contexts and lifecycle. The Web Beans RI currently doesn't expose lifecycle extension points, so you would have to code directly against Web Beans RI classes.
The Web Beans SPI is located in webbeans-ri-spi
module, and packaged as webbeans-ri-spi.jar
. Some
SPIs are optional, if you need to override the default behavior,
others are required.
You can specify the implementation of an SPI either as a system
property, or in a properties file
META-INF/web-beans-ri.properties
. All property names
are the fully qualified class name of the implemented interface; all
property values are the fully qualified class name of the
implementation class.
All interfaces in the SPI support the decorator pattern and provide a
Forwarding
class.
public interface WebBeanDiscovery {
/**
* Gets list of all classes in classpath archives with web-beans.xml files
*
* @return An iterable over the classes
*/
public Iterable<Class<?>> discoverWebBeanClasses();
/**
* Gets a list of all web-beans.xml files in the app classpath
*
* @return An iterable over the web-beans.xml files
*/
public Iterable<URL> discoverWebBeansXml();
}
The discovery of Web Bean classes and web-bean.xml
files is self-explanatory (the algorithm is described in Section 11.1
of the JSR-299 specification, and isn't repeated here).
The Web Beans RI can be told to load your implementation of
WebBeanDiscovery
using the property
org.jboss.webbeans.bootstrap.spi.WebBeanDiscovery
with the
fully qualified class name as the value. For example:
org.jboss.webbeans.bootstrap.spi.WebBeanDiscovery=org.jboss.webbeans.integration.jbossas.WebBeanDiscoveryImpl
If the Web Beans RI is being used in a servlet container, it expects a constructor of the form:
public WebBeanDiscoveryImpl(ServletContext servletContext) {}
The servlet context can be used to allow your implementation of
WebBeanDiscovery
to interact with the container.
The Web Beans RI also delegates EJB3 bean discovery to the container
so that it doesn't have to scan for EJB3 annotations or parse
ejb-jar.xml
. For each EJB in the application an
EJBDescriptor should be discovered:
public interface EjbDiscovery
{
public static final String PROPERTY_NAME = EjbDiscovery.class.getName();
/**
* Gets a descriptor for each EJB in the application
*
* @return The bean class to descriptor map
*/
public Iterable<EjbDescriptor<?>> discoverEjbs();
}
public interface EjbDescriptor<T> {
/**
* Gets the EJB type
*
* @return The EJB Bean class
*/
public Class<T> getType();
/**
* Gets the local business interfaces of the EJB
*
* @return An iterator over the local business interfaces
*/
public Iterable<BusinessInterfaceDescriptor<?>> getLocalBusinessInterfaces();
/**
* Gets the remote business interfaces of the EJB
*
* @return An iterator over the remote business interfaces
*/
public Iterable<BusinessInterfaceDescriptor<?>> getRemoteBusinessInterfaces();
/**
* Get the remove methods of the EJB
*
* @return An iterator over the remove methods
*/
public Iterable<Method> getRemoveMethods();
/**
* Indicates if the bean is stateless
*
* @return True if stateless, false otherwise
*/
public boolean isStateless();
/**
* Indicates if the bean is a EJB 3.1 Singleton
*
* @return True if the bean is a singleton, false otherwise
*/
public boolean isSingleton();
/**
* Indicates if the EJB is stateful
*
* @return True if the bean is stateful, false otherwise
*/
public boolean isStateful();
/**
* Indicates if the EJB is and MDB
*
* @return True if the bean is an MDB, false otherwise
*/
public boolean isMessageDriven();
/**
* Gets the EJB name
*
* @return The name
*/
public String getEjbName();
}
The EjbDescriptor
is fairly self-explanatory,
and should return the relevant metadata as defined in the EJB
specification. In addition to these two interfaces, there is
BusinessInterfaceDescriptor
which represents a
local business interface (encapsulating the interface class and
jndi name used to look up an instance of the EJB).
The Web Beans RI can be told to load your implementation of
EjbDiscovery
using the property
org.jboss.webbeans.bootstrap.spi.EjbDiscovery
with the
fully qualified class name as the value. For example:
org.jboss.webbeans.bootstrap.spi.EjbDiscovery=org.jboss.webbeans.integration.jbossas.EjbDiscoveryImpl
If the Web Beans RI is being used in a servlet container, it expects a constructor of the form:
public EjbDiscoveryImpl(ServletContext servletContext) {}
The servlet context can be used to allow your implementation of
EjbDiscovery
to interact with the container.
The Web Beans RI implements JNDI binding and lookup according to
standards, however you may want to alter the binding and lookup (for
example in an environment where JNDI isn't available). To do this,
implement
org.jboss.webbeans.spi.resources.NamingContext
:
public interface NamingContext extends Serializable {
/**
* Typed JNDI lookup
*
* @param <T> The type
* @param name The JNDI name
* @param expectedType The expected type
* @return The object
*/
public <T> T lookup(String name, Class<? extends T> expectedType);
/**
* Binds an item to JNDI
*
* @param name The key to bind under
* @param value The item to bind
*/
public void bind(String name, Object value);
}
and tell the RI to use it:
org.jboss.webbeans.resources.spi.NamingContext=com.acme.MyNamingContext
If the Web Beans RI is being used in a servlet container, it expects a constructor of the form:
public MyNamingContext(ServletContext servletContext) {}
The servlet context can be used to allow your implementation of
NamingContext
to interact with the container.
The Web Beans RI needs to load classes and resources from the
classpath at various times. By default, they are loaded from the
same classloader that was used to load the RI, however this may not
be correct for some environments. If this is case, you can implement
org.jboss.webbeans.spi.ResourceLoader
:
public interface ResourceLoader {
/**
* Creates a class from a given FQCN
*
* @param name The name of the clsas
* @return The class
*/
public Class<?> classForName(String name);
/**
* Gets a resource as a URL by name
*
* @param name The name of the resource
* @return An URL to the resource
*/
public URL getResource(String name);
/**
* Gets resources as URLs by name
*
* @param name The name of the resource
* @return An iterable reference to the URLS
*/
public Iterable<URL> getResources(String name);
}
and tell the RI to use it:
org.jboss.webbeans.resources.spi.ResourceLoader=com.acme.ResourceLoader
If the Web Beans RI is being used in a servlet container, it expects a constructor of the form:
public MyResourceLoader(ServletContext servletContext) {}
The servlet context can be used to allow your implementation of
ResourceLoader
to interact with the container.
There are a number of requirements that the Web Beans RI places on the container for correct functioning that fall outside implementation of APIs
If you are integrating the Web Beans RI into an environment that supports deployment of multiple applications, you must enable, automatically, or through user configuation, classloader isolation for each Web Beans application.
If you are integrating the Web Beans into a Servlet
environment you must register
org.jboss.webbeans.servlet.WebBeansListener
as a Servlet listener, either automatically, or through user
configuration, for each Web Beans application which uses
Servlet.
If you are integrating the Web Beans into an EJB
environment you must register
org.jboss.webbeans.ejb.SessionBeanInterceptor
as a EJB interceptor for all EJBs in the application, either
automatically, or through user configuration, for each Web
Beans application which uses enterprise beans.
webbeans-ri.jar
If you are integrating the Web Beans into an environment that
supports deployment of applications, you must insert the
webbeans-ri.jar
into the applications
isolated classloader. It cannot be loaded from a shared
classloader.