viernes, 25 de julio de 2014

Importando certificado a la JVM

Importando un certificado a la JVM (cacerts)

Esto permite evitar configurar programaticamente el certificado

System.setProperty(SSL_TRUSTSTORE, trustStore);
System.setProperty(SSL_TRUSTSTORE_PASSWORD, trustStorePwd);

donde:
trustStore=C\:\\ejemplo.jks
trustStorePwd=

y donde
public static final String SSL_TRUSTSTORE_PASSWORD  = "javax.net.ssl.trustStorePassword";
public static final String SSL_TRUSTSTORE                      = "javax.net.ssl.trustStore";

1. Listamos los certificados importados en la JVM
Entramos a <JAVA_HOME>\jre\lib\security\

  • keytool -list -v -keystore cacerts 


2. Importamos el certificado descargado desde el sitio HTTPS al cacerts de la JVM

  • keytool -importcert -alias "TEST_CERT" -file e:\\pepe.cer -keystore cacerts
  • password: changeit

Y si queremos generar un truestore (jks) a partir del certificado para poder utilizarlo programaticamente:

  • keytool.exe -import -file e:\pepe.cer -keystore e:\jjjjj.jks

NOTA: Si estamos ejecutando el código dentro de un jboss (es decir, tenemos alguna clase java dentro del jboss que intenta establecer una comunicacion segura con algun sitio) es factible que estas lineas (System.setProperty(..)...) no sean tenias en cuenta:

En un jboss 5.0.0.GA: Va a tomar en cuenta las lineas System.setProperty(...) sin problemas, con lo cual, programaticamente podemos setear el certificado y la conexion segura se establecera.

En un jboss 5.1.0.GA: Nunca va a tomar en cuenta las lineas System.setProperty(...), con lo cual, programaticamente NO podemos setear el certificado. Tenemos que agregarlo via configuracion del jboss como explicamos mas abajo.

***************************************************
IMPORTANTISIMO: Cuando se crea el keystore tiene que tener CN=localhost, sino esta como localhost no anda!
***************************************************


Importando varios certificados a un keystore (para no depender de la JVM en caso de futuros upgrades)

# Import VeriSign root certificate

  • keytool -import -v -keystore my.truststore -alias VeriSign_Root -storepass changeit -file VeriSign,Inc..crt


# Import VeriSign intermediate certificate

  • keytool -import -v -keystore my.truststore -alias VeriSignIntermediateCACert -storepass changeit -file VeriSignIntermediateCACert.txt


# Import server certificate

  • keytool -import -v -keystore my.truststore -alias server_cert -storepass changeit -file cert.cer


# List trust store certificates

  • keytool -list -v -keystore my.truststore


y en caso de querer levantar este keystore (certificado) generado previamente via configuracion del JBOSS

De esta manera, no es necesario setear programaticamente nada:

En jboss 5.1.0.GA:

Edit bin/run.conf

# Set trust store file location
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=c://server//jboss-5.0.0.GA_ConHTTPS_Activado//server//default//conf//demottrust.jks"
# Set trust store password
JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStorePassword=password"
# Turn off host verification if needed
#JAVA_OPTS="$JAVA_OPTS -Dorg.jboss.security.ignoreHttpsHost=true"
# Turn on ssl handshake debugging if needed
#JAVA_OPTS="$JAVA_OPTS -Djavax.net.debug=ssl,handshake"

En jboss 5.0.0.GA

Edit bin/run.bat (no me tomaba el run,conf)

# Set trust store file location
set JAVA_OPTS=%JAVA_OPTS% -Djavax.net.ssl.trustStore=c:\server\jboss-5.0.0.GA_ConHTTPS_Activado\server\default\conf\demottrust.jks
# Set trust store password

set JAVA_OPTS=%JAVA_OPTS% -Djavax.net.ssl.trustStorePassword=changeit

Nota: para esta version de jboss va sin comillas

Ver: http://jianmingli.com/wp/?p=975

Es importante entender que de esta manera, no hace falta agregar programáticamente ningún comando para levantar el certificado en la JVM y asi establecer la conexión segura (HTTPS).

lunes, 19 de mayo de 2014

Web Service + REST + JAX-RS

En WebServices existen dos modalidades: SOAP y REST
  1. JAX-WS represents SOAP
  2. JAX-RS represents REST
SOAP es intercambio de mensajes SOAP (que son mensajes envueltos en XML).
JAX WS es la implementación estándar de web services SOAP en Java. Viene desde la versión de JDK 6.

REST es una implementación posterior. Más rica, no sólo utiliza un tipo de mensaje HTTP para el intercambio de mensajes, si no que permite más mensajes. Esto es, con Rest puedes tener un cliente que envíe mensajes HTTP de tipo GET, PUT, POST y DELETE. Cada mensaje enviará los datos correspondientes asociados hacia el servidor, que, recibirá la petición, la entenderá, y delegará en el método correspondiente. GET sirve para recuperar un dato desde el cliente al servidor, PUT para insertar un dato, POST para enviar información para modificar y DELETE para eliminar información del servidor.

The important thing to know about the request body is that it is unique to each service. The service designer must define the format of the request body and convey that to service consumers. Information in the request body is typically encoded in XML or JSON format. Here is a typical HTTP request that contains XML information within the body:

Service CallDescription
GET http://{server}/MyRestService/library/booksGet a list of books
PUT http://{server}/MyRestService/library/books/12345Create a new book with ISBN 12345
GET http://{server}/MyRestService/library/books/12345Get a single book with ISBN 12345
DELETE http://{server}/MyRestService/library/books/12345Delete a single book with ISBN 12345

Link muy util:



Algunas implementaciones REST:
  • Apache CXF
  • Jersey
  • RESTeasy (is JBOSS provided implementation of JAX-RS specification for building RESTful Web Services and RESTful Java applications. Though this is not limited to be used in JBOSS only, and you can use with other servers also. In this post, I am building such a hello world application in tomcat server)
  • Restlet
  • Apache Wink

Ejemplo usando RESTeasy:

http://howtodoinjava.com/2013/05/09/resteasy-tomcat-hello-world-application/

Ejemplo usando CXF con Spring:

http://dhruba.name/2008/12/08/rest-service-example-using-cxf-22-jax-rs-10-jaxb-and-spring/
http://www.luckyryan.com/2013/06/15/apache-cxf-with-spring-integration/

Luego para acceder a la URL, vamos a:

http://localhost:8081/WSRestWithSpringProject/services

Y haciendo clic en la URL, vemos lo siguiente:


Para acceder a alguno de los dos servicios expuestos hacemos:

  • http://localhost:8081/WSRestWithSpringProject/myservice/users
  • http://localhost:8081/WSRestWithSpringProject/myservice/customers

Si queremos acceder a un método pasando por parámetro un valor:


El método es del estilo:

    @GET
    @Path("/users")
    @Produces("application/xml") //The @Produces annotation is used to 
    specify the format of the response. W
    @Override
    public Response getUsers(@QueryParam("id")String id) {
  
    UserCollection usersList = new UserCollection(users.values());
    if (StringUtils.hasText(id)){
    Integer idAsInt = Integer.valueOf(id);
    User user = users.get(idAsInt);
    System.out.println("user: " + user);
        return Response.status(200).entity(user).build();
   
    return Response.status(200).entity(usersList).build();
    }

Leer:
http://stackoverflow.com/questions/11552248/when-to-use-queryparam-vs-pathparam

Otro Ejemplo usando CXF con Spring + JSON:

This is a simple link to demostrate how to create a simple JAX-RS Web Service in Java using Spring and Apache CXF. This service will be follow the request/response pattern, it will using HTTP POSTs which are formatted JSON requests and it will produce JSON responses:

http://www.dreamsyssoft.com/blog/blog.php?/archives/7-Simple-JAX-RS-Web-Service-in-Java-with-Spring-and-CXF.html

@Path("/myservice")
@Consumes("application/json")
@Produces("application/json")
public interface UserManagerJson {

@GET
@Path("/fetchUserById")
public UserResponseJson fetchUserById(@QueryParam("id")String request);

..
}

public class UserManagerimplJson implements UserManagerJson {

@Override
public UserResponseJson fetchUserById(String request) {
UserResponseJson userResponseJson = new UserResponseJson();
userResponseJson.setSuccess(true);
userResponseJson.setErrorMessage("OK");
userResponseJson.setUsers(new ArrayList<String>());
return userResponseJson;
}
..
}

ApplicationContext.xml

.....
.....        
   <!-- 2. CON JSON RESPONSE -->
  <jaxrs:server id="userManagerWithJson" address="/dos">
  <jaxrs:serviceBeans>
  <ref bean="userManagerService"/>
  </jaxrs:serviceBeans>
  <jaxrs:providers>
<ref bean='jsonProvider' />
</jaxrs:providers>
  </jaxrs:server>
 
  <bean id="jsonProvider" 
class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
    
<bean id="userManagerService" class="service.json.UserManagerimplJson"/>

.....
.....

POM.XML

....
....
 <!-- Provider para jax-rs para devolver una respuesta en formato json -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.1.1</version>
</dependency>
....
....


jueves, 15 de mayo de 2014

Implementing an EJB as Web Service using jax-ws

Creando un EJB como un Web Service utilizando JAX-WS

Requerimientos:
  • JBoss 5.0.0.GA 
  • librerias JBoss WS native.

Vamos a copiar las siguientes librerias desde c:\server\jboss-5.0.0.GA\client\ y a c:\server\jboss-5.0.0.GA\lib\endorsed\
  • jbossws-native-jaxrpc.jar
  • jbossws-native-jaxws-ext.jar
  • jbossws-native-saaj.jar
  • jbossws-native-jaxws.jar

Luego, creamos el EJB y le agregamos la anotación @WebService

@WebService
@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;
}
}

@Remote
public interface BancoService {

public long consultarSaldo(String cuenta);
}

POM.XML

<dependencies>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>

<dependency>
   <groupId>org.mockito</groupId>
   <artifactId>mockito-all</artifactId>
   <version>1.9.5</version>
</dependency>
       
<dependency>
<groupId>org.mockejb</groupId>
<artifactId>mockejb</artifactId>
<version>0.6-beta2</version>
</dependency>

<dependency>
    <groupId>jboss</groupId>
    <artifactId>jboss-ejb-api</artifactId>
    <version>4.2.0.GA</version>
    <scope>provided</scope>
  </dependency>

<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>openejb-client</artifactId>
<version>4.0.0</version>
<scope>test</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>

Note: Existen dependencias de este POM que no son necesarias.

Y por ultimo, creamos un JAR utilizando mvn clean package y lo copiamos en c:\server\jboss-5.0.0.GA\server\default\deploy\

Para ver que el WS esta deployado correctamente, vamos a:

http://localhost:8099/jbossws/services


Para acceder al WSDL, vamos a:

http://localhost:8099/ejb-banco-service/BancoServiceImpl?wsdl

Utilizando el SOAP UI:



Creando un POJO como un Web Service utilizando JAX-WS

Deploying your ejb as webservice is not your only option: you can deploy a POJO as web service as well. In this case you just need to tag@WebService in a plain java class.

Pero para esto, vamos a necesitar armar un WAR y decir que el POJO sera un servlet



When you choose EJB over a POJO for a web service?

JAX-WS 2.0 allows both regular Java classes and stateless EJBs to be exposed as web services. If you
were using J2EE 1.4, you’re probably wondering why you’d use a stateless EJB as a web service. A
look at the code for a POJO and for EJB 3 web services reveals that there are hardly any differences,
with the exception that the EJB 3 web service will have a few extra annotations. A Java class web
service is packaged in a web module whereas an EJB web service is packaged in an EJB-JAR.
Both a Java web service and an EJB web service support dependency injection and lifecycle
methods such as @PostConstruct and @PreDestroy, but you get a few extra benefits from
using EJB 3 web services.

Leer: http://www.mastertheboss.com/jboss-web-services/jboss-web-services-part-1

Connecting to EJB using lookup + JBoss 5

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();
                                }
                }



Connecting to EJB using lookup + OpenEJB

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 OpenEJB (version 4.6.0.2)

Creamos un JAR con las dos clases y la deployamos en la carpeta apps:

Ex:
c:\server\apache-openejb-4.6.0.2\apps\ejb-banco-service.jar

Levantamos el OpenEJB

c:\server\apache-openejb-4.6.0.2\bin\Start.bat

Cremos un test de integracion

@BeforeClass
public static void setUp() throws NamingException {
/**
* Inicializando contexto de JEE
*/
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
env.put(Context.PROVIDER_URL, "ejbd://localhost:4201");
ctx = new InitialContext(env);
}

@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("BancoServiceImplRemote");
long result = service.consultarSaldo("666");
Assert.assertEquals(SALDO_ESPERADO, result);

}

POM.XML (tanto para crear el jar con el EJB como para crear el test de integracion)

<dependencies>

<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-ejb_3.0_spec</artifactId>
<version>1.0.1</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>

<dependency>
   <groupId>org.mockito</groupId>
   <artifactId>mockito-all</artifactId>
   <version>1.9.5</version>
</dependency>
       
<dependency>
<groupId>org.mockejb</groupId>
<artifactId>mockejb</artifactId>
<version>0.6-beta2</version>
</dependency>

<dependency>
    <groupId>jboss</groupId>
    <artifactId>jboss-ejb-api</artifactId>
    <version>4.2.0.GA</version>
    <scope>provided</scope>
   </dependency>

<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>openejb-client</artifactId>
<version>4.0.0</version>
<scope>test</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>

Importante: la dependencia "openejb-client" tiene que ser la version 4.0 o superior

Nota: Existen dependencies en este POM que a los fines de esta prueba pueden no ser necesarias