Comment devrait être EJB Stateless Session Bean correctement injecté dans le module web?
Être complètement nouveau pour Java EE (mais pas de Java lui-même), je suis en train de construire un très simple "Application d'Entreprise" avec mise en veille prolongée en tant que fournisseur JPA et JSF que le framework d'INTERFACE. Pour ce faire j'utilise NetBeans 7 avec GlassFish 3.1.
{ApplicationName}-ejb:
Que j'ai accompli pour générer les classes d'entité à partir de la base de données et local sesssion haricots pour ces entités. Beans.xml est en place.
@Stateless
public class QuestFacade extends AbstractFacade<Quest> implements QuestFacadeLocal {
//some methods here as well as EntityManager injection ...
}
{ApplicationName}-guerre:
J'ai créé un simple POJO comme un backing bean pour le JSF page. J'ai annoté avec javax.inject.@Named
et javax.enterprise.context.@SessionScoped
. Ce backing bean est maintenant accessible à partir de la page JSF ainsi que l'injection lorsque la page est accessible. Beans.xml est en place ainsi.
@Named
@SessionScoped
public class QuestBean implements Serializable {
@EJB
protected QuestFacade questFacade;
//several methods delegating lookups to the questFacade ...
}
Avoir cette déployés et les pages consultées, le je suis, cependant, obtenir une erreur de GlassFish que le QuestFacade
ne peut pas être recherché par le JNDI.
La stacktrace est un peu long mais la cause initiale pourrait être suffisant:
Caused by: javax.naming.NamingException: Lookup failed for 'model.session.QuestFacade#model.session.QuestFacade' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: model.session.QuestFacade#model.session.QuestFacade not found]
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at javax.naming.InitialContext.lookup(InitialContext.java:392)
at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:173)
... 74 more
Caused by: javax.naming.NameNotFoundException: model.session.QuestFacade#model.session.QuestFacade not found
at com.sun.enterprise.naming.impl.TransientContext.doLookup(TransientContext.java:248)
at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:215)
at com.sun.enterprise.naming.impl.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:77)
at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:119)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:505)
... 78 more
Je comprends que je suis persuader GlassFish pour injecter un EJB à partir d'un autre module au sein de la même application. Si le @Remote
interface être utilisé à la place? J'ai aussi essayé de spécifier explicitement le nom à la fois @Stateless
et @EJB
annotation, mais sans succès.
Je crois que je suis en train de faire quelque chose de fondamentalement mauvais, mais je ne trouve pas quoi.
Toute suggestion ou serait grandement apprécié!
OriginalL'auteur merxbj | 2011-06-08
Vous devez vous connecter pour publier un commentaire.
Ce que vous faites mal, c'est que si vous mettez en œuvre une interface métier (
@Local
ou@Remote
), vous devez déclarer la variable où l'injection a lieu comme ayant le type de l'interface, pas de la véritable classe d'haricot.Donc dans votre cas:
Toutefois, une entreprise de l'interface n'est pas nécessaire dans EJB lorsque vous êtes en train de faire locaux (jvm) de la communication. Comme vous l'avez découvert, si vous ne spécifiez pas une entreprise d'interface à tous pour votre EJB, vous pouvez injecter de la fève de classe elle-même. C'est ensuite parce que vous obtenez automatiquement la soi-disant
no-interface view
.Si vous le souhaitez, vous pouvez déclarer que vous souhaitez à la FOIS la vue locale et de la non-vue de l'interface. De cette façon, vous pouvez injecter votre classe d'haricot dans des endroits que soit le type de bean lui-même est déclaré ou son interface métier. Pour cela, vous utilisez le
@LocalBean
.Injection peut donc se faire de deux façons maintenant:
Dans la pratique, je n'ai pas trouvé beaucoup d'utilisation pour avoir les deux méthodes disponibles dans le même temps, mais peut-être que cela ajoute à votre compréhension.
OriginalL'auteur Arjan Tijms
Apparemment, le problème est que j'ai généré
@Local
beans de session. Par ce tutoriel il n'est plus nécessaire (?) pour spécifier le@Local
ou@Remote
interface. J'ai pas encore tout à fait comprendre le problème.J'Espère que cette réponse pourrait potentiellement sauver un peu de temps pour quelqu'un 🙂
Jarda
OriginalL'auteur merxbj