JBoss 5.0.1.GA, EJB3, Maven2 e Cargo Juntos e na Prática
Neste post vou mostrar como criar um projeto EJB 3 bem simples usando Maven 2. Vamos fazer o deploy no JBoss 5.o.1.GA através do plugin do maven do cargo. Além disso vamos criar um projeto cliente que acessa o EJB criado através de JNDI.
Meu objetivo é mostrar de uma maneira simples e que funciona :) como usar maven 2 com projetos ejb3, de barbada vamos fazer o deploy no JBoss 5.0.1.GA, no fim do post você irá encontrar os códigos fontes e bem como as dependências(jars) da aplicação cliente.
Criar uma aplicação Java com Maven é realmente muito fácil mais quando falamos de fazer um deploy no servidor com o cargo usando o plugin do maven as coisas não são tão simples, por que a documentação do Cargo não é 100% intuitiva e faltam exemplos práticos de como usar as configurações. Além disso o JBoss 5 ainda não está 100% com o maven 2, mais para frente do post vocês irão entender o por que disso.
Cuidado com o JDK
Recomendo que você use um JDK acima do JDKu10, eu estou usando no momento o JDKu13. Caso você use um inferior ao JDKu10 você terá sérios problemas para subir o comtainer do JBoss 5. Existem diversos posts em blogs e tutoriais na web que recomendam você colocar os jars do jaxb e jaxws no diretório endorsed da jvm, para mim isso não funcionou. A melhor saída é usar um JDK mais novo.
Nota: Até por que o JDK tem uma performance melhor do que as dos anteriores e recursos bem interessantes em termos de ferramentas.
O Projeto EJB 3
Nesse projeto vamos criar uma interface de negocio chamada de DateService. Essa interface é simples seu objetivo e representar o contrato de um serviço de datas, que informa através de uma String a data atual do container. Vamos ao código da interface:
Agora vamos a implementação do EJB 3. Vou usar os novos recursos do EJB 3 em termos de anotações. Vamos ver o código então:
Como podem ver a implementação é simples, por que o meu objetivo no post é mostrar como integrar e usar essas tecnologias. Muito bem agora vamos ao pom do maven desse projeto:
Vocês podem ver que estou usando o plugin de ejb do maven e bem como o plugin do cargo. Não repare ao onde diz 'jboss4x' pois isso funciona no JBoss 5. Na propriedade 'home' você tem que apontar para a sua intalação do JBoss 5.
Agora suba o JBoss 5.0 pelo console e após o JBoss ter subido execute os seguintes goals do maven:
Com o 'cargo:deploy' você irá fazer o deploy do seu ejb no JBoss 5 através do plugin do cargo do maven. Agora verifique no console do JBoss5, ele deve ter mostrado algo parecido com isso:
Agora podemos ir para o projeto ejb-client. Nesse projeto vamos usar maven, mas será necessário o uso de bibliotecas fora as do maven.
Por que não usar Maven no Ejb3-Client?
Por que ao utilizar os repositórios do maven do JBoss que são:
A Classe de testes do projeto cliente, ela chama o ejb através e um lookup JNDI feito por uma classe helper chamada de ServiceLocator que por sinal é um padrão de design da sun.
Vamos a classe de ServiceLocator. Essa classe é genérica, e melhora a qualidade do código mas para isso você deve criar as suas implementação de ejb com o sufixo Bean.
As configurações de JNDI estão em um arquivo properties. São as configurações default para o JBoss.
E por fim vamos ver o pom desse projeto. Perceba que as dependências não estão aqui:
Os Jars necessários ao projeto cliente são:
Como eu já disse antes você acha esses jars aqui: $JBOSS_HOME/lib e e $JBOSS_HOME/common/lib.
Ok, podemos rodar a classe client, perceba que ela é uma classe de testes do Junit. Vamos rodar o teste, o resultado deve ser algo como esse:
Você pode pegar os fontes completos no meu repositório do Subersion. São esses urls:
Abraços e até a próxima.
Meu objetivo é mostrar de uma maneira simples e que funciona :) como usar maven 2 com projetos ejb3, de barbada vamos fazer o deploy no JBoss 5.0.1.GA, no fim do post você irá encontrar os códigos fontes e bem como as dependências(jars) da aplicação cliente.
Criar uma aplicação Java com Maven é realmente muito fácil mais quando falamos de fazer um deploy no servidor com o cargo usando o plugin do maven as coisas não são tão simples, por que a documentação do Cargo não é 100% intuitiva e faltam exemplos práticos de como usar as configurações. Além disso o JBoss 5 ainda não está 100% com o maven 2, mais para frente do post vocês irão entender o por que disso.
Cuidado com o JDK
Recomendo que você use um JDK acima do JDKu10, eu estou usando no momento o JDKu13. Caso você use um inferior ao JDKu10 você terá sérios problemas para subir o comtainer do JBoss 5. Existem diversos posts em blogs e tutoriais na web que recomendam você colocar os jars do jaxb e jaxws no diretório endorsed da jvm, para mim isso não funcionou. A melhor saída é usar um JDK mais novo.
Nota: Até por que o JDK tem uma performance melhor do que as dos anteriores e recursos bem interessantes em termos de ferramentas.
O Projeto EJB 3
Nesse projeto vamos criar uma interface de negocio chamada de DateService. Essa interface é simples seu objetivo e representar o contrato de um serviço de datas, que informa através de uma String a data atual do container. Vamos ao código da interface:
package com.blogspot.diegopacheco.services; /** * Interface de Servico de Data * * @author Diego Pacheco * @version 1.0 * @since 03/05/2009 * */ public interface DateService { public String getDateTime(); }
Agora vamos a implementação do EJB 3. Vou usar os novos recursos do EJB 3 em termos de anotações. Vamos ver o código então:
package com.blogspot.diegopacheco.services; import java.util.Date; import javax.ejb.Remote; import javax.ejb.Stateless; /** * Stateless Session Bean que eh uma implementacao do Servico de Data * * @author Diego Pacheco * @version 1.0 * @since 03/05/2009 * */ @Stateless @Remote(DateService.class) public class DateServiceBean implements DateService{ public String getDateTime() { return new Date().toString(); } }
Como podem ver a implementação é simples, por que o meu objetivo no post é mostrar como integrar e usar essas tecnologias. Muito bem agora vamos ao pom do maven desse projeto:
4.0.0 com.blogspot.diegopacheco mvn2-jboss5-ejb3 1.0-SNAPSHOT ejb Maven 2 + EJB 3.0 + Jboss 5 org.apache.maven.plugins maven-compiler-plugin 1.6 UTF-8 true org.apache.maven.plugins maven-source-plugin attach-sources jar org.apache.maven.plugins maven-ejb-plugin 3.0 org.codehaus.cargo cargo-maven2-plugin 0.3-SNAPSHOT false jboss4x remote runtime D:/Diego/Java/bin/jboss-5.0.1.GA/server/default javax.ejb ejb-api 3.0
Vocês podem ver que estou usando o plugin de ejb do maven e bem como o plugin do cargo. Não repare ao onde diz 'jboss4x' pois isso funciona no JBoss 5. Na propriedade 'home' você tem que apontar para a sua intalação do JBoss 5.
Agora suba o JBoss 5.0 pelo console e após o JBoss ter subido execute os seguintes goals do maven:
mvn clean install cargo:deploy
Com o 'cargo:deploy' você irá fazer o deploy do seu ejb no JBoss 5 através do plugin do cargo do maven. Agora verifique no console do JBoss5, ele deve ter mostrado algo parecido com isso:
20:26:11,545 INFO [MainDeployer] deploy, url=file:/D:/Diego/workspace-gps/mvn2-jboss5-ejb3/target/mvn2-jboss5-ejb3-1.0-SNAPSHOT.jar 20:26:11,717 INFO [Ejb3DependenciesDeployer] Encountered deployment AbstractVFSDeploymentContext@19623251{vfszip:/D:/Diego/workspace-gps/mvn2-jboss5-ejb3/target/mvn2-jboss5-ejb3-1.0-SNAPSHOT.jar/} 20:26:11,718 INFO [Ejb3DependenciesDeployer] Encountered deployment AbstractVFSDeploymentContext@19623251{vfszip:/D:/Diego/workspace-gps/mvn2-jboss5-ejb3/target/mvn2-jboss5-ejb3-1.0-SNAPSHOT.jar/} 20:26:14,862 INFO [JBossASKernel] Created KernelDeployment for: mvn2-jboss5-ejb3-1.0-SNAPSHOT.jar 20:26:14,871 INFO [JBossASKernel] installing bean: jboss.j2ee:jar=mvn2-jboss5-ejb3-1.0-SNAPSHOT.jar,name=DateServiceBean,service=EJB3 20:26:14,871 INFO [JBossASKernel] with dependencies: 20:26:14,871 INFO [JBossASKernel] and demands: 20:26:14,872 INFO [JBossASKernel] jboss.ejb:service=EJBTimerService 20:26:14,872 INFO [JBossASKernel] and supplies: 20:26:14,872 INFO [JBossASKernel] jndi:DateServiceBean/remote-com.blogspot.diegopacheco.services.DateService 20:26:14,872 INFO [JBossASKernel] jndi:DateServiceBean/remote 20:26:14,872 INFO [JBossASKernel] Class:com.blogspot.diegopacheco.services.DateService 20:26:14,872 INFO [JBossASKernel] Added bean(jboss.j2ee:jar=mvn2-jboss5-ejb3-1.0-SNAPSHOT.jar,name=DateServiceBean,service=EJB3) to KernelDeployment of: mvn2-jboss5-ejb3-1.0-SNAPSHOT.jar 20:26:15,068 INFO [SessionSpecContainer] Starting jboss.j2ee:jar=mvn2-jboss5-ejb3-1.0-SNAPSHOT.jar,name=DateServiceBean,service=EJB3 20:26:15,086 INFO [EJBContainer] STARTED EJB: com.blogspot.diegopacheco.services.DateServiceBean ejbName: DateServiceBean 20:26:15,169 INFO [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI: DateServiceBean/remote - EJB3.x Default Remote Business Interface DateServiceBean/remote-com.blogspot.diegopacheco.services.DateService - EJB3.x Remote Business Interface
Agora podemos ir para o projeto ejb-client. Nesse projeto vamos usar maven, mas será necessário o uso de bibliotecas fora as do maven.
Por que não usar Maven no Ejb3-Client?
Por que ao utilizar os repositórios do maven do JBoss que são:
- http://repository.jboss.org/maven2/
- http://repository.jboss.com/maven2/
- $JBOSS_HOME/lib
- $JBOSS_HOME/common/lib
A Classe de testes do projeto cliente, ela chama o ejb através e um lookup JNDI feito por uma classe helper chamada de ServiceLocator que por sinal é um padrão de design da sun.
package com.blogspot.diegopacheco.services; import org.junit.Test; import com.blogspot.diegopacheco.services.DateService; /** * Classe de testes unitarios que usa o ejb 3. * * @author Diego Pacheco * @version 1.0 * @since 03/05/2009 * */ public class ClientEjb3Test { @Test public void testDateServiceAsGetDate(){ try{ System.out.println("Inicio dos testes."); DateService ds = ServiceLocator.getServiceRemote(DateService.class); System.out.println("A Data retornada do EJB eh:" + ds.getDateTime()); System.out.println("Fim dos testes."); }catch(Throwable t){ t.printStackTrace(); } } }
Vamos a classe de ServiceLocator. Essa classe é genérica, e melhora a qualidade do código mas para isso você deve criar as suas implementação de ejb com o sufixo Bean.
package com.blogspot.diegopacheco.services; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; /** * Classe utitilária para recuperação de EJBs. * * @author Diego Pacheco * @version 1.0 * @since 03/05/2009 * */ public class ServiceLocator { public static final String RemoteJNDIName = "Bean/remote"; private static String BASE; private static FileInputStream PATH_SIMPLE; private static String BASE_PATH; private static Context context; static{ try { BASE = new File(".").getCanonicalPath(); BASE_PATH = BASE + "/src/main/resources/jndi.properties"; PATH_SIMPLE = new FileInputStream(new File(BASE_PATH)); } catch (Throwable t) { throw new RuntimeException(t); } } static{ try { Properties properties = new Properties(); try { properties.load(PATH_SIMPLE); properties.list(System.out); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } context = new InitialContext(properties); } catch (NamingException e){ e.printStackTrace(); } } @SuppressWarnings("unchecked") public staticT getServiceRemote(Class clazz) throws NamingException{ T temp = (T)context.lookup( clazz.getSimpleName() + RemoteJNDIName ); return temp; } }
As configurações de JNDI estão em um arquivo properties. São as configurações default para o JBoss.
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces java.naming.provider.url=jnp://localhost:1099
E por fim vamos ver o pom desse projeto. Perceba que as dependências não estão aqui:
4.0.0 com.blogspot.diegopacheco mvn2-jboss5-ejb3-client jar 1.0-SNAPSHOT Maven 3 + EJB3 + Jboss 5 Client org.apache.maven.plugins maven-compiler-plugin 1.6 UTF-8 true org.apache.maven.plugins maven-source-plugin attach-sources jar junit junit 4.3 com.blogspot.diegopacheco mvn2-jboss5-ejb3 1.0-SNAPSHOT
Os Jars necessários ao projeto cliente são:
- concurrent.jar
- jboss-aop.jar
- jboss-common-core.jar
- jboss-ejb3-common.jar
- jboss-ejb3-core.jar
- jboss-ejb3-proxy.jar
- jboss-ejb3-security.jar
- jboss-integration.jar
- jboss-javaee.jar
- jboss-logging-spi.jar
- jboss-remoting.jar
- jboss-remoting-aspects.jar
- jboss-security-spi.jar
- jbosssx.jar
- jboss-transaction-aspects.jar
- jnpserver.jar
Como eu já disse antes você acha esses jars aqui: $JBOSS_HOME/lib e e $JBOSS_HOME/common/lib.
Ok, podemos rodar a classe client, perceba que ela é uma classe de testes do Junit. Vamos rodar o teste, o resultado deve ser algo como esse:
Inicio dos testes. -- listing properties -- java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory java.naming.provider.url=jnp://localhost:1099 java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces A Data retornada do EJB eh:Sun May 03 20:50:37 BRT 2009 Fim dos testes.
Você pode pegar os fontes completos no meu repositório do Subersion. São esses urls:
- http://diegopacheco.svn.beanstalkapp.com/sandbox/trunk/mvn2-jboss5-ejb3
- http://diegopacheco.svn.beanstalkapp.com/sandbox/trunk/mvn2-jboss5-ejb3-client
Abraços e até a próxima.