IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java EE Discussion :

La création d'un EJB avec des paramètres côté serveur et son invocation côté client.


Sujet :

Java EE

  1. #1
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 608
    Par défaut La création d'un EJB avec des paramètres côté serveur et son invocation côté client.
    Bonjour,

    J'ai égaré la manière de créer un EJB 3 Stateless ou Stateful qui prend des paramètres au moment de sa création.

    Pouvez-vous me rappeler comment on l'implémente côté serveur puis on l'invoque côté client? Je me rappelle de ce que je faisais en EJB 2... mais en EJB 3 pour faire l'équivalent, j'ai un trou de mémoire!

    Avez-vous un exemple en stock?


    Je vous remercie d'avance,

    Grunt.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 70
    Par défaut
    Ca veut dire quoi "EJB qui prend des paramètres au moment de sa création" ?
    Voulez vous dire "un Session Bean qui récupère les paramétrés d'initialisation " ?
    Paramètres d'initialisation == paramètres passés dans le fichier ejb_jar;

  3. #3
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 608
    Par défaut
    Un ejb qui en EJB 2 aurait été invoqué comme cela:

    MonService = home.create("Service spécial");


    Comment obtient-on l'équivalent en EJB 3?

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    70
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 70
    Par défaut
    Je ne sais pas exactement ce que vous voulez faire mais sachez que la méthode create n'existe plus en EJB3.
    Il faudra jongler entre la constructeur par défaut (obligatoire) et la méthode annotée @PostConstruct (appelée juste après l'instantiation du bean) pour arriver à vos fins.

  5. #5
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 608
    Par défaut
    En fait, c'est exactement un exemple de ce jonglage que je cherche.

    Implémentation côté serveur,
    et invocation côté client.

  6. #6
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 608
    Par défaut
    Bonjour,

    Je m'excuse de relancer cette question, mais je vais avoir besoin de passer un paramètre à la construction de mes stateless bean très prochainement.

    Concrètement, mon problème est de m'assurer qu'un service sera rendu dans la locale qu'a choisie un appelant (qui n'est pas nécessairement un site web).

    Trois solutions:
    1) L'atroce
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    @Stateless public class MonServiceBean
    {
       public void service1(Locale locale, ...);
       public void service2(Locale locale, ...);
       public void service3(Locale locale, ...);
    }
    2) La solution de contournement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Stateless public class MonServiceBean
    {
    private Locale m_locale;
     
       public void setLocale(Locale locale) {m_locale = locale};
       public void service1(...);
       public void service2(...);
       public void service3(...);
    }
    Mais alors tous les appelants se paient le triplet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    MonService service = ctx.lookup("...mon service...");
    service.setLocale(locale);
    service.service1();
    3) La solution que j'aimerais voir, sans la trouver précisément
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Stateless public class MonServiceBean
    {
    private Locale m_locale;
     
       @PostConstruct create(Locale locale) {m_locale = locale};
       public void service1(...);
       public void service2(...);
       public void service3(...);
    }

    Côté client, je ne sais pas précisément comment l'invoquer, de surcroît ...

    Cela me gêne, parce qu'en EJB 2, j'aurais créé et utilisé le constructeur d'un EJB avec des paramètres sans difficultés. Alors, pourquoi est-ce que je ne parviens pas à trouver son équivalent en EJB 3?


    Grunt.

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    365
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Par défaut
    Salut,

    Déjà, étant donné que chaque client aura son propre Locale, tu ne pourrais pas utiliser ta solution 2) parce qu'un stateless session bean peut être réutilisé pour servir des clients différents. Donc il y aurait collision des valeurs de la variable d'instance m_locale.
    Par contre, cette solution est celle qui conviendrait si ton ejb était déclaré Stateful.

    Si tu tiens à ce que cet ejb reste Stateless, ta solution 1) me semble plus adaptée, et le locale dans ce cas serait enregistré dans HttpSession ou équivalent (pour client non web).

    La solution 3) ne convient pas, à partir du moment où @PostConstruct est appelé juste après instanciation et injection de dépendances, on ne dispose pas encore de la valeur passée par le client, sauf si c'est pour initialiser une valeur par défaut.

    Un ejb qui en EJB 2 aurait été invoqué comme cela:

    MonService = home.create("Service spécial");

    Comment obtient-on l'équivalent en EJB 3?
    Justement, même en ejb2, on ne peut faire cela que sur un ejb stateful.
    Et comme il s'agit d'initialiser une variable d'instance, en ejb3 on peut faire un appel initial comme dans ta solution 2), puis réutiliser la variable d'instance dans les appels suivants.

    J'espère que ça aide.

  8. #8
    Membre très actif

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    608
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 608
    Par défaut
    Merci pour tes réponses. Cependant, je ne suis pas d'accord avec ce que tu dis.

    Un EJB stateless peut être utilisé par des clients différents, certes.
    Mais il ne l'est que par un seul à la fois à un instant donné, et sa méthode @PostConstruct est toujours appelée dans ce cas, avant qu'un service soit exécuté. Sinon, on ne pourrait jamais s'assurer qu'il soit dans un état initial certain.
    Ce n'est pas le cas d'un éventuel constructeur que l'on aurait déclaré pour l'EJB Stateless, qui lui effectivement, ne sera jamais appelé qu'une fois.


    La solution 1 que je propose n'est pas acceptable parce qu'elle vieillit brutalement tout le code appelant, et demande de vastes changements.

    Je viens de trouver une solution théorique en EJB 3... Mais elle n'est pas drôle.

    Côté serveur:
    Déclarer une Home, avec le prototype de la méthode create que l'on souhaite avoir, à l'ancienne.

    Annoter son bean avec @RemoteHome.
    Implémenter sa méthode create, en l'annotant avec @Init.

    Côté client:
    Réaliser une invocation, à la sauce EJB 2.

    1) lookup dans le contexte avec la home,
    2) PortableRemoteObject.narrow(...);
    3) Invocation de create avec ses paramètres.


    Note que pour l'instant, l'ayant juste découverte, je n'ai pas encore essayée cette construction. Mais elle semble pouvoir marcher.

    Je pense (il me semble que) les EJB stateless peuvent tout à fait être construits avec des arguments, ce n'est pas l'apanage des seuls EJB statefuls. En revanche, ils ne peuvent pas être volontairement détruits, car ils n'acceptent pas @Remove.

    Grunt.

  9. #9
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    365
    Détails du profil
    Informations personnelles :
    Localisation : Maroc

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Par défaut
    Citation Envoyé par grunt2000 Voir le message
    Merci pour tes réponses. Cependant, je ne suis pas d'accord avec ce que tu dis.

    Un EJB stateless peut être utilisé par des clients différents, certes.
    Mais il ne l'est que par un seul à la fois à un instant donné, et sa méthode @PostConstruct est toujours appelée dans ce cas, avant qu'un service soit exécuté. Sinon, on ne pourrait jamais s'assurer qu'il soit dans un état initial certain.
    Justement, c'est pour cela qu'il est dit stateless (sans état), entendu sans état conversationnel, qui dépendrait d'un client. Un ejb stateless est utilisé par un seul client à un instant donné, comme tu dis, mais c'est seulement parce que le container gère la synchronisation des accès concurrent. Deux appels de méthodes différents de la part d'un même client sur un même ejb stateless peuvent être servis par deux instances différentes de l'ejb.
    Toutes les instances d'un même ejb stateless sont considérées comme équivalentes; et c'est pour cela que le container peut optimiser en créant un certain nombre d'instances qu'il place dans un pool. A chaque appel de client, il en prend une de libre dans le pool pour servir cet appel, et la renvoie aussitôt la méthode terminée.
    Ainsi la méthode @PostConstruct pour un stateless bean n'est appelée qu'une seule fois, au moment de la création des instances de bean, que le container fait à sa guise pour remplir le pool.

    Citation Envoyé par grunt2000 Voir le message
    La solution 1 que je propose n'est pas acceptable parce qu'elle vieillit brutalement tout le code appelant, et demande de vastes changements.

    Je viens de trouver une solution théorique en EJB 3... Mais elle n'est pas drôle.

    Côté serveur:
    Déclarer une Home, avec le prototype de la méthode create que l'on souhaite avoir, à l'ancienne.

    Annoter son bean avec @RemoteHome.
    Implémenter sa méthode create, en l'annotant avec @Init.

    Côté client:
    Réaliser une invocation, à la sauce EJB 2.

    1) lookup dans le contexte avec la home,
    2) PortableRemoteObject.narrow(...);
    3) Invocation de create avec ses paramètres.


    Note que pour l'instant, l'ayant juste découverte, je n'ai pas encore essayée cette construction. Mais elle semble pouvoir marcher.
    Tu remarqueras que dans l'exemple de ce lien, l'ejb en question est avec état (stateful), ce qui revient à ce que je disais dans mon post précédent. La méthode annotée @Init correspond ici à ejbCreate() si la classe d'implémentation du bean est écrit avec les API ejb2.x

    Remarque aussi dans cet exemple, il s'agit d'adapter un ejb2 à la sauce ejb3, tout en ne modifiant pas l'interface du bean pour ne pas perturber les codes clients qui utilisent l'ancienne API, ce qui semble être ton souci aussi.
    Par contre, dans ton cas, je pense que c'est difficile d'échapper à une modification des codes clients, parce que c'est le besoin qui change aussi, il faudrait bien un moyen pour obtenir le Locale du client, ce qui plaide pour un ejb stateful.

    Citation Envoyé par grunt2000 Voir le message
    Je pense (il me semble que) les EJB stateless peuvent tout à fait être construits avec des arguments, ce n'est pas l'apanage des seuls EJB statefuls. En revanche, ils ne peuvent pas être volontairement détruits, car ils n'acceptent pas @Remove.
    Non, les EJB stateless n'acceptent pas des arguments dépendant du client, parce qu'ils peuvent être construits par le container sans qu'il y ait le moindre appel de client, comme dit plus haut.
    Bien évidemment, un ejb stateless peut initialiser des attributs indépendants du client (EntityManager, DataSource, autre EJB, QueueConnectionFactory, JavaMail...)

    Bon, je suis conscient que tout ceci ne résout toujours pas ton problème si vraiment tu ne pas faire autrement que d'éviter à tout pris de modifier les codes clients.
    Il faudrait encore chercher sûrement, peut-être du côté de la nouvelle spécification JSR-299 (Contexts and Dependency Injection) dans JavaEE6. L'idée serait de créerr un Producer method qui récupérerait le Locale hors de l'ejb, puis ce locale serait injecté dans notre ejb ou un un autre managed bean auquel on accéderait, sans que cela puisse affecter l'interface client.
    Je vais faire un post si j'ai quelque de plus précis, sous forme de code simple.
    Sinon il faudrait se résoudre à faire plus de modif de code client.

Discussions similaires

  1. création d'une dll avec des pointeurs en paramètre
    Par patoche.05 dans le forum Langage
    Réponses: 7
    Dernier message: 03/07/2010, 02h27
  2. ireport et création de rapport avec des paramètres
    Par Talel2010 dans le forum iReport
    Réponses: 9
    Dernier message: 05/04/2010, 11h51
  3. Réponses: 2
    Dernier message: 27/07/2004, 14h38
  4. Erreur sur une fonction avec des paramètres
    Par Elois dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 05/05/2004, 21h00
  5. créer un noeuds avec des paramétres
    Par Toxine77 dans le forum XMLRAD
    Réponses: 5
    Dernier message: 21/01/2003, 16h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo