SeamFramework.orgCommunity Documentation

Appendice A. Integrating Web Beans into other environments

Currently Web Beans 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.

The Web Beans SPI is located in the webbeans-spi module, and packaged as webbeans-spi.jar. Some SPIs are optional, if you need to override the default behavior, others are required.

All interfaces in the SPI support the decorator pattern and provide a Forwarding class located in the helpers sub package. Additional, commonly used, utility classes, and standard implementations are also located in the helpers sub package.

Web Beans 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 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();

Il EjbDescriptor è abbastanza auto-esplicatorio e dovrebbe restituire i metadati rilevanti definiti nella specifica EJB. In aggiunta a queste due interfacce, vi è BusinessInterfaceDescriptor a rappresentare un'interfaccia locale di business (che incapsula la classe d'interfaccia ed il nome jndi usato per la ricerca di una istanza EJB).

The resolution of @EJB (for injection into simple beans), the resolution of local EJBs (for backing session beans) and remote EJBs (for injection as a Java EE resource) is delegated to the container. You must provide an implementation of org.jboss.webbeans.ejb.spi.EjbServices which provides these operations. For resolving the @EJB injection point, Web Beans will provide the InjectionPoint; for resolving local EJBs, the EjbDescriptor will be provided, and for remote EJBs the jndiName, mappedName, or ejbLink will be provided.

When resolving local EJBs (used to back session beans) a wrapper (SessionObjectReference) around the EJB reference is returned. This wrapper allows Web Beans to request a reference that implements the given business interface, and, in the case of SFSBs, request the removal of the EJB from the container.

Web Beans must delegate JTA activities to the container. The SPI provides a couple hooks to easily achieve this with the TransactionServices interface.

public interface TransactionServices

{
   /**
    * Possible status conditions for a transaction. This can be used by SPI
    * providers to keep track for which status an observer is used.
    */
   public static enum Status
   {
      ALL, SUCCESS, FAILURE
   }
   /**
    * Registers a synchronization object with the currently executing
    * transaction.
    * 
    * @see javax.transaction.Synchronization
    * @param synchronizedObserver
    */
   public void registerSynchronization(Synchronization synchronizedObserver);
   /**
    * Queries the status of the current execution to see if a transaction is
    * currently active.
    * 
    * @return true if a transaction is active
    */
   public boolean isTransactionActive();
}

La enumeration Status serve agli implementatori per poter essere in grado di tracciare se una sincronizzazione deve notificare un osservatore solo quando la transazione ha avuto successo, o dopo un errore, o indipendentemente dallo stato della transazione.

Qualsiasi implementazione di javax.transaction.Synchronization può essere passata al metodo registerSynchronization() e l'implementazione SPI deve immediatamente registrare la sincronizzazione con il gestore della transazione JTA usato per EJB.

Per facilitare la determinazione se o no una transazione è attualmente attiva per il thread di richiesta, può essere usato il metodo isTransactionActive(). L'implementazione SPI deve interrogare lo stesso gestore della transazione JTA usato per EJB.

L'interfaccia org.jboss.webbeans.bootstrap.api.Bootstrap definisce il bootstrap per Web Beans. Per avviare Web Beans occorre ottenere un'istanza di org.jboss.webbeans.bootstrap.WebBeansBootstrap (che implementa Boostrap), e comunicare le SPI in uso, e poi chiedere che il container venga avviato.

Il bootstrap è suddiviso in più fasi, inizializzazione del bootstrap, bootstrap e shutdown. L'inizializzazione creerà un manager, e aggiungerà i contesti standard (definiti dalla specifica). Bootstrap scoprirà EJB, classi e XML; aggiungerà i bean definiti con le annotazioni; aggiungerà i bean definiti con XML; e validerà tutti i bean.

The bootstrap supports multiple environments. An environment is defined by an implementation of the Environment interface. A number of standard envrionments are built in as the enumeration Environments. Different environments require different services to be present (for example servlet doesn't require transaction, EJB or JPA services). By default an EE environment is assumed, but you can adjust the environment by calling bootstrap.setEnvironment().

Web Beans uses a generic-typed service registry to allow services to be registered. All services implement the Service interface. The service registry allows services to be added and retrieved.

Per inizializzare il bootstrap si chiama Bootstrap.initialize(). Prima della chiamata di initialize() occorre registrare i servizi richiesti dal proprio ambiente. Si può fare questo chiamando bootstrap.getServices().add(JpaServices.class, new MyJpaServices()). Occorre anche fornire l'application context bean store.

Dopo aver chiamato initialize(), il Manager può essere ottenuto chiamando Bootstrap.getManager().

Per avviare il container chiamare Bootstrap.boot().

To shutdown the container you call Bootstrap.shutdown() or webBeansManager.shutdown(). This allows the container to perform any cleanup operations needed.

Per il corretto funzionamento al di fuori dell'implementazione delle API, ci sono un numero di requisiti che Web Beans RI pone nel container.

Isolamento del classloader

Se si integra Web Beans in un ambiente che supporta il deploy di applicazioni, occorre abilitare, automaticamente o attraverso la configurazione utente, l'isolamento del classloader per ogni applicazione Web Beans.

Servlet

Se si integra Web Beans in un ambiente Servlet occorre registrare org.jboss.webbeans.servlet.WebBeansListener come Servlet listener, o automaticamente, o attraverso una configurazione utente, per ciascuna applicazione Web Beans che usa Servlet.

JSF

If you are integrating the Web Beans into a JSF environment you must register org.jboss.webbeans.jsf.WebBeansPhaseListener as a phase listener, and org.jboss.webbeans.el.WebBeansELREsolver as an EL resolver, either automatically, or through user configuration, for each Web Beans application which uses JSF.

Se si integra Web Beans in un ambiente Servlet occorre registrare org.jboss.webbeans.servlet.ConversationPropagationFilter come Servlet listener, o automaticamente, o attraverso una configurazione utente, per ciascuna applicazione Web Beans che usa JSF. Questo filtro può venir registrato in modo sicuro per tutti i deploy dei servlet.

Session Bean Interceptor

Se si integra Web Beans in un ambiente EJB occorre registrare org.jboss.webbeans.ejb.SessionBeanInterceptor come interceptor EJB per ogni EJB dell'applicazione, o automaticamente o attraverso una configurazione utente, per ciascuna applicazione Web Beans che utilizza bean enterprise.

webbeans-core.jar

Se si integra Web Beans in un ambiente che supporta il deploy di applicazioni, occorre inserire webbeans-core.jar nel classloader isolato delle applicazioni. Non può essere caricato da un classloader condiviso.

Binding the manager in JNDI

You should bind a Reference to the Manager ObjectFactory into JNDI at java:app/Manager. The type should be javax.inject.manager.Manager and the factory class is org.jboss.webbeans.resources.ManagerObjectFactory