JBoss Seam no Tomcat

July 28th, 2008 by rafaelliu Leave a reply »

Quem está começando a aprender JBoss Seam pode ter a impressão que ele roda apenas no JBoss AS, o que não é verdade. Devido à maioria da documentação ser provida pelo pessoal do JBoss é claro que tudo é feito tendo-se em mente o AS deles. Mesmo quem sabe ser possível rodar sobre outros ASs, muitas vezes não tem idéia de como fazê-lo.

O Seam em si não é um serviço no JBoss, mas sim um framework, o que possibilita sua utilização em vários ASs. Caso não seja usada nenhuma facilidade EE (ou mesmo algumas que o Seam cobre), é possível fazer o deploy de uma aplicação Seam até mesmo sobre um simples container web como o Tomcat e esse post sobre esse caso.

Sendo o Seam uma biblioteca, dificuldades em fazer deploy em containers se limitam a conflitos e dependências. Mas quem já usou Seam sabe da grande mão na roda que é o seam-gen para geração de scaffold (inclusa no JBoss Tools). O problema é que o scaffold gerado é feito para o JBoss.

Então nossos esforços serão basicamente mudar configurações do JBoss para o Tomcat e passar para o Seam o tratamento de features enterprise. As instruções são para o seguinte ambiente:

  • Eclipse 3.3.2 com JBoss Tools 2.1.1.GA
  • JBoss Seam 2.0.3.CR1
  • Apache Tomcat 6.0.16

Vamos lá:

  1. Já que estamos rodando num container web não temos o controle transacional provido pelo AS, então devemos passá-lo para o Seam.
  2. No persistence.xml alteramos o transaction-type da persistence-unit para RESOURCE_LOCAL e removemos a property hibernate.transaction.manager_lookup_class. Vamos mudar também a linha do data source, para utilizar ENC. Ela deve refletir:

    <non-jta-data-source>java:comp/env/jdbc/meuDatasource</non-jta-data-source>

    Note que aqui perdemos a possibilidade de transações distribuídas.

  3. Vamos definir agora no components.xml que o Seam será responsável pelo controle transcional. Adicionamos a seguinte linha:
  4. <transaction:entity-transaction entity-manager="#{entityManager}"/>

    Onde #{entityManager} é o nome da managed-persistence-context, que é o persistence context que será usado pelo Seam nas conversações. A definição do namespace:

    xmlns:transaction="http://jboss.com/products/seam/transaction"
    xsi:schemaLocation="http://jboss.com/products/seam/transaction http://jboss.com/products/seam/transaction-2.0.xsd"
  5. Para finalizarmos com essa parte de persistência falta apenas criar o próprio datasource. Quem usa o Sysdeo deve ir nas propriedades do Tomcat Project fazer isso, mas quem usa o WTP (usem!) não tem essa opção. Ao invés disso podemos usar o esquema de deploy de contexto do Tomcat. Crie um arquivo context.xml em seu WEB-INF/META-INF contendo seu data source. No meu caso:
  6. <?xml version="1.0" encoding="UTF-8"?>
    <Context>
    <Resource name="jdbc/meuDatasource" type="javax.sql.DataSource" driverClassName="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:meuBD" username="sa" password="" auth="Container" maxActive="20" maxIdle="5" maxWait="10000"/>
    </Context>
  7. Por último temos que adicionar as seguintes bibliotecas que não vêm no Tomcat:
  8. persistence-api.jar
    hibernate.jar
    hibernate-entitymanager.jar
    hibernate-validator.jar
    hibernate-annotations.jar
    dom4j.jar
    jta.jar
    hibernate-commons-annotations.jar
    cglib-nodep.jar
    antlr.jar
    jboss-common-core.jar

    jsf-api.jar
    jsf-impl.jar

    commons-logging-1.1.1.jar
    commons-collections-3.2.1.jar
    javassist.jar

    A maioria delas pode ser achada na pasta lib do Seam. No meu caso criei uma User Libraries e as marquei como dependência para a Web Library, assim organizo meus jars e torno mais fácil a adição desses frameworks em projetos futuros.

Assumi que se sabe somo criar um projeto Seam. Deixei a idéia de um tutorial básico de lado, quero ainda falar do uso do JBoss Tools para geração de código e um pouco da integração com o Drools e com o jBPM (muito interessante!!).

Dêem o feedback sobre o que querem ler! Que se houver muita manifestação de interesse faço um post, até se for o caso, sobre o gorado tutorial ou o passo-a-passo para a criação de um projeto Seam.

referência: Edem Morny’s Tech Blog

Related posts:

  1. Parte I: O que é Seam?
  2. Treinamento Seam
  3. Estrutura de um projeto Seam
  4. Two components with the same name and precedence
  5. Abertas inscrições para o JBoss In Bossa 2010
Advertisement

24 comments

  1. Ana Júlia says:

    Rafael,
    segui todos os passos que você citou acima, mas quando rodo o tomcat, na hora de dar o deploy, dá esse erro:

    org.apache.catalina.core.StandardContext listenerStart
    SEVERE: Exception sending context initialized event to listener instance of class org.jboss.seam.servlet.SeamListener
    java.lang.IllegalStateException: Two components with the same name and precedence – component name: authenticator, component classes: org.domain.teste2.session.Authenticator, org.domain.teste2.session.Authenticator

    Você saberia dizer porque??
    Desde já agradeço.
    Att.
    Ana Júlia

  2. rafaelliu says:

    Isso é problema no codigo. Só é possível ter componentes com nomes distintos no Seam (a não ser que tenham precedências diferentes, usando-se @Install). Você está com dois componentes “authenticator” registrados.

    O que acho estranho é que as classes registradas aparecem como sendo a mesma. Você por acaso não definiu esse componente através de XML e também annotations?

    Acho que vou fazer um tutorial Seam, já que vi muitos hints do google procurando por Seam tutorial.

  3. Daniel says:

    Poderia me informar os jars que preciso colocar na lib da app. Pois estou começando com o JBoss Seam agora e não sei quais são elas.

    Muito Obrigada

  4. rafaelliu says:

    Daniel, comece usando o JBoss Tools. Ele é um plugin do Eclipse para se mexer com os vários frameworks da JBoss. Utilizei esse plugin ao escrever o post.

    Dentro dele tem um perspectiva Seam onde pode-se criar templates de projetos Seam já funcionais e também possui outros wizards muito úteis a um iniciante

  5. Fala Liu! beleza cara, encontrei seu blog por aqui procurando algumas coisas sobre o seam, muito legal!! Parabéns!!

  6. rafaelliu says:

    Valeu João! Quanto tempo hein?

    Me adiciona no GTalk ai qualquer coisa.

    abs

  7. Paulo says:

    Cara, tava pesquisando na net e encontrei seu blog.

    Veja se pode me ajudar… Tenho o seam configurado aqui no tomcat de boa. Mas chegou num ponto do sistema onde terei que acessar mais 2 bancos além do qual já estava trabalhando. Como configurar isso? Não achei nada que ajudasse na internet!

    Valeu!

  8. rafaelliu says:

    @Paulo

    Você vai precisar de dois Persistence Units e especificar o unitName da Persistence Unit no @PersistenceContext na hora de injetá-lo.

  9. renata says:

    fiz o projeto com o seam-gen mas quando fui rodar deu problemas com datasource. O que que eu faço com o data source gerado pelo seam-gen?

    so esta parte que nao ficou muito clara… o context.xml fica dentro do web/WEB-INF certo?

    esta dando uns erros de JNDI fala que o jdbc nao existe no contexto

    me ajude!

  10. rafaelliu says:

    @renata

    É dentro do web/WEB-INF/META-INF ao que me parece que é a estrutura do teu projeto. O erro de JNDI é justamente devido ao Tomcat não está achando o contexto da aplicação nem o DataSource declarado.

    Você pode declara esse contexto direto no Tomcat também, só tem que lembrar de adicionar o DataSource também.

  11. Carlos says:

    Como faço para marcar a minha “User Library” do Seam com as libs citadas no artigo como dependência para a Web Library ???

    Obrigado e parabéns

  12. rafaelliu says:

    @Carlos

    No Eclipse, já nas propriedades do projeto no item Java EE Module Dependencies.

    As User Libraries marcadas lá irão para deploy.

  13. Leandro says:

    Rafael,
    Inicie um projeto com Seam aqui na empresa e estou aprendendo sim “na raça”. Estamos utilizando o Jboss AS como conteiner, e eu já sabia que o tomcat poderia ser utilizado como uma alternativa. Inicialmente optamos pelo AS devido ao conteiner EJB principalmente devido ao controle de transações (antes injetávamos o entity manger do conteiner EJB), porém após alguns estudos percebi que é muito melhor utilizar o entity manager gerenciado pelo Seam, aí vem a pergunta: Qual realmente a vantagem de utilizar o seam com o conteiner EJB?
    Obrigado e parabéns!

  14. rafaelliu says:

    @Leandro

    As vantagens são as facilidades que JEE dá. Por exemplo, transação distribuida e gerenciada pelo container (algumas classes Seam provêem isso por baixo dos panos) , web services, acesso remoto via RMI, etc.

    Mesmo algumas facilidades JEE são cobertas pelo Seam como injeção de dependência, controle transacional declarativo, segurança, interceptors, etc.

    A menos que seu projeto necessite facilidades JEE específicas, não há porque usar um AS e um Tomcat daria conta do recado tão bem quanto o JBoss AS.

  15. pablosborges says:

    Rafael, estou em um dilema, devo ou não utilizar ejb3 com o jboss
    seam? Lembrando que os hosts que oferecem jboss são caros. Eu pensei
    usar tomcat, daí eu não precisaria de usar ejb3. Mas como eu vou
    controlar as minhas transações? O seam controla por default as minhas
    transações (existe alguma regra) ? A melhor forma seria integrar com o
    spring, para ele gerenciar as minhas transações.

    Eu posso simplesmente não usar spring e EJB. e deixar o controle de transações gerenciado pelo seam ?

    Eu te adicionei no gtalk.

  16. rafaelliu says:

    @pablosborges

    Desculpa a demora.. Bom foi justamente a resposta do comentário anterior. Como regra você pode se perguntar se há algum motivo para usar EJB. Se não há motivos para o uso de EJBs, use POJO. O desenvolvimento se torna mais simples.

    O Seam tem sim controle transacional. Ele usa anotações @Begin e @End, você não precisa do Spring para isso.

    Um aspecto que pode passar despercebido são as diferenças de clusterização entre EJBs e POJOs. EJBs, SFSB e SLSB, foram feitos para clusterização e podem ser configurados com política de balanceamento de carga, alta disponibilidade, passivação, pool, etc. A clusterização de POJOs fica restrita à clusterização da sessão HTTP.

  17. Cristiano says:

    Funcionou belezinha! Parabéns pela dica! No meu caso só faltava incluir as linhas do namespace no components.xml. Valeu!!

  18. Renato says:

    Segui todas as suas dicas mas deu um erro: Cannot load JDBC driver class mesmo eu tendo incluído o jar do driver JDBC na lib da aplicação.

  19. rafaelliu says:

    Renato, adicione a em $TOMCAT_HOME/lib, se você adicionar dentro do WEB-INF/lib o Tomcat não enchergará, e é ele quem cria o Datasource.

  20. ilmar ferreira says:

    Cara tava tentando migrar meu projeto seam do jboss para o jetty e acredito que as configurações postadas seguem as mesmas diretivas. Após implementar todas as alterações postadas o jetty vai ao ar com sucesso mas quando tento acessar a aplicação existe uma execeção:

    javax.naming.NameNotFoundException; remaining name ‘EJBContext’

    Porque a esta altura de configuração, o seam ainda precisa procurar por um EJB context?

    Configurei o hibernate provider como
    org.hibernate.ejb.HibernatePersistence. e este é provalvelmente o problema. Logo, qual o provider que eu coloco no JPA?

  21. rafaelliu says:

    ilmar ferreira, o provider está certo. Deve ser alguma funcionalidade do Seam que tás usando.

    Veja a stacktrace para identificar em que ponto da sua aplicação isso acontece.

  22. Lelo De Pieri says:

    Caro Rafael,
    Estou trabalhando em uma aplicação que até o momento estávamos utilizando JBoss, mas como o tomcat nos é suficiente estamos querendo migrar para o mesmo.
    Fiz um projeto de teste rodar no jBoss e tentei migrá-lo seguindo o seu tutorial mas obtive o erro:
    SEVERE: Exception sending context initialized event to listener instance of class com.sun.faces.config.ConfigureListener
    java.lang.NoClassDefFoundError: javax/servlet/jsp/JspFactory
    at com.sun.faces.config.ConfigureListener.isJspTwoOne(ConfigureListener.java:523)

    Vasculhei o diretório lib do tomcat 6 e lá encontrei:
    unzip -l jsp-api.jar | grep JspFactory
    998 2010-07-19 14:58 javax/servlet/jsp/JspFactory.class

    Ou seja, a classe está lá.

    Tem alguma ideia de oque possa estar ocorrendo?

    PS: Estou inicializando o tomcat via eclipse

    Grato

Leave a Reply