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 :

Choix de technologies pour un projet web


Sujet :

Java EE

  1. #1
    Membre habitué
    Inscrit en
    Septembre 2008
    Messages
    261
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 261
    Points : 164
    Points
    164
    Par défaut Choix de technologies pour un projet web
    Salut,
    Alors dans les grandes lignes, j'essaie de faire un projet avec des technologies que je maitrise plus ou moins, sachant que je tente de le faire avec les dernières versions.
    Du coup, cela donne du struts 2 pour la partie web. Après je tente une assco ejb 3/hibernate. C'est là que je me pose une petite question.
    J'aurais des ejb entity et des sessions qui vont communiquer avec mes DAO (sans doute une DaoFactory).

    Je me demande est ce que je tape ensuite côté action directement dans les ejb, ou est ce que je cree des classes services.
    Enfin, quel serait la solution la plus propre. Je recherche un modèle d'architecture propre et fiable en gros

    ...+ est ce que je différencie les entity des pojo métiers. Je suppose que oui...

    Merci

  2. #2
    Membre habitué
    Inscrit en
    Septembre 2008
    Messages
    261
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 261
    Points : 164
    Points
    164
    Par défaut
    2 petites questions.
    Je n'arrive pas à lancer l'appli via l'ear :

    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
    Caused by: org.jboss.as.server.deployment.DeploymentUnitProcessingException: JBAS011448: Failed to parse "/C:/install_jboss/7.1.1.Final/standalone/deployments/ikEAR.ear/ikBO.jar/META-INF/persistence.xml"
    	at org.jboss.as.jpa.processor.PersistenceUnitParseProcessor.parse(PersistenceUnitParseProcessor.java:222)
    	at org.jboss.as.jpa.processor.PersistenceUnitParseProcessor.handleJarDeployment(PersistenceUnitParseProcessor.java:100)
    	at org.jboss.as.jpa.processor.PersistenceUnitParseProcessor.deploy(PersistenceUnitParseProcessor.java:84)
    	at org.jboss.as.server.deployment.DeploymentUnitPhaseService.start(DeploymentUnitPhaseService.java:113) [jboss-as-server-7.1.1.Final.jar:7.1.1.Final]
    	... 5 more
    Caused by: com.ctc.wstx.exc.WstxParsingException: Received non-all-whitespace CHARACTERS or CDATA event in nextTag().
     at [row,col {unknown-source}]: [13,54]
    	at com.ctc.wstx.sr.StreamScanner.constructWfcException(StreamScanner.java:606)
    	at com.ctc.wstx.sr.StreamScanner.throwParseError(StreamScanner.java:479)
    	at com.ctc.wstx.sr.StreamScanner.throwParseError(StreamScanner.java:464)
    	at com.ctc.wstx.sr.BasicStreamReader.nextTag(BasicStreamReader.java:1137)
    	at org.jboss.as.jpa.puparser.PersistenceUnitXmlParser.parseProperties(PersistenceUnitXmlParser.java:293)
    	at org.jboss.as.jpa.puparser.PersistenceUnitXmlParser.parsePU(PersistenceUnitXmlParser.java:232)
    	at org.jboss.as.jpa.puparser.PersistenceUnitXmlParser.parse(PersistenceUnitXmlParser.java:122)
    	at org.jboss.as.jpa.processor.PersistenceUnitParseProcessor.parse(PersistenceUnitParseProcessor.java:217)
    	... 8 more
    J'ai tenté de mettre le persistence.xml au niveau du meta-inf de l'ear, mais ce n'est pas mieux.
    La tête de mon persistence.xml

    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
    <?xml version="1.0" encoding="UTF-8"?>
    <persistence>
    	<persistence-unit name="manager1" transaction-type="RESOURCE_LOCAL">
    		<class>com.ik.ejb.entity.user.UserEntity</class>
    		<properties>
    			<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
    			<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
    			<property name="hibernate.connection.username" value="sa" />
    			<property name="hibernate.connection.password" value="" />
    			<property name="hibernate.connection.url" value="jdbc:hsqldb:file:database/ikDataBase" />
    			<property name="hibernate.max_fetch_depth" value="3" />
    			<property name="hibernate.hbm2ddl.auto" value="update" />
    			<property name="hibernate.connection.shutdown">true</property>
    		</properties>
    	</persistence-unit>
    </persistence>
    Si quelqu'un voit le hic...

    Deuxièment, je suis parti sur mon idée, des dao et des ejb dans un projet ejb. A présent, je voudrais appeler mes ejb au niveau de mes actions struts 2. Si quelqu'un a un bout de code approchant sachant que j'utilise jboss 7.1, ejb 3.1

    Merki

  3. #3
    Membre du Club
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 36
    Points : 59
    Points
    59
    Par défaut
    Pour ton erreur : j'ai un doute, mais la dernière propriété de ton persistence.xml me parait anormale. Ce devrait être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <property name="hibernate.connection.shutdown" value="true" />
    (valeur en attribut, et non comme contenu de la balise).

    De manière plus générale, sur tes questions d'archi : oublie l'idée de séparer entités et objets métier. Rajoute tes annotations directement, et basta. S'il commence à y avoir trop de code métier sur tes objets et que la classe devient trop longue, tu pourras toujours le scinder en deux : faire une super-classe abstraite avec juste les données et les annotations JPA, et une classe fille (qui sera celle référencée partout dans l'appli) avec le code métier. Honnêtement, j'ai rarement ressenti le besoin de le faire. En séparant entity et objet métier dès le début, tout ce que tu gagnes c'est une méthode inutile pour copier-coller le contenu de l'une dans l'autre. C'est essentiellement un vieil héritage de l'époque des EJB Entity de J2EE 1.4 où tu n'avais pas le choix (point de détail : on JEE 5, on dit Entity, pas EJB Entity).

    Pareil pour la couche de Service : est-ce qu'il y a vraiment un besoin ? Ç'a été une mode pendant longtemps, de multplier les couches superposées, et ça n'a jamais réussi à empêcher que les problématiques d'une couche remontent à celle du dessus (par contre, pour s'assurer que la moindre évolution fonctionnelle demande trois fois plus de changements, ça marche nickel).

    Dernier point : ton DAO contient quoi ? Si tu utilises l'EntityManager, tu peux te contenter d'un DAO générique pour toutes tes classes pour les méthodes CRUD, et n'avoir de classes spécifiques que pour les requêtes un peu plus élaborées (recherches ou mises à jour en masse).

    Bref : fais simple.

  4. #4
    Membre habitué
    Inscrit en
    Septembre 2008
    Messages
    261
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 261
    Points : 164
    Points
    164
    Par défaut
    Salut et merci.
    Exact le problème venait bien de cette balise. La propriété value est intégrée à la balise. Je l’avais corrigé un peu plus tôt. J’ai aussi mis une référence au xsd.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <?xml version="1.0" encoding="UTF-8"?>
    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
       http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
       version="1.0">

    En ce qui concerne les classes, tu as raison, autant se passer du pojo puisque l’entity fait le "même" job. Si j'en éprouve le besoin, je partirai sur ton idée d'abstraction.

    Ouais pour les services, je ne pense pas en avoir l'utilité pour l'instant. Mais ca serait histoire de pas taper directement sur l'ejb. Est ce que cela a un sens ? J'en sais rien. J'avais bossé sur un projet scindé un peu comme cela. Donc il y a peut être l'envie de repomper un truc de ce côté inconsciemment.

    Mes DAO seront scindés par "service", et reprendront donc les méthodes CRUD standards, plus quelques méthodes un peu plus tordues..., enfin complexes
    Ouais j'essaierai sans doute d'adopter ton approche. J'avais aussi l'idée d'une factory.

    Mais bon pour l'instant, je suis parti dans l'idée de faire un test avec un select, de traverser les différentes couches. En ressort l'inutilité du pojo qui fait doublons avec l'Entity.

    Je bute sur l'injection de l'ejb au niveau de l'action. J'ai vu que le lookup n'était pas tout à fait standard avec JBoss 7. Il y a aussi un plugin ejb3struts2.

    Mais enfin, si quelqu'un a un appel ejb 3 dans une action struts 2, je prends.

    Merci

  5. #5
    Membre habitué
    Inscrit en
    Septembre 2008
    Messages
    261
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 261
    Points : 164
    Points
    164
    Par défaut
    Je n'arrive pas à taper dans mon ejb. Je l'ai fait de deux façons. Alors ci-dessous, ma classe
    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
    /**
     * Session Bean implementation class UserBean
     */
    @Stateless(mappedName = "UserBean")
    @LocalBean
    public class UserBean implements UserRemote, UserLocal {
     
        /**
         * Default constructor. 
         */
        public UserBean() {
            // TODO Auto-generated constructor stub
        }
     
    	/**
             * @see com.iwk.ejb.session.user.UserRemote#login(java.lang.String, java.lang.String)
             * @param email
             * @param password
             * return an UserEntity if exist or null
             */
    	@Override
    	public UserEntity login(String email, String password) {
    		UserDao myUserDao = new UserDaoImpl();
    		return myUserDao.login(email, password);
    	}
     
    }
    et mes interfaces
    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
    import javax.ejb.Remote;
     
    import com.iwk.ejb.entity.user.UserEntity;
     
    @Remote
    public interface UserRemote {
     
    	/** 
             * @see com.iwk.ejb.session.user.UserRemote#login(java.lang.String, java.lang.String)
             * @param email
             * @param password
             * return an UserEntity if exist or null
             */
    	public UserEntity login (String email, String password);
     
    }
    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
    mport javax.ejb.Local;
     
    import com.iwk.ejb.entity.user.UserEntity;
     
    @Local
    public interface UserLocal {
     
    	/**
             * @see com.iwk.ejb.session.user.UserRemote#login(java.lang.String, java.lang.String)
             * @param email
             * @param password
             * return an UserEntity if exist or null
             */
    	public UserEntity login (String email, String password);
     
    }
    On en arrive à l'action, sachant que j'ai tenté 2 trucs différents :

    1 -
    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
    		final Hashtable jndiProperties = new Hashtable();
    		jndiProperties.put(Context.URL_PKG_PREFIXES,
    		"org.jboss.ejb.client.naming");
    		final Context context = new InitialContext(jndiProperties);
    
    		final String appName = "";
    
    		final String moduleName = "iWBO";
    		// THIS IS THE NAME OF THE JAR WITH YOUR EJBs. Write its name here, without the .jar.
    
    		final String distinctName = "";
    		//&nbsp;&nbsp; &nbsp;AS7 allows deployments to have an distinct name. If you don't use this feature, let this field empty.
    
    		final String beanName = UserBean.class.getSimpleName();
    		System.out.println("beanName : " + beanName);
    		//EJB CLASS WITH THE IMPLEMENTATION (simple name)
    
    		final String viewClassName = UserRemote.class.getName();
    		// FULLY QUALIFIED NAME OF THE REMOTE CLASS (interface).
    
    		UserRemote bean = (UserRemote) context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);
    
    		
    		bean.login("email", "password");
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1234567891011121314151617
    
    avec au niveau du build path du projet web, jboss-ejb-client.properties
    
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    12345678
     
    remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
     
    remote.connections=default
     
    remote.connection.default.host=localhost
    remote.connection.default.port = 4447
    remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
    Cela me remonte :
    javax.naming.NameNotFoundException: UserBean/local -- service jboss.naming.context.java.UserBean.local org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:97) org.jboss.as.naming.NamingContext.lookup(NamingContext.java:178) org.jboss.as.naming.InitialContext.lookup(InitialContext.java:113) org.jboss.as.naming.NamingContext.lookup(NamingContext.java:214) javax.naming.InitialContext.lookup(Unknown Source)

    et 2 -
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	@InjectEJB(name="UserBean")
    	private UserBean scl;
     
    ...
    		scl.login("email", "password");
    (suppose l'ajout de struts2ejb3-jboss-plugin-0.0.4.jar)

    qui remonte également
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    javax.naming.NameNotFoundException: UserBean/local -- service jboss.naming.context.java.UserBean.local
    	org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:97)
    	org.jboss.as.naming.NamingContext.lookup(NamingContext.java:178)
    	org.jboss.as.naming.InitialContext.lookup(InitialContext.java:113)
    	org.jboss.as.naming.NamingContext.lookup(NamingContext.java:214)
    	javax.naming.InitialContext.lookup(Unknown Source)
    Voilà
    Si quelqu'un peut m'expliquer ou est le probleme, quel devrait etre le nom, et sur quoi se base t il ?

  6. #6
    Membre habitué
    Inscrit en
    Septembre 2008
    Messages
    261
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 261
    Points : 164
    Points
    164
    Par défaut
    problème de path. En le mettant en dur, cela passe en faisant un look up. Donc reste à voir comment récupérer l'équivalent de façon dynamique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    		Context context = new InitialContext();
    		String a = "java:jboss/exported/iWkEAR/iWkBO/UserBean!com.iwk.ejb.session.user.UserRemote";
     
            UserRemote beanRemote = (UserRemote)context.lookup(a);
     
            beanRemote.login("email", "password");

  7. #7
    Membre du Club
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 36
    Points : 59
    Points
    59
    Par défaut
    Déjà, il y a un truc pas cohérent au niveau de ton EJB :
    - il porte l'annotation @LocalBean, ce qui signifie que tu l'utilises sans interface ;
    - tu l'a fait implémenter deux interfaces, une @Local et une @Remote, sans les lui affecter par annotation, et du coup elles ne servent à rien ;
    - sauf cas particulier, ton interface Local devrait hériter de la Remote (tu peux généralement faire en local toutes les opérations que tu peux faire à distance, et ça évite de se répéter).

    Donc : soit tu fais sauter tes interfaces, soit tu remplace @LocalBean par @Remote(UserRemote.class) et @Local(UserLocal.class). En fait, avec le paramétrage actuel, je suis un peu surpris que ton dernier exemple marche.

    Pour ton problème : le paramètre mappedName sur @Stateless a un fonctionnement spécifique à chaque serveur d'applications => à éviter. Je n'ai jamais utilisé Struts 2 donc je vais peut-être dire une bêtise, mais si tu te contentes de @EJB ou @Inject (sans aucun paramètre) sur ton attribut UserBean, ça ne marche pas ?

  8. #8
    Membre habitué
    Inscrit en
    Septembre 2008
    Messages
    261
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 261
    Points : 164
    Points
    164
    Par défaut
    J'ai modifié le code dans ton sens,

    L'interface local étend l'interface remote. Quant au bean, j'ai fait sauter les implementations au profit d'annotation.

    Par contre dans mon action, quand j'utilise @EJB ou @Inject, j'ai un nullPointerException, d'ou le plugin struts 2 ejb3 plugin. A ce que j'ai lu, le @EJB
    marche niveau servlet, et pas dans une action de type struts 2, d'ou ce plugin : http://code.google.com/p/struts2ejb3-jboss-plugin/
    qui pour l'instant ne fait quand meme pas l'affaire : nameNotFoundExcepeiont

    Je regarderai cela d'un peu plus près.

  9. #9
    Membre du Club
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 36
    Points : 59
    Points
    59
    Par défaut
    Citation Envoyé par ifsera Voir le message
    Quant au bean, j'ai fait sauter les implementations au profit d'annotation.
    Uh ? Fait pas sauter le "implements Machin" hein, c'est une excellente chose (si tu gardes le principe d'avoir une interface Local et une Remote).

    Pour ce qui est de l'injection, j'avoue ne pas avoir d'autres idées.

  10. #10
    Membre confirmé
    Avatar de Khaled.Noordin
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 354
    Points : 497
    Points
    497
    Billets dans le blog
    1
    Par défaut
    salut,
    comme tu as deux implémentations possibles, local ou remote, un moment faut dire au container quoi injecter et ou sur les candidats à l'injection, t'as le choix entre la vielle méthode avec un ejb-jar.xml, ou sinon tu utilise CDI avec configuration par annotation, du coup tu n'aura plus à utiliser d'annotations @Ejb @local @remote, mais juste des @inject (pour les interfaces ou injecter une implémentation) @Named(pour les contrôleurs de vue typiquement des pojo jsf)
    je te conseil de te balader sur ce blog http://blog.alexis-hassler.com/
    je te conseil pas trop struts2 mais plus jsf2, c'est le standard il a plus de doc de composants et une plus grande communauté

  11. #11
    Membre habitué
    Inscrit en
    Septembre 2008
    Messages
    261
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 261
    Points : 164
    Points
    164
    Par défaut
    Ok merci Khaled.

    Je vais regarder de ce côté, du blog. Après pour jsf, je connais un peu. Mais je préfère rester sur du struts 2 (j'ai pas mal avançé ). J'ai implémenté le truc avec tiles. Même si je sais qu'il y a l'équivalent côté facelet, je suis moyennement chaud.

    Je regarderai ce qu'il y a sur le net histoire de me faire une idée.

  12. #12
    Membre du Club
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2007
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Juillet 2007
    Messages : 36
    Points : 59
    Points
    59
    Par défaut
    Euh non, il n'a qu'une seule implémentation. Local et Remote, ce sont les interfaces. Le conteneur est parfaitement capable de déterminer s'il doit utiliser un proxy local ou distant selon le type déclaré, et l'implémentation derrière sera toujours la même.

    Pour CDI : attention, il y a des différences subtiles entre injecter un EJB avec @EJB et avec @Inject. Dans le doute, je conseille plutôt d'injecter avec @EJB. A noter que CDI n'est disponible qu'en JEE 6 (vu que ifsera utilise @LocalBean, ce doit être son cas), et que dans ce cas-là on peut également injecter des @EJB par annotations en utilisant les noms JNDI standardisés (sans utiliser mappedName ni ejb-jar.xml, donc).

    Quoi qu'il en soit, dans son cas, ça ne va probablement pas marcher non plus avec CDI : si ses actions Struts 2 ne sont pas des objets managés par le conteneur, ni @Inject ni @EJB ne fonctionneront (du moins, pas sans l'ajout de bibliothèques extérieures).

    Sur JSF 2 , j'avoue, il a également ma préférence. Il s'intègre parfaitement avec les autres composants de JEE 6, contrairement à Struts 2 (visiblement ). Mais si ifsera est déjà bien avancé sur Struts 2, changer de framework n'est pas forcément la solution la plus économique.

  13. #13
    Membre confirmé
    Avatar de Khaled.Noordin
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 354
    Points : 497
    Points
    497
    Billets dans le blog
    1
    Par défaut
    Salut a tous,
    merci de ta participation Boojum,
    @ifsera
    Struts2 n'est pas a jeter a la poubelle c'est un bon framework et vue que tu as l'air plus a l'aise avec je comprend ton envie d'y rester, en l'occurrence le problème n'est pas dans la partie Struts mais bien dans l'injection de DAO/services dans tes contrôleurs.
    Pourrais tu me préciser dans quel serveur d'application ton application tourne et sa version?

    En regardant ton code et ta facon d'injecter un ejb dans un controlleur, bon bah c'est pas ça essaye un truc plutot de ce genre la
    Code java : 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
    import com.opensymphony.xwork2.ActionSupport;
    import javax.ejb.EJB;
     
    public class UserBean extends ActionSupport {
     
        @EJB
        private IUserDao userDao 
     
        public UserBean() {
        }
     
     
        @Override
        public UserEntity login(String email, String password) {
            return myUserDao.login(email, password);
        }
    }
    je me souvient plus trop de la gestion du scope d'une action avec struts mais bon voila comment injecter un ejb en sachant UserDao est la classe concrète qui implémente IUserDao, si tu n'a que une implémentation qui est local ne t’embarrasse pas du mécanisme des interfaces et met l'annotation @Ejb sur une classe concrète

    petite remarque pour donner a manger au troll, a mon gout spring se marrie mieux avec struts que les ejb, mais bon la n'est pas le sujet

  14. #14
    Membre habitué
    Inscrit en
    Septembre 2008
    Messages
    261
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 261
    Points : 164
    Points
    164
    Par défaut
    @Khaled.Noordin
    Pour le conteneur, il s'agit de jboss AS 7.1
    Je voulais jouer un peu avec les dernières releases

    En suivant ta méthode, j'obtiens un NullPointerException. L'annotation @EJB ne prend pas à première vue.

    Du coup, je garde le lookup pour l'instant, et vais me pencher quand j'aurais un moment vers struts2ejb3plugin et guice.


    @Boojum
    On arrive à la même conclusion
    @EJB et @InjectEjb ne marchent pas dans une action Struts 2.
    Et oui, je suis sous JEE 6

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

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Points : 495
    Points
    495
    Par défaut
    Citation Envoyé par ifsera Voir le message
    @Boojum
    On arrive à la même conclusion
    @EJB et @InjectEjb ne marchent pas dans une action Struts 2.
    Et oui, je suis sous JEE 6
    Il existe déjà un plugin cdi pour Struts 2, il te suffit d'avoir le jar dans le classpath et si cdi est bien activé sur ton projet (en ajoutant un fichier beans.xml même vide dans ton WEB-INF), tu devrais pouvoir faire des injections d'ejb (par @EJB ou @Inject) dans tes actions Struts2 sans aucun problème. Aucune autre config à faire.

  16. #16
    Membre habitué
    Inscrit en
    Septembre 2008
    Messages
    261
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 261
    Points : 164
    Points
    164
    Par défaut
    @manblaizo
    J'ai commencé à regarder. Si j'ai pas pû avant
    Autre chose à faire...

    J'ai testé, mas j'ai un petit souci.

    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
     
     
    root cause 
     
    com.opensymphony.xwork2.inject.ContainerImpl$MissingDependencyException: No mapping found for dependency [type=com.iwk.ejb.session.user.UserBean, name='default'] in com.iwk.ejb.session.user.UserBean com.iwk.action.login.LoginAction.myUserBean.
    	com.opensymphony.xwork2.inject.ContainerImpl$FieldInjector.<init>(ContainerImpl.java:187)
    	com.opensymphony.xwork2.inject.ContainerImpl$4.create(ContainerImpl.java:128)
    	com.opensymphony.xwork2.inject.ContainerImpl$4.create(ContainerImpl.java:125)
    	com.opensymphony.xwork2.inject.ContainerImpl.addInjectorsForMembers(ContainerImpl.java:141)
    	com.opensymphony.xwork2.inject.ContainerImpl.addInjectorsForFields(ContainerImpl.java:124)
    	com.opensymphony.xwork2.inject.ContainerImpl.addInjectors(ContainerImpl.java:89)
    	com.opensymphony.xwork2.inject.ContainerImpl$1.create(ContainerImpl.java:71)
    	com.opensymphony.xwork2.inject.ContainerImpl$1.create(ContainerImpl.java:67)
    	com.opensymphony.xwork2.inject.util.ReferenceCache$CallableCreate.call(ReferenceCache.java:150)
    	java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
    	java.util.concurrent.FutureTask.run(Unknown Source)
    	com.opensymphony.xwork2.inject.util.ReferenceCache.internalCreate(ReferenceCache.java:76)
    	com.opensymphony.xwork2.inject.util.ReferenceCache.get(ReferenceCache.java:116)
    	com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:490)
    	com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:530)
    	com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:528)
    	com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:580)
    	com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:528)
    	com.opensymphony.xwork2.ObjectFactory.injectInternalBeans(ObjectFactory.java:139)
    	org.apache.struts2.cdi.CdiObjectFactory.buildBean(CdiObjectFactory.java:167)
    	com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:151)
    	com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:121)
    	com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:300)
    	com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:400)
    	com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
    	org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
    	org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
    	com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
    	org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:500)
    	org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:432)
     
     
    note The full stack trace of the root cause is available in the JBoss Web/7.0.13.Final logs.
     
     
    --------------------------------------------------------------------------------
     
    JBoss Web/7.0.13.Final
    J'ai crée un beans.xml vide au niveau du WEF-INF de mon projet web. A propos, si je voulais ne pas le laisser vide, je mettrais quoi dedans ?

    le struts.xml comme suit
    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
     
    <?xml version="1.0" encoding="UTF-8"?>
     
    <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
     
    <struts>
    	<!-- internationalisation -->
    	<constant name="struts.custom.i18n.resources" value="resources.messages,resources.global" />
     
    	<!-- 	struts cdi plugin   -->
    	<constant name="struts.objectFactory.cdi.jndiKey" value="java:comp/some/weird/BeanManagerReference" /> 
     
     
    	<package name="default" extends="struts-default">
    		<result-types>
    			<result-type name="tiles"
    				class="org.apache.struts2.views.tiles.TilesResult" />
    		</result-types>
     
    		<!-- ACTIONS -->
     
    		<!-- action lançée au démarrage de l'application - redirection de l'index 
    			vers la home -->
    		<action name="*Home" method="{1}" class="com.iwk.action.login.LoginAction">
    			<result name="welcome" type="tiles">welcome</result>
    		</action>
     
     
    		<!-- 	liaison name et forward 	-->
    		<action name="login" method="login"
    			class="com.iwk.action.login.LoginAction">
    			<result name="failedIdentification" type="tiles">failedIdentification</result>
    			<result name="connect" type="tiles">connect</result>
    		</action>
     
    		<!-- ...  ... -->
     
    	</package>
     
    </struts>
    ma classe action
    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
     
    package com.iwk.action.login;
     
    import java.util.ArrayList;
     
    import org.apache.log4j.Logger;
     
    import com.iwk.ejb.session.user.UserBean;
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.inject.Inject;
     
    public class LoginAction extends ActionSupport/* implements ServletContextAware*/{
     
    	private ArrayList<String> listOfCountries = null;
    	private static final long serialVersionUID = -2613425890762568273L;
    	private static Logger logger = Logger.getLogger(LoginAction.class);
     
     
    	@Inject 
        UserBean myUserBean;
     
    	public String login (){
    	if (myUserBean == null) {
    			System.out.println(" ##  ##  ##  ##  ##  ##  NULL  ##  ##  ##");
    		}else{
    		myUserBean.login("firstanme", "lastname");
    		}
    		System.out.println("   PASSES BIEN DANS LOGIN ACTION   -   PASSES BIEN DANS LOGIN ACTION   ");
    		return "connect";
    	}
     
    	//...
     
     
    }
    l'interface remote de mon ejb
    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
     
    package com.iwk.ejb.session.user;
     
    import javax.ejb.Remote;
     
    import com.iwk.ejb.entity.user.UserEntity;
     
    @Remote
    public interface UserRemote {
     
    	/** 
             * @see com.iwk.ejb.session.user.UserRemote#login(java.lang.String, java.lang.String)
             * @param email
             * @param password
             * return an UserEntity if exist or null
             */
    	public UserEntity login (String email, String password);
     
    }
    et enfin l'implémentation
    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
     
    package com.iwk.ejb.session.user;
     
    import java.io.Serializable;
     
    import javax.ejb.Remote;
    import javax.ejb.Stateless;
     
    import com.iwk.dao.User.UserDao;
    import com.iwk.dao.User.UserDaoImpl;
    import com.iwk.ejb.entity.user.UserEntity;
     
    /**
     * Session Bean implementation class UserBean
     */
    @Remote(UserRemote.class)
    @Stateless
    public class UserBean implements Serializable{
     
        /**
         * Default constructor. 
         */
        public UserBean() {
            // TODO Auto-generated constructor stub
        }
     
    	/**
             * @see com.iwk.ejb.session.user.UserRemote#login(java.lang.String, java.lang.String)
             * @param email
             * @param password
             * return an UserEntity if exist or null
             */
    	public UserEntity login(String email, String password) {
    		System.out.println(email + "  -  au niveau de userbean -  " + password);
    		UserDao myUserDao = new UserDaoImpl();
    		return myUserDao.login(email, password);
    	}
     
    }
    et j'ai enfin ajouté 2 jars au build-path:
    cdi-api-1.0.jar et struts2-cdi-plugin-2.3.3.jar

    Mais je saisis pas l'histoire du mapping, où elle se ferait ?

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

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Points : 495
    Points
    495
    Par défaut
    Bonjour,

    Je pourrais répondre à tes questions sur CDI et autres beans.xml plus tard (beaucoup de boulot en ce moment...), mais juste pour te débloquer rapidement, en gros, ton application étant une application Web, avec EJBs déployés dans un WAR, ces EJBs ne peuvent avoir que des interfaces locales (ou pas d'interface du tout, le fameux no-interface view).

    Donc le code serait:

    pour l'interface ejb:
    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
     
    package com.iwk.ejb.session.user;
     
    import javax.ejb.Local;
     
    import com.iwk.ejb.entity.user.UserEntity;
     
    @Local
    public interface UserLocal {
     
    	/** 
             * @see com.iwk.ejb.session.user.UserLocal#login(java.lang.String, java.lang.String)
             * @param email
             * @param password
             * return an UserEntity if exist or null
             */
    	public UserEntity login (String email, String password);
     
    }
    pour l'implémentation ejb:
    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
     
    package com.iwk.ejb.session.user;
     
    import javax.ejb.Stateless;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
     
    import com.iwk.ejb.entity.user.UserEntity;
     
    /**
     * Session Bean implementation class UserBean
     */
    @Stateless
    public class UserBean implements UserLocal {
     
        @PersistenceContext
        private EntityManager em;
     
        /**
         * Default constructor. 
         */
        public UserBean() {
            // TODO Auto-generated constructor stub
        }
     
    	/**
             * @see com.iwk.ejb.session.user.UserLocal#login(java.lang.String, java.lang.String)
             * @param email
             * @param password
             * return an UserEntity if exist or null
             */
    	public UserEntity login(String email, String password) {
                    List<UserEntity> users = em.createQuery("select u from UserEntity u where u.email = :email and u.password = :password", UserEntity.class)
                                   .setParameter("email", email)
                                   .setParameter("password", password)
                                   .getResultList();
     
                    UserEntity result = null;
     
                    if (!users.isEmpty()) {
                        result = users.get(0);
                    }
     
    		return result;
    	}
     
    }
    J'ai ici réécrit un peu l'implémentation, ne sachant pas trop ce qu'il y a dans ton UserDao / UserDaoImpl...

    Et ensuite pour l'action struts2:
    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
     
    package com.iwk.action.login;
     
    import java.util.ArrayList;
     
    import org.apache.log4j.Logger;
     
    import com.iwk.ejb.session.user.UserLocal;
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.inject.Inject;
     
    public class LoginAction extends ActionSupport/* implements ServletContextAware*/{
     
    	private ArrayList<String> listOfCountries = null;
    	private static final long serialVersionUID = -2613425890762568273L;
    	private static Logger logger = Logger.getLogger(LoginAction.class);
     
     
    	@Inject UserLocal myUserBean;
     
    	public String login (){
    	if (myUserBean == null) {
    			System.out.println(" ##  ##  ##  ##  ##  ##  NULL  ##  ##  ##");
    		}else{
    		myUserBean.login("firstanme", "lastname");
    		}
    		System.out.println("   PASSES BIEN DANS LOGIN ACTION   -   PASSES BIEN DANS LOGIN ACTION   ");
    		return "connect";
    	}
     
    	//...
     
     
    }
    Voilà, si je n'ai rien oublié, je crois que ceci devrait te débloquer.

  18. #18
    Membre habitué
    Inscrit en
    Septembre 2008
    Messages
    261
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 261
    Points : 164
    Points
    164
    Par défaut
    Citation Envoyé par manblaizo Voir le message
    Bonjour,

    Je pourrais répondre à tes questions sur CDI et autres beans.xml plus tard (beaucoup de boulot en ce moment...),
    .
    Tracasses. C'est déjà cool d'avoir une piste. Et je suis aussi sur un truc en parallèle en ce moment. J'ai testé rapidement, et je remonte toujours le même souci de config :

    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
     
    root cause 
     
    com.opensymphony.xwork2.inject.ContainerImpl$MissingDependencyException: No mapping found for dependency [type=com.iwk.ejb.session.user.UserLocal, name='default'] in com.iwk.ejb.session.user.UserLocal com.iwk.action.login.LoginAction.myUserBean.
    	com.opensymphony.xwork2.inject.ContainerImpl$FieldInjector.<init>(ContainerImpl.java:187)
    	com.opensymphony.xwork2.inject.ContainerImpl$4.create(ContainerImpl.java:128)
    	com.opensymphony.xwork2.inject.ContainerImpl$4.create(ContainerImpl.java:125)
    	com.opensymphony.xwork2.inject.ContainerImpl.addInjectorsForMembers(ContainerImpl.java:141)
    	com.opensymphony.xwork2.inject.ContainerImpl.addInjectorsForFields(ContainerImpl.java:124)
    	com.opensymphony.xwork2.inject.ContainerImpl.addInjectors(ContainerImpl.java:89)
    	com.opensymphony.xwork2.inject.ContainerImpl$1.create(ContainerImpl.java:71)
    	com.opensymphony.xwork2.inject.ContainerImpl$1.create(ContainerImpl.java:67)
    	com.opensymphony.xwork2.inject.util.ReferenceCache$CallableCreate.call(ReferenceCache.java:150)
    	java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
    	java.util.concurrent.FutureTask.run(Unknown Source)
    	com.opensymphony.xwork2.inject.util.ReferenceCache.internalCreate(ReferenceCache.java:76)
    	com.opensymphony.xwork2.inject.util.ReferenceCache.get(ReferenceCache.java:116)
    	com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:490)
    	com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:530)
    	com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:528)
    	com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:580)
    	com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:528)
    	com.opensymphony.xwork2.ObjectFactory.injectInternalBeans(ObjectFactory.java:139)
    	org.apache.struts2.cdi.CdiObjectFactory.buildBean(CdiObjectFactory.java:167)
    	com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:151)
    	com.opensymphony.xwork2.ObjectFactory.buildAction(ObjectFactory.java:121)
    	com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:300)
    	com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:400)
    	com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:194)
    	org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
    	org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:39)
    	com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
    	org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:500)
    	org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:432)
    Je vais chercher un peu
    Après je sais pas si le fait que je sois sur jboss 7.1 a une incidence. J'ai vu quelques posts. Je te tiens au courant quand je remonte quelque chose de concluant.

  19. #19
    Membre habitué
    Inscrit en
    Septembre 2008
    Messages
    261
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 261
    Points : 164
    Points
    164
    Par défaut
    Ca le fait. Merci.

    J'avais le mauvais import côté inject http://struts.apache.org/2.3.3/docs/cdi-plugin.html

    C'était précisé. J'ai squeezé.

    Par contre, je te laisse quelques questions en suspens, pour quand t'auras un moment.

    ton application étant une application Web, avec EJBs déployés dans un WAR, ces EJBs ne peuvent avoir que des interfaces locales (ou pas d'interface du tout, le fameux no-interface view).
    Dans l'idéal, il me faudrait un projet ejb indépendant, dans lequel je pourrais taper. Ca serait plus cohérent dans une idée de distribution et d'indépendance?

    Du coup, cdi est toujours OK, ou le lookup est mieux? Globalement, c'est quoi l'avantage de l'un et de l'autre?

    Je sais pas si je suis clair...

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

    Informations forums :
    Inscription : Janvier 2006
    Messages : 365
    Points : 495
    Points
    495
    Par défaut
    Hmmm, bizarre...

    ça ne m'a pas l'air d'être une erreur d'injection cdi, mais bon

    note The full stack trace of the root cause is available in the JBoss Web/7.0.13.Final logs.
    Est-ce qu'on peut avoir la trace complète ? ça aiderait peut-être un peu plus.

Discussions similaires

  1. Réponses: 2
    Dernier message: 31/05/2014, 16h53
  2. Choix des technologies pour site Web
    Par salvador.frederic dans le forum Débuter
    Réponses: 18
    Dernier message: 27/06/2013, 22h33
  3. Quel langage est le mieux adapté pour un projet web ?
    Par aztec dans le forum Général Conception Web
    Réponses: 2
    Dernier message: 03/09/2006, 18h34
  4. Déploiement d'un état crystal report pour un projet web
    Par ddii dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 07/08/2006, 12h03
  5. Choix de technologies pour mon application
    Par Franco dans le forum Java EE
    Réponses: 5
    Dernier message: 21/10/2003, 15h10

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