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 :

Injecter un EJB dans une classe Java


Sujet :

Java EE

  1. #1
    Membre averti Avatar de Tom1x
    Femme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2013
    Messages : 22
    Par défaut Injecter un EJB dans une classe Java
    Bonjour,

    Est il possible d'injecter un EJB dans une classe Java avec CDI ?
    Si oui comment ?

  2. #2
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 326
    Billets dans le blog
    12
    Par défaut
    Salut,

    Je pense que tu peux, mais fait gaffe à ne pas mixer les annotations de déclaration et d'injection CDI/EJB (ps: par le passé j'avais déjà essayé de mixer CDI avec des annotations d'injection propres au framework JSF et j'avais eu des problèmes).

    Si tu veux tu peux toujours essayer de voir ce que ça donne :
    • Pour injecter un composant CDI (annoté avec @Named + Scope CDI), utilise l'annotation @Inject dans la classe où tu injectes ta dépendance.
    • Pour injecter un composant EJB (annoté avec @Stateless, @Stateful ou @Singleton en fonction de ton scope), utilise l'annotation @EJB dans la classe où tu injectes ta dépendance.



    Cordialement,
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  3. #3
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    oui, dans le dernière spec javaEE, les annotations d'injection EJB présentent dans les Beans CDI sont respectées, et inversément. Tu peux donc aussi injecter du CDI dans un EJB. J'ai du code ici où c'est l'orgie et tout le monde y trouve son compte

    Tu peux aussi injecter tout ça dans les Beans JSF, mais pas l'inverse il me semble.

  4. #4
    Membre averti Avatar de Tom1x
    Femme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2013
    Messages : 22
    Par défaut
    Merci pour vos réponses,

    Je suis novice avec CDI et c'est par hasard que je me suis rendu compte que je pouvais en avoir l'utilité.
    J'utilise Apache Shyro pour ma Sécurité et je dois implémenter mon propre Realm qui est une classe Java, j'utilise ensuite dans cette classe une méthode provenant de mon EJB me permettant de récupérer des valeurs depuis ma DB (via JPA) mais celui ci est null.

    C'est à ce moment que j'ai vu que les injection d'EJB ne fonctionnait que dans des servlet ejbs .. mais pas dans des classes java

    J'avais le choix en utilisant lookup ou CDI et je trouve que CDI est beaucoup plus pratique..
    J'ai cru voir que je pouvais utiliser l'annotation Produce avec un ManagerBean mais je ne sais pas si c'est vraiment adapté à mon besoin et s'il y a d'autres moyens plus simple pour faire ça.

    Je ne comprend pas pourquoi d'ailleurs l'injection d'EJB ne fonctionne pas dans une classe Java ?

  5. #5
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Fait quand même attention si tu es dans un Realm. Je ne connais pas apache Shyro, mais en général le realm se déclenche avant de rentrer dans la partie sécurisée où on trouve les EJB / Beans CDI. Du coup ton injection pourrait foirer parce qu'il n'y a pas encore de contexte accessible quand tu es dans le Realm. Ca dépend surtout de ta sécurité comment elle travaille. Si elle fonctionne au dessus du conteneur J2EE ou en dessous.

  6. #6
    Membre averti Avatar de Tom1x
    Femme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2013
    Messages : 22
    Par défaut
    Oui je comprend, je ferais attention à ça.
    Mais je suis dans l'impasse mon Realm est appelé implicitement par les méthodes des lib Shiro je ne peux pas faire autrement que d'appeler la méthode de mon EJB à moins de créer une classe DAO exprès pour cette méthode..

    Je ne vois vraiment pas comment injecter mon EJB dans ma java class avez vous d'autres idées ?

  7. #7
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Mais pourquoi ne pas utiliser la solution ultra simple de lookup JNDI ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Membre confirmé Avatar de JacNar6
    Homme Profil pro
    Développeur Java/Java EE/Android
    Inscrit en
    Mai 2012
    Messages
    163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Développeur Java/Java EE/Android

    Informations forums :
    Inscription : Mai 2012
    Messages : 163
    Par défaut
    Citation Envoyé par OButterlin Voir le message
    Mais pourquoi ne pas utiliser la solution ultra simple de lookup JNDI ?
    Pour avoir essayé Apache Shiro, je comprend Tom1x, car j'avais moi même essayé toutes les injections et les lookup possibles mais sans succès.
    J'avais dû abandonner l'idée de vouloir localiser mes EJB dans le Realm de Apache Shiro. J'avais contourné cela en utilisant mon managed bean de la page d'authentification pour récupérer tout ce dont j'ai besoin dans Apache Shiro.

    La présentation ci-dessous suppose l'utilisation des pages JSF pour la partie web.

    Ci-dessous ma page de login (avec PrimeFaces, m'est c'est pas ça le plus important)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:p="http://primefaces.org/ui">
     
        <ui:composition template="/templateLogin.xhtml">
            <ui:define name="body">
                <p:panel  class="background">
                    <div id="container">
                        <h:form>
                            <h:panelGroup id="display" style="position:fixed;top:35%;left:40%;">
                                <p:panelGrid columns="1">
                                    <p:messages globalOnly="true"/>
                                    <h:panelGrid columns="3">
     
                                        <p:outputLabel for="username" value="Login :" />
                                        <p:inputText id="username" value="#{userLoginViewController.username}" placeholder="User name"
                                                     required="true" label="Username" requiredMessage="Enter the login"
                                                     onkeyup="this.value = this.value.toUpperCase();"/>
                                        <h:message for="username" />
     
                                        <p:outputLabel for="password" value="Password :" />
                                        <p:password id="password" value="#{userLoginViewController.password}" placeholder="Password"
                                                    required="true" requiredMessage="Enter the password"/>
                                        <h:message for="password" />
                                        <p:outputLabel for="rememberMe" value="Remember Me:" />
                                        <p:selectBooleanCheckbox id="rememberMe"
                                                                 value="{userLoginViewController.rememberMe}" />
                                    </h:panelGrid>
                                    <p:commandButton action="#{userLoginViewController.authenticate()}"
                                                         update="display" 
                                                         value="Login"/>
                                </p:panelGrid>
                            </h:panelGroup>
                        </h:form>
                    </div>
                </p:panel>
            </ui:define>
     
        </ui:composition>
     
    </html>
    Le contrôleur (Managed Bean) de ma page

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    @ManagedBean
    @SessionScoped
    public class UserLoginViewController implements Serializable{
    
        @EJB
        private UserFacade userFacade;
        /**
         * Creates a new instance of UserLoginViewController
         */
        public UserLoginViewController()  {
        }
    
        private String username;
    
        private String password;
        
        private boolean rememberMe = false;
        
        private static final Logger log = Logger.getLogger(UserLoginViewController.class.getName());
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public boolean isRememberMe() {
            return rememberMe;
        }
    
        public void setRememberMe(boolean rememberMe) {
            this.rememberMe = rememberMe;
        }
        public String authenticate() {
        // Example using most common scenario of username/password pair:
            UsernamePasswordToken token = new UsernamePasswordToken(username,
                    password);
            
            // "Remember Me" built-in:
            token.setRememberMe(rememberMe);
            Subject currentUser = SecurityUtils.getSubject();
     
            try {
                currentUser.login(token);
            } catch (AuthenticationException e) {
                password = null;
                // Could catch a subclass of AuthenticationException if you like
                log.warning(e.getMessage());
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Login Failed (incorrect login or password, or user probably suspended )", e.toString()));
                
                return "/login";
            }
            SecurityUtils.getSubject().getSession().setAttribute("username", username);
            
            return "/views/index?faces-redirect=true";
     
        }
     
        public String logout() {
     
            Subject currentUser = SecurityUtils.getSubject();
            try {
                currentUser.logout();
                ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
                ec.redirect(((HttpServletRequest)ec.getRequest()).getRequestURI());
            } catch (Exception e) {
                log.warning(e.toString());
            }
            return null;
        }
        
        public User getUser(String login){
            return userFacade.findUserByLogin(login);
        }
    }
    Remarque surtout l'injection de mon EJB UserFacade et la méthode getUser (Bref des choses que tu aimerais faire dans ton Realm de Apache Shiro)

    Dans mon Realm Apache Shiro, j'ai la fonction ci-dessous

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    @Override
        protected AuthenticationInfo doGetAuthenticationInfo( AuthenticationToken authenticationToken) throws AuthenticationException {
           
            UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) authenticationToken;
            if (usernamePasswordToken.getUsername() == null
                    || usernamePasswordToken.getUsername().isEmpty()) {
                throw new AuthenticationException("Authentication failed");
            }
            FacesContext context = FacesContext.getCurrentInstance();
            UserLoginViewController userLoginViewController = context.getApplication().evaluateExpressionGet(context, "#{userLoginViewController}", UserLoginViewController.class);
            User user = userLoginViewController.getUser(usernamePasswordToken.getUsername());
    
            if (user == null || user.getStatutil()) {
                return null;
            }
            return new SimpleAccount(user.getNomUtil(), user.getMotdepas(), getName(), user.getRoles(), new HashSet());
            
        }
    Je m'appui sur le contrôleur de ma page web, que je récupère dans le contexte de l'application pour utiliser les EJB que je n'arrive pas récupérer avec Apache Shiro. J'espère que tout ceci aidera..... Mon appli est en exploitation aujoud'hui quelque part

  9. #9
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    le lookup jndi devrait marcher à tous les coup. C'est vrai que je ne comprend pas pourquoi tu préfère CDI. Oui tu peux injecter un EJB dans un bean CDI, mais si ton realm n'est pas un Bean CDI, tu rond, tu va devoir localiser le bean CDI et c'est un peu chiant à faire.

Discussions similaires

  1. Injection d'EJB dans une appli web lance java.lang.NullPointerException
    Par Sylvain__A_ dans le forum Glassfish et Payara
    Réponses: 1
    Dernier message: 20/06/2011, 23h31
  2. Réponses: 15
    Dernier message: 28/04/2009, 07h26
  3. Réponses: 5
    Dernier message: 28/09/2007, 14h58
  4. script sh dans une classe java
    Par decksroy dans le forum Langage
    Réponses: 2
    Dernier message: 11/09/2007, 18h33
  5. Réponses: 13
    Dernier message: 25/03/2005, 11h00

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