A partir da especificação EJB 3.1 para os beans de sensação sem informação de estado com acesso local à definição de uma interface assim como a utilização da anotação @Local são opcionais. Lembramos que para acesso remoto, tanto a definição da interface remota como a utilização da anotação @Remote continuam sendo necessárias. Para testar nosso bean de sessão criaremos um Servlet que fará uso do nosso componente. Como esse Servlet está rodando localmente a referencia para o bean de sessão pode ser obtida através de injeção de dependência com a utilização da anotação @EJB. Se desconsiderarmos essa anotação e a variável de instância anotada por ela, o nosso Servlet é convencional. package estacio; import import import import import import import import java.io.IOException; java.io.PrintWriter; javax.ejb.EJB; javax.servlet.ServletException; javax.servlet.annotation.WebServlet; javax.servlet.http.HttpServlet; javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletResponse; @WebServlet(name = "ConversorServlet", urlPatterns = { "/ConversorServlet" }) public class ConversorServlet extends HttpServlet { private static final long serialVersionUID = 1L; @EJB private Conversor conversorBean; protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); try { String valor = request.getParameter("valor"); String de = request.getParameter("de"); String para = request.getParameter("para"); out.println("<html>"); out.println("<head>"); out.println("<title>Conversão de Escalas</title>"); out.println("</head>"); out.println("<body>"); if (valor == null || de == null || para == null) { out.println("<form action=\"ConversorServlet\" method=\"post\">"); out.println("<fieldset title=\"Conversão de Escalas\">"); out.println("De: <input type=\"text\" name=\"valor\"/><br/>"); out.println("<select name=\"de\">"); out.println("<option value=\"Celsius\">Celsius</option>"); out.println("<option value=\"Fahrenheit\">Fahrenheit</option>"); out.println(" <option value=\"Kelvin\">Kelvin</option>"); out.println("</select>"); out.println("Para: <select name=\"para\">"); out.println("<option value=\"Celsius\">Celsius</option>"); out.println("<option value=\"Fahrenheit\">Fahrenheit</option>"); out.println(" <option value=\"Kelvin\">Kelvin</option>"); out.println("</select>"); out.println("<input type=\"submit\" value=\"Converter\"/>"); out.println("</fieldset>"); out.println("</form>"); } else { double valorConvertido = Double.parseDouble(valor); if (de.equalsIgnoreCase("Celsius") && para.equalsIgnoreCase("Fahrenheit")) { out.println(valor + "° " + de + " equivalem a " + conversorBean .celsiusToFahrenheit(valorConvertido) + "° " + para); } } // Implemente o restante da lógica out.println("</body>"); out.println("</html>"); } catch (Exception e) { e.printStackTrace(); } finally { out.close(); } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } } Nos casos dos beans que implementam uma interface remorta, esses objetos devem ser obtidos pelas aplicações remotas através do método lookup() pertencente a um objeto do tipo javax.naming.InitialContext. Esse objeto Java Naming and Directory Interface (JNDI) que é uma API para acesso a serviços de diretórios que possibilita a obtenção dos Session Beans remotos. Essa API é disponibilizada pela API dos servidores de aplicação, podendo ser inclusive utilizada pelo Java SE. Observe interface rêmora declarada abaixo que visa fornecer um método de conversão de uma velocidade de Km/h para M/s. package estacio; import javax.ejb.Remote; @Remote public interface ConversorVelocidade { public double kmhToMs(double velocidade); } Agora alteraremos nosso ConversorBean para que ele implemente essa nova interface. Além de adicionar os métodos necessários devemos inserir também à notação @Remote, para indicar qual a interface remota implementada pelo nosso bean. package estacio; import javax.ejb.Local; import javax.ejb.Remote; import javax.ejb.Stateless; @Stateless @Local(Conversor.class) @Remote(ConversorVelocidade.class) public class ConversorBean implements Conversor, ConversorVelocidade{ @Override public double kmhToMs(double velocidade) { return velocidade*0.277777778; } ... Agora nosso session bean ConversorBean tem implementados uma interface local e uma rêmora. A interface local já foi testada através do Servlet ConversorServlet, agora precisamos exemplificar a utilização dos métodos da interface remota, para isso criaremos outro projeto, só que desta vez um projeto Java convencional com apenas uma classe. Para isso siga os passos descritos abaixo. 1. Arquivo/ Novo/ Classe Java 2. Defina o nome que julgar apropriado e finaliza a criação do projeto. package estacio; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; public class TesteRemoto { public static void main(String[] args) { try { Context ic = new InitialContext(); ConversorVelocidade conversorBean = (ConversorVelocidade) ic .lookup("estacio.ConversorVelocidade"); System.out.println(conversorBean.kmhToMs(100)); } catch (NamingException ex) { ex.printStackTrace(); ; } } } Execute a classe para verificar o resultado obtido. Abaixo vemos o ciclo de vida de um Stateless Session Bean. http://marakana.com/bookshelf/jboss_admin_tutorial/ejb.html Existem duas anotações básicas que podem ser utilizadas nos beans de sessão: @PostConstruct e @PreDestroy. A primeira é utilizada para indicar qual método será executado após o bean ser instanciado e a segunda qual método será utilizado antes de ser destruído. Poderíamos inserir fragmento de código abaixo no bean ConversorBean para observarmos as consequências da utilização dessas anotações.