elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Java
| | | |-+  Controlar Timeout mediante un EJB
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Controlar Timeout mediante un EJB  (Leído 6,515 veces)
routerico

Desconectado Desconectado

Mensajes: 34


Ver Perfil
Controlar Timeout mediante un EJB
« en: 31 Enero 2015, 13:19 pm »

Hola qué tal, estoy intentando controlar un TimeOut mediante un EJB.


Ésta es la clase que tiene mi EJB:

import javax.ejb.Stateless;
import javax.ejb.Timeout;
 
@Stateless
public class TimeoutRespuesta {
   
 
    @Timeout
    public int sumador(int resultado){
 
        return resultado;
 
    }
}




Exporto el EJB mediante un .jar, me creo un proyecto Java y me creo una clase de pruebas:


public class Suma {
 
    public static void main(String[] args) {
       
       
        int res = (new TimeoutRespuesta()).sumador(sumar(1,2));
       
        System.out.println(res);
       
    }
 
    public static int sumar(int a, int b){
       
        return a+b;
    }
}



Aunque es un ejemplo muy sencillo, pero mi idea es controlar el Timeout mediante EJB, si fuese un método más complejo que no deje la aplicación bloqueada, que salte el Timeout del EJB y salga del método.

¿Estaría bien así?.

¿Cuál es el tiempo por defecto del Timeout del EJB?.


Un saludo y muchas gracias.


En línea

Usuario Invitado


Desconectado Desconectado

Mensajes: 625



Ver Perfil
Re: Controlar Timeout mediante un EJB
« Respuesta #1 en: 31 Enero 2015, 15:42 pm »

Cuando se utiliza un método timeout anotado con @timeout, la especificación nos dice que el método debe retornar void y sólo recibir como parámetro un objeto javax.ejb.TimerService o en su defecto, no debe recibir parámetros.

Para registrar un timeout podemos hacerlo de la siguiente manera (de acuerdo a la tercera forma):

Código
  1. createTimer(long duracionInicial, long duracionIntervalo, serializable objetoAsociado);

Así que puedes crearlo así:

Código
  1. @Resource TimerService timer; // opcional, aquí inyectamos al objeto TimerService
  2.  
  3. public void doSomething(Objeto obj) {
  4.    timer.createTimer(15*60*1000, 15*60*1000, obj);
  5. }

Lo que se ha hecho es crear un TimerService cuya primera véz de ejecución será un timeout de 15 minutos y el intérvalo entre ejecuciones será de 15 minutos también. Así mismo, hemos asociado al TimerService un objeto que debe implementar Serializable.

Bien, ahora el método que se ejecutará luego del registro del TimerService será:

Código
  1. @timeout doOtherThing(Timer timer)  {
  2.    Objeto obj = (Objeto) timer.getInfo();
  3.    // hacer otras cosas...
  4. }

El método getInfo() retorna el objeto asociado al TimerService. Si al momento de crear el TimerService en lugar de un objeto se declara null, el valor devuelto será null también.

Ahora, si estoy en lo correcto, podemos cancelar un TimerService. Por ejemplo si en lugar de un objeto le hemos asociado un nombre, podríamos detenerlo así:

Código
  1. public void stop(String timerName) {
  2.    for(Object obj : timerService.getTimers()) {
  3.        Timer t = (Timer)obj;
  4.        if (t.getInfo().equals(timerName)) {
  5.        t.cancel();
  6.        }
  7.    }
  8. }

Pero si no hemos asociado un nombre, podemos detenerlos iterando el conjunto de TimerService:

Código
  1. public void stop() {  
  2.        List<Timer> timers = timerService.getTimers();  
  3.        if (timers != null)  
  4.        {  
  5.            for(Timer t : timers) {
  6.                t.cancel();
  7.            }
  8.        }  
  9. }

Salu2.

PD: Usa las etiquetas Geshi para colocar código.


« Última modificación: 31 Enero 2015, 18:03 pm por Gus Garsaky » En línea

"La vida es muy peligrosa. No por las personas que hacen el mal, si no por las que se sientan a ver lo que pasa." Albert Einstein
routerico

Desconectado Desconectado

Mensajes: 34


Ver Perfil
Re: Controlar Timeout mediante un EJB
« Respuesta #2 en: 31 Enero 2015, 18:14 pm »

Cuando se utiliza un método timeout anotado con @timeout, la especificación nos dice que el método debe retornar void y sólo recibir como parámetro un objeto javax.ejb.TimerService o en su defecto, no debe recibir parámetros.

Para registrar un timeout podemos hacerlo de la siguiente manera (de acuerdo a la tercera forma):

Código
  1. createTimer(long duracionInicial, long duracionIntervalo, serializable objetoAsociado);

Así que puedes crearlo así:

Código
  1. @Resource TimerService timer; // opcional, aquí inyectamos al objeto TimerService
  2.  
  3. public void doSomething(Objeto obj) {
  4.    timer.createTimer(15*60*1000, 15*60*1000, obj);
  5. }

Lo que se ha hecho es crear un TimerService cuya primera véz de ejecución será un timeout de 15 minutos y el intérvalo entre ejecuciones será de 15 minutos también. Así mismo, hemos asociado al TimerService un objeto que debe implementar Serializable.

Bien, ahora el método que se ejecutará luego del registro del TimerService será:

Código
  1. @timeout doOtherThing(Timer timer)  {
  2.    Objeto obj = (Objeto) timer.getInfo();
  3.    // hacer otras cosas...
  4. }

El método getInfo() retorna el objeto asociado al TimerService. Si al momento de crear el TimerService en lugar de un objeto se declara null, el valor devuelto será null también.

Ahora, si estoy en lo correcto, podemos cancelar un TimerService. Por ejemplo si en lugar de un objeto le hemos asociado un nombre, podríamos detenerlo así:

Código
  1. public void stop(String timerName) {
  2.    for(Object obj : timerService.getTimers()) {
  3.        Timer t = (Timer)obj;
  4.        if (t.getInfo().equals(timerName)) {
  5.        t.cancel();
  6.        }
  7.    }
  8. }

Pero si no hemos asociado un nombre, podemos detenerlos iterando el conjunto de TimerService:

Código
  1. public void stop() {  
  2.        List<Timer> timers = timerService.getTimers();  
  3.        if (timers != null)  
  4.        {  
  5.            for(Timer t : timers) {
  6.                t.cancel();
  7.            }
  8.        }  
  9. }

Salu2.

PD: Usa las etiquetas Geshi para colocar código.

Muchas gracias por tu ayuda, pero tengo algunas dudas de implementación.

Si quisiera controlar el timeout de un método como el anterior, ¿sería algo así?


Código
  1.  
  2. import java.io.Serializable;
  3. import javax.annotation.Resource;
  4. import javax.ejb.Stateless;
  5. import javax.ejb.Timeout;
  6. import javax.ejb.Timer;
  7. import javax.ejb.TimerService;
  8.  
  9.  
  10. @Stateless
  11. public class TimeoutRespuesta {
  12.  
  13.  
  14. @Resource TimerService timer;
  15.  
  16. public void doSomething(Object obj) {
  17.    timer.createTimer(1000, 1000, (Serializable) obj);
  18. }
  19.  
  20. @Timeout void doOtherThing(Timer timer)  {
  21.    Object obj = (Object) timer.getInfo();
  22.  
  23. }
  24.  
  25. public int sum(int i){
  26. return i;
  27. }
  28.  
  29. }
  30.  
  31.  



Código
  1. import timeout.TimeoutRespuesta;
  2.  
  3.  
  4. public class Suma {
  5.  
  6. public static void main(String[] args) {
  7.  
  8.  
  9. int res = (new TimeoutRespuesta()).sum(sumar(1,2));
  10.  
  11. System.out.println(res);
  12.  
  13. }
  14.  
  15. public static int sumar(int a, int b){
  16. return a+b;
  17. }
  18. }
  19.  
  20.  
  21.  


Gracias.
En línea

Usuario Invitado


Desconectado Desconectado

Mensajes: 625



Ver Perfil
Re: Controlar Timeout mediante un EJB
« Respuesta #3 en: 1 Febrero 2015, 00:08 am »

No te entiendo. ¿Dices que quieres controlar el timeout dinámicamente?

Si es así, puedes controlarlo cancelándolo y volviendo a crearlo. Por ejemplo:

Código
  1. public void startOrModifyTimer(long initialExpiration, long interval, String name){      
  2.        for (Timer timer: timer.getTimers()) {
  3.            if (timer.getInfo().equals(name)) {
  4.                timer.cancel();
  5.            }
  6.        }
  7.        TimerConfig config = new TimerConfig();
  8.        config.setInfo(name);
  9.        config.setPersistent(false);
  10.        timerService.createIntervalTimer(initialExpiration, interval, config);
  11. }
En línea

"La vida es muy peligrosa. No por las personas que hacen el mal, si no por las que se sientan a ver lo que pasa." Albert Einstein
routerico

Desconectado Desconectado

Mensajes: 34


Ver Perfil
Re: Controlar Timeout mediante un EJB
« Respuesta #4 en: 1 Febrero 2015, 17:16 pm »

No te entiendo. ¿Dices que quieres controlar el timeout dinámicamente?

Si es así, puedes controlarlo cancelándolo y volviendo a crearlo. Por ejemplo:

Código
  1. public void startOrModifyTimer(long initialExpiration, long interval, String name){      
  2.        for (Timer timer: timer.getTimers()) {
  3.            if (timer.getInfo().equals(name)) {
  4.                timer.cancel();
  5.            }
  6.        }
  7.        TimerConfig config = new TimerConfig();
  8.        config.setInfo(name);
  9.        config.setPersistent(false);
  10.        timerService.createIntervalTimer(initialExpiration, interval, config);
  11. }


Hola, muchas gracias. Ésto es lo que quiero hacer, pongo un ejemplo:

Tengo un proyecto web en Java, ahora bien, tengo un método que hace una consulta a la base de datos, pues imagínate que se queda pillado el método y no devuelve nunca el resultado de la consulta, en vez de quedarse bloqueado, lo que quiero es mediante el timeout de un EJB, controlar y decir si se invoca el método y pasan 20 segundos y no se recibe respuesta que se salga del método y no se quede pillado ahí.


Saludos.
En línea

Usuario Invitado


Desconectado Desconectado

Mensajes: 625



Ver Perfil
Re: Controlar Timeout mediante un EJB
« Respuesta #5 en: 1 Febrero 2015, 17:52 pm »

Yo lo haría así:

1.- Hacer la consulta en un Thread.
2.- Haces la consulta.
3.- Registras el Timer a 20 segundos.
4.- En el método @Timeout cancelas el Thread y por consiguiente la consulta.
En línea

"La vida es muy peligrosa. No por las personas que hacen el mal, si no por las que se sientan a ver lo que pasa." Albert Einstein
routerico

Desconectado Desconectado

Mensajes: 34


Ver Perfil
Re: Controlar Timeout mediante un EJB
« Respuesta #6 en: 1 Febrero 2015, 18:29 pm »

Yo lo haría así:

1.- Hacer la consulta en un Thread.
2.- Haces la consulta.
3.- Registras el Timer a 20 segundos.
4.- En el método @Timeout cancelas el Thread y por consiguiente la consulta.

Vale gracias, hice los pasos:


1.- Hacer la consulta en un Thread.

Código
  1.  
  2. public class ConsultaBBDD implements Runnable{
  3.  
  4. public void run() {
  5. String datos = consultarBBDD();
  6.  
  7. }
  8.  
  9. public String consultarBBDD(){
  10. return "datosBBDD";
  11. }
  12. }
  13.  
  14.  






2.- Haces la consulta.


Código
  1. public class ClasePrincipal {
  2.  
  3. public String obtenerDatos(){
  4. Thread t = new Thread(new ConsultaBBDD());
  5. t.start();
  6.  
  7. return "";
  8. }
  9.  
  10. }
  11.  
  12.  



3.- Registras el Timer a 20 segundos.
4.- En el método @Timeout cancelas el Thread y por consiguiente la consulta.


Código
  1. import java.io.Serializable;
  2. import javax.annotation.Resource;
  3. import javax.ejb.Stateless;
  4. import javax.ejb.Timeout;
  5. import javax.ejb.Timer;
  6. import javax.ejb.TimerService;
  7.  
  8.  
  9. @Stateless
  10. public class TimeoutRespuesta {
  11.  
  12. @Resource TimerService timer;
  13.  
  14. public void doSomething(Object obj) {
  15.    timer.createTimer(20000, 20000, (Serializable) obj);
  16. }
  17.  
  18. @Timeout void doOtherThing(Timer timer)  {
  19.    Thread t = new Thread();
  20.    t.stop();
  21. }
  22. }
  23.  




¿Sería algo parecido a lo que puse?. Lo que me falta sería la invocación del EJB dentro de la ClasePrincipal, pero es que no sé exactamente cómo sería, ¿qué método suyo tendrían que invocar?.


Muchas gracias.

Saludos.

En línea

Usuario Invitado


Desconectado Desconectado

Mensajes: 625



Ver Perfil
Re: Controlar Timeout mediante un EJB
« Respuesta #7 en: 1 Febrero 2015, 19:18 pm »

Exactamente. Me captaste la idea  ;D

Para invocar al método @Timeout no es necesario invocar nada. En el momento en que registras un TimerService, el método @Timeout se invocará automáticamente cuando expire el tiempo de espera.

Otra cosa. Un TimerService tiene que ser usado en un servidor de aplicaciones ya que, éste será inyectado por medio de @Resource por el contenedor del servidor. Además creo que para usar un EJB Timer es necesario especificar si es un Bean local o remoto por medio de sus interfaces. Te dejo un ejemplo:

Interface local:
Código
  1. import javax.ejb.Local;
  2. import javax.ejb.Timer;
  3.  
  4. @Local
  5. public interface BeanLocal {
  6. public void start(String name);
  7. public void execute(Timer timer);
  8. public void stop(String name);
  9. }

El EJB
Código
  1. import javax.annotation.Resource;
  2. import javax.ejb.Singleton;
  3. import javax.ejb.Timeout;
  4. import javax.ejb.Timer;
  5. import javax.ejb.TimerService;
  6.  
  7. @Singleton
  8. public class TimerBean implements BeanLocal {
  9.  
  10. @Resource TimerService timer;
  11.  
  12. @Override
  13. public void start(String name) {
  14. boolean exists = false;
  15. for(Timer temp : timer.getTimers()) {
  16. if(temp.getInfo().equals(name))
  17. exists = true;
  18. }
  19. if(!exists)
  20. timer.createTimer(15000, 3000, name);
  21. }
  22.  
  23. @Override @Timeout
  24. public void execute(Timer timer) {
  25. System.out.println("M&#233;todo @Timeout invocado: "+timer.getInfo());
  26. }
  27.  
  28. @Override
  29. public void stop(String name) {
  30. for(Timer temp : timer.getTimers()) {
  31. if(temp.getInfo().equals(name))
  32. temp.cancel();
  33. }
  34. }
  35.  
  36. }

Luego, donde uses el EJB Timer lo inyectas también:

Código
  1. @Inject private BeanLocal myEJB;

Para registrar un TimerService, simplemente haría:

Código
  1. myEJB.start("identificadorTimer");

Y para cancelar un TimerService:

Código
  1. myEJB.stop("identificadorTimer");

Nota: Yo le puse @Singleton porque quería que solo exista una instancia del EJB Timer. Funciona igual con EJB Stateless y Stateful.

UPDATE

De acuerdo a la especificación de EJB 3.1, si va a ser un EJB local solamente, se puede obviar la interface @Local. Solo basta ponerle al EJB @LocalBean para indicar que es un EJB local.

Código
  1. @LocalBean
  2. @Singleton
  3. public class TimerBean {
« Última modificación: 1 Febrero 2015, 21:32 pm por Gus Garsaky » En línea

"La vida es muy peligrosa. No por las personas que hacen el mal, si no por las que se sientan a ver lo que pasa." Albert Einstein
routerico

Desconectado Desconectado

Mensajes: 34


Ver Perfil
Re: Controlar Timeout mediante un EJB
« Respuesta #8 en: 1 Febrero 2015, 19:47 pm »

Exactamente. Me captaste la idea  ;D

Para invocar al método @Timeout no es necesario invocar nada. En el momento en que registras un TimerService, el método @Timeout se invocará automáticamente cuando expire el tiempo de espera.

Otra cosa. Un TimerService tiene que ser usado en un servidor de aplicaciones ya que, éste será inyectado por medio de @Resource por el contenedor del servidor. Además creo que para usar un EJB Timer es necesario especificar si es un Bean local o remoto por medio de sus interfaces. Te dejo un ejemplo:

Interface local:
Código
  1. import javax.ejb.Local;
  2. import javax.ejb.Timer;
  3.  
  4. @Local
  5. public interface BeanLocal {
  6. public void start(String name);
  7. public void execute(Timer timer);
  8. public void stop(String name);
  9. }

El EJB
Código
  1. import javax.annotation.Resource;
  2. import javax.ejb.Singleton;
  3. import javax.ejb.Timeout;
  4. import javax.ejb.Timer;
  5. import javax.ejb.TimerService;
  6.  
  7. @Singleton
  8. public class TimerBean implements BeanLocal {
  9.  
  10. @Resource TimerService timer;
  11.  
  12. @Override
  13. public void start(String name) {
  14. boolean exists = false;
  15. for(Timer temp : timer.getTimers()) {
  16. if(temp.getInfo().equals(name))
  17. exists = true;
  18. }
  19. if(!exists)
  20. timer.createTimer(15000, 3000, name);
  21. }
  22.  
  23. @Override @Timeout
  24. public void execute(Timer timer) {
  25. System.out.println("Método @Timeout invocado: "+timer.getInfo());
  26. }
  27.  
  28. @Override
  29. public void stop(String name) {
  30. for(Timer temp : timer.getTimers()) {
  31. if(temp.getInfo().equals(name))
  32. temp.cancel();
  33. }
  34. }
  35.  
  36. }

Luego, donde uses el EJB Timer lo inyectas también:

Código
  1. @Inject private BeanLocal myEJB;

Para registrar un TimerService, simplemente haría:

Código
  1. myEJB.start("identificadorTimer");

Y para cancelar un TimerService:

Código
  1. myEJB.stop("identificadorTimer");

Nota: Yo le puse @Singleton porque quería que solo exista una instancia del EJB Timer. Funciona igual con EJB Stateless y Stateful.

De acuerdo, muchísimas gracias. Mañana lo voy a probar a ver qué sucede.

Un saludo!!
En línea

routerico

Desconectado Desconectado

Mensajes: 34


Ver Perfil
Re: Controlar Timeout mediante un EJB
« Respuesta #9 en: 2 Febrero 2015, 20:31 pm »



Código
  1. @Inject private BeanLocal myEJB;

Para registrar un TimerService, simplemente haría:

Código
  1. myEJB.start("identificadorTimer");

Y para cancelar un TimerService:

Código
  1. myEJB.stop("identificadorTimer");

Nota: Yo le puse @Singleton porque quería que solo exista una instancia del EJB Timer. Funciona igual con EJB Stateless y Stateful.

UPDATE

De acuerdo a la especificación de EJB 3.1, si va a ser un EJB local solamente, se puede obviar la interface @Local. Solo basta ponerle al EJB @LocalBean para indicar que es un EJB local.

Código
  1. @LocalBean
  2. @Singleton
  3. public class TimerBean {




Hola compañero, me está dando NullPointerException cuando en el proyecto web.


- Me creo el atributo del EJB
Código
  1. @Inject private BeanLocal myEJB;


Pero cuando invoco al método start, ahí me da NullPointerException

Código
  1. myEJB.start("identificadorTimer");


¿Cómo tendría que instanciar el EJB dentro de una clase del Proyecto Web para que no me de null?

Un saludo y muchas gracias de nuevo.
En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Controlar circuito mediante LPT
Electrónica
nser 3 6,848 Último mensaje 6 Octubre 2006, 01:50 am
por skapunky
Controlar TimeOut en conexión
Java
imaginawireless 4 6,065 Último mensaje 23 Febrero 2012, 04:41 am
por RyogiShiki
Controlar un led mediante un Transistor como interruptor
Electrónica
ButterySAM777 0 2,661 Último mensaje 30 Diciembre 2013, 15:05 pm
por ButterySAM777
'Hackers' pueden controlar su celular mediante una herramienta ya integrada
Noticias
Mister12 0 2,050 Último mensaje 2 Agosto 2014, 07:33 am
por Mister12
Read timeout
Java
Xedrox 2 2,394 Último mensaje 5 Septiembre 2014, 20:45 pm
por Chuidiang
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines