Creamos un EJB
@Remote//Anotamos la interface como remote para poder ser accedida desde JNDI
public interface BancoService {
public long consultarSaldo(String cuenta);
}
@Stateless
public class BancoServiceImpl implements BancoService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final long SALDO_ESTATICO=1000000;
/* (non-Javadoc)
* @see com.gemalto.inlakech.spring.ejb.template.example.BancoService#consultarSaldo(java.lang.String)
*/
@Override
public long consultarSaldo(String cuenta){
logger.info("Entering to method with paraemeters[cuenta:"+cuenta+"]");
//TODO here business logic to get REAL balance
logger.info("The current balance for cuenta["+cuenta+"] is ["+SALDO_ESTATICO+"]");
return SALDO_ESTATICO;
}
}
Deployamos el EJB en JBoss (version 5.0.0.GA)
Creamos un JAR con las dos clases y la deployamos en la carpeta apps:
Ex:
c:\server\jboss-5.0.0.GA\server\default\deploy\ejb-banco-service.jar
Levantamos el JBoss
c:\server\jboss-5.0.0.GA\bin\run.bat
Aqui vemos como el EJB se deployó correctamente bajo el jndi name:
BancoServiceImpl/remote-com.gemalto.inlakech.spring.ejb.template.example.BancoService
ó
BancoServiceImpl/remote
Cremos un test de integracion
@BeforeClass
public static void setUp() throws NamingException {
Properties props = new Properties();
props.setProperty("java.naming.provider.url", "localhost:1099");
props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
ctx = new InitialContext(props);
}
@AfterClass
public static void tearDown() throws NamingException {
ctx.close();
}
@Test//Consultar SALDO desde API de EE
public void conlsutarSaldoRemoteEJBTest() throws NamingException {
BancoService service = (BancoService) ctx.lookup("BancoServiceImpl/remote-com.gemalto.inlakech.spring.ejb.template.example.BancoService");
long result = service.consultarSaldo("666");
Assert.assertEquals(SALDO_ESPERADO, result);
BancoService service2 = (BancoService) ctx.lookup("BancoServiceImpl/remote");
long result2 = service2.consultarSaldo("666");
Assert.assertEquals(SALDO_ESPERADO, result2);
}
POM.XML (tanto para crear el jar con el EJB como para crear el test de integracion)
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jboss</groupId>
<artifactId>jboss-ejb-api</artifactId>
<version>4.2.0.GA</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<!-- slf4j dependencies for Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- logback dependencies -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
</dependencies>
Nota: Existen dependencias en este POM que a los fines de esta prueba pueden no ser necesarias
Importante: la dependencia "jbossall-client" NO ESTA EN EL POM ya que tuve problemas para bajar dicha dependencia... PERO USE LA QUE TRAE EL JBOSS y la agregue al classpath, pero hay que tener en cuenta que este JAR esta vacio, solo tiene referencias a los JARs que se necesitan:
c:\server\jboss-5.0.0.GA\client\jbossall-client.jar
Esta dependencia es vital para acceder remotamente al EJB deployado en el JBOSS.
This jar file contains a classpath reference to various client jar files used by jboss client applications.
Each of the jar files in the following list must available in the same directory as the jbossall-client.jar, Otherwise they will not be found by the classloader.
The classpath includes the following files:
- commons-logging.jar
- concurrent.jar
- ejb3-persistence.jar
- hibernate-annotations.jar
- jboss-aop-client.jar
- jboss-appclient.jar
- jboss-aspect-jdk50-client.jar
- jboss-client.jar
- jboss-common-core.jar
- jboss-deployers-client-spi.jar
- jboss-deployers-client.jar
- jboss-deployers-core-spi.jar
- jboss-deployers-core.jar
- jboss-deployment.jar
- jboss-ejb3-common-client.jar
- jboss-ejb3-core-client.jar
- jboss-ejb3-ext-api.jar
- jboss-ejb3-proxy-client.jar
- jboss-ejb3-proxy-clustered-client.jar
- jboss-ejb3-security-client.jar
- jboss-ha-client.jar
- jboss-ha-legacy-client.jar
- jboss-iiop-client.jar
- jboss-integration.jar
- jboss-j2se.jar
- jboss-javaee.jar
- jboss-jsr77-client.jar
- jboss-logging-jdk.jar
- jboss-logging-log4j.jar
- jboss-logging-spi.jar
- jboss-main-client.jar
- jboss-mdr.jar
- jboss-messaging-client.jar
- jboss-remoting.jar
- jboss-security-spi.jar
- jboss-serialization.jar
- jboss-srp-client.jar
- jboss-system-client.jar
- jboss-system-jmx-client.jar
- jbosscx-client.jar
- jbosssx-as-client.jar
- jbosssx-client.jar
- jmx-client.jar
- jmx-invoker-adaptor-client.jar
- jnp-client.jar
- slf4j-api.jar
- slf4j-jboss-logging.jar
- xmlsec.jar
Leer para entender que pasa con las dependencias del JBoss 5:
http://www.javahelp.info/2010/01/27/get-the-right-dependencies-for-jboss-5-client-and-maven/
Segunda alternativa
Otra alternativa de configuracion y consumo de EJB gracias al aporte de Carlos Weckesser
- La configuración de nuestro pom es la siguiente:
<properties>
...
<jboss-as-client-version>5.1.0.GA</jboss-as-client-version>
...
</properties>
<dependencies>
...
<dependency>
<groupId>org.jboss.jbossas</groupId>
<artifactId>jboss-as-client</artifactId>
<version>${jboss-as-client-version}</version>
<type>pom</type>
<scope>test</scope>
</dependency>
...
</dependencies>
- Luego definimos una interfaz comun con los metodos necesarios:
package com.myCompany.myProject.interfaces;
public interface MyPrettyInterfaceCommon {
/** Mapped name for this EJB custom */
public static final String MAPPED_NAME = "MyPrettyImplementationConnector";
public void performPrettyAction1();
public void performPrettyAction2();
}
- Posteriormente, creamos nuestra interfaz local, extendiendo la misma de la interfaz comun y utilizando las anotaciones correspondientes a un componente "local":
package com.myCompany.myProject.interfaces;
@Local(MyPrettyInterfaceLocal.class)
@LocalBinding(jndiBinding = MyPrettyInterfaceLocal.MAPPED_NAME + "/local")
public interface MyPrettyInterfaceLocal extends MyPrettyInterfaceCommon {
}
- A continuación, creamos nuestra interfaz remota, extendiendo la misma de la interfaz comun y utilizando las anotaciones correspondientes a un componente "remoto":
package com.myCompany.myProject.interfaces;
@Remote(MyPrettyInterfaceRemote.class)
@RemoteBinding(jndiBinding = MyPrettyInterfaceRemote.MAPPED_NAME + "/remote")
public interface MyPrettyInterfaceRemote extends MyPrettyInterfaceCommon {
}
- Después, definimos una implementación para las interfaces local y remota de la siguiente manera:
package com.myCompany.myProject.implementations;
@Stateless(mappedName = MyPrettyImplementationConnector.MAPPED_NAME)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class MyPrettyImplementationConnector implements MyPrettyInterfaceLocal,
MyPrettyInterfaceRemote {
...
}
- Por último, vemos un ejemplo de como podemos utilizar inyección de dependencias y resolución de componentes por JNDI para obtener instancias de nuestros componentes:
package com.myCompany.myProject.implementations;
public class AnotherClass {
// Inyeccion de dependencia de interfaz local
@EJB
protected MyPrettyInterfaceLocal myPrettyConnectorLocal;
// Inyeccion de dependencia de interfaz remota
@EJB
protected MyPrettyInterfaceRemote myPrettyConnectorRemote;
// Lookup via JNDI de interfaz local
public void useLocalInterface() {
MyPrettyInterfaceLocal connector = (MyPrettyInterfaceLocal) ctx
.lookup("MyPrettyImplementationConnector/local-com" +
".myCompany.myProject.interfaces.MyPrettyInterfaceLocal");
connector.performPrettyAction1();
}
// Lookup via JNDI de interfaz remota
public void useRemoteInterface() {
MyPrettyInterfaceRemote connector = (MyPrettyInterfaceRemote) ctx
.lookup("MyPrettyImplementationConnector/remote-com" +
".myCompany.myProject.interfaces.MyPrettyInterfaceRemote");
connector.performPrettyAction1();
}
}