Seam en aplicaciones Standalone

Jboss Seam es un magnífico framework para el desarrollo de aplicaciones Web, pero plantea algunos problemas, cuando deseamos reutilizar nuestro código Seam  desde una aplicación que no se esta ejecutando dentro de un servidor de aplicaciones o desde un Thread independiente. Esto es debido a que sin la envoltura del servidor de aplicaciones, ninguno de los contextos Seam estarán disponibles.

El error típico con el que nos vamos a encontrar es:


java.lang.IllegalStateException: No application context active
at org.jboss.seam.Component.forName(Component.java:1807)

Código para inicializar Seam antes de utilizarlo:


     /**
     * Inicializa el contexto Seam.
     * Necesario para ejecutar código cuando el contexto Seam no esta inicializado y necesitamos acceder a elementos del contexto.
     * Con esto evitamos la excepción "No application context active"
     * @author Félix García Borrego
     */
    public static void initContextApplication(){
        if(!Contexts.isApplicationContextActive()){
        // Si el contexto no esta inicializado lo creamos
       if(!Lifecycle.isApplicationInitialized()){
            // La aplicación no esta activa, la activamos
            MockServletContext servletcontextMock = new MockServletContext();
            ServletLifecycle.beginApplication(servletcontextMock);
            new Initialization(servletcontextMock).create().init();
     }
     // Inicializamos el contexto
     ServletLifecycle.beginInitialization();
 }

Comentarios

  1. Gracias!!

    Probado desde Coldfusion 8 como war en una aplicacion en donde los componentes seam estan en un jar (modulo EJB) y funciona bien

  2. Bien eso soluciona lo del application context… pero como se soluciona luego lo del:

    java.lang.IllegalStateException: No session context active

    me ocurre cuando trato de efectuar un request.getContextPath();

  3. Cierto, esta solución es útil si tienes todos tus beans en contexto de Aplicación, si quieres acceder a sesión es un poco mas complejo, quizás esto código te pueda servir de orientación:
    /**
    * Si la request del usuario no esta asociada a Seam la inicializa
    * Para que estén disponibles todos los elementos seam.
    * Nota: Si el Application Context no esta inicializado, también lo crea.
    * @param request
    */
    public static void beginRequest(HttpServletRequest request){
    ServletLifecycle.beginRequest(request);
    ServletContexts.instance().setRequest(request);
    ConversationPropagation.instance().restoreConversationId( request.getParameterMap() );
    Manager.instance().restoreConversation();
    ServletLifecycle.resumeConversation(request);
    Manager.instance().handleConversationPropagation( request.getParameterMap() );
    }

  4. Estoy buscando la forma de acceder al EntityManager desde una aplicación Standalone, y vi que sugeriste el código para acceder al contexto de una sesión, pero esta incompleto, ¿ Podrías darme un ejemplo completo?

    Gracias.

  5. Necesito integrar una aplicacion standalone a otra hecha con Seam. Veo que hay una orientacion para acceder a un contexto de sesion pero necesito saber si se puede utilizar el EntityManager de seam desde la aplicacion standalone.

  6. Hola Gustavo,
    Aunque hay que montar algunos “artificios” es perfectamente posible usar/integrar una aplicación Seam dentro de una aplicación standalone.

    Te pongo un caso típico.
    -El main inicializa el contexto Seam (esto hace que todos los componentes declarados con anotaciones o en el components.xml estén disponibles).
    -En la clase en la que quieras utilizar en el EntityManager colocas el @In
    -Creas una instancia de la clase mediante Seam (por ejemplo Component.getInstance(clase) en lugar de con “new”.

  7. Felix, gracias por la respuesta. Lo que te pido es si me podías pasar como montar los “artificios” y como el main inicializa el contexto Seam. Tengo que resolver este problema y no encuentro mucha información.

    Gracias nuevamente.
    Saludos.

Comments are closed.