8
votes

Injecter une ejb dans un servlet mappé dynamique

J'ai un filtre où je suis dinamiquement mappage de classes de servlet: xxx pré>

puis lorsque j'accumule une cartographie donnée, l'EJB n'est pas injecté. P>

...

@Override
    public void contextInitialized( ServletContextEvent sce ) {
        ServletContext servletContext = sce.getServletContext();

        FileSystemInspector fileInspector = new FileSystemInspector();
        Set<ActionInfoData> actions = fileInspector.getActions( getConventionDirectory() );

        for ( ActionInfoData action : actions ) {
            servletContext
                .addServlet( action.getServletName(), action.getClassName() )
                .addMapping( action.getServletMapping() );
        }
    }

...


0 commentaires

3 Réponses :


0
votes

Premier, dans mon test, cela a fonctionné bien à l'aide d'une version de Glassfish V3.

Mais, seconde, vous pouvez bien exécuter cette clause de la spécification de servlet 3.0.

Les méthodes suivantes sont ajoutées à servletContext depuis le servlet 3.0 à Activer la définition programmatique des servlets, des filtres et de l'URL modèle qu'ils mappent. Ces méthodes ne peuvent être appelées que pendant la initialisation de l'application soit du contextinitialisé Méthode d'une mise en œuvre d'un servletContextExtener ou de la Méthode ONSTARTUP d'une mise en œuvre de servletsContaintainerInitialisation.

notamment, ces méthodes ne peuvent pas être appelées à partir d'un filtre.Init () méthode. J'ai essayé à l'origine ceci dans un servlet () méthode, et la méthode init échoué car le contexte était déjà initialisé.

Donc, mon expérience n'a pas dupliquer votre test exactement - je n'ai pas utilisé de méthode filter.init () pour cela, plutôt je mettez le code dans un servleContextListener . Et quand je l'ai fait, mon @ejb annotation a été honoré.

EDIT:

Comme non utile comme ça sonne, je suggérerais que ceci est un bogue dans JBoss. Lorsque j'ai initialement essayé votre code d'origine avec l'injection du filtre, Glassfish a lancé une exception, car vous n'êtes pas autorisé à faire économiser l'injection où j'ai mentionné plus tôt. Maintenant peut-être que c'est une "fonctionnalité ajoutée" de JBoss, mais apparemment, le traitement d'injection @ejb ne fonctionne tout simplement pas. Selon les spécifications, cela devrait fonctionner comme annoncé.


1 commentaires

Merci pour l'homme de réponse. Malheureusement, cela n'a pas fonctionné lors du chargement via le servletContextListener. J'ai édité la question ci-dessus, vous pouvez me dire si j'ai fait quelque chose de mal.



3
votes

SPED 3.0 SPEC, sect. 4.4.3.5 forte>

Injection de ressources [E.g. @Ejb] strong> sur tous les composants (servlets, filtres et auditeurs) ajoutés programmatiquement ou créé par programme, autre que ceux ajoutés via la méthodes qui prend une instance, ne sera prise en charge que lorsque le composant est un Bean géré fort>. Pour plus de détails sur ce qui est un haricot géré s'il vous plaît se référer à la Spécification de haricots gérés définie dans le cadre de Java EE 6 et JSR 299. P>

Déclaration de haricots gérés forte> p>

Un haricot géré Java EE 6 est annoté @ javax.annotation.managedbean code> a un constructeur de no-arg. Un haricot géré JSR 299 (CDI) a simplement besoin d'un constructeur de no-arg ni d'un constructeur annoté @ javax.inject.inject code>. p>

réponse forte> p>

Pour activer l'injection de ressources, vous devez: P>

  • lieu @managedbean code> Annotation sur servlet ajouté dynamiquement p>

    ou p> li>

  • Activer CDI & Inclure un haricot vide vide.xml code> p> li> ul>


    edit strong> p>

    Même si vous créez le servlet dynamiquement, il est important que le conteneur effectue la création. Ne pensez pas que la création au sein de servleContext appuiera l'injection. Servlet doc très vague ici. p>

    avec CDI Essayez: P>

     servletContext.addServlet("your servlet name", @Inject YourServletClass servlet)
    


5 commentaires

Ok j'ai essayé le @ javax.annotation.managedbean annotation dans la classe qui étend le HTTPServillet (celui qui est carié de manière dinamique). Mon haricot n'a pas été injecté. J'ai essayé d'activer CDI en mettant un haricot vide.xml dans le répertoire Meta-Inf. N'a toujours pas été injecté lors de l'utilisation de @Inject. Aucune idée de ce qui pourrait être? Je ferai plusieurs tests avec les informations que j'ai jusqu'à présent.


Pensé que cela pourrait arriver lorsque SerbleletContext crée le servlet. Forcer le conteneur pour créer le servlet- pour CDI, appelez servletContext.addsservlet ("Votre nom de servlet", @Inject YourservletClass Servlet)


Juste pour clarifier @glenbest, "défini dans le cadre de Java EE 6 et JSR 299". JSR 299 Définit les haricots gérés, Java EE 6 définit les autres classes à l'appui d'une injection, y compris des servlets (page 69 de la spécification). Il n'est pas nécessaire de faire une étape supplémentaire pour rendre le servlet A gantbean.


Java EE 6 (JSR 318) Définit les haricots gérés de "base" ( JCP.org/ Aboutjava / CommunityProcess / final / JSR316 / Index.html ). JSR 299 définit des haricots gérés étendus. Il est nécessaire de prendre l'étape supplémentaire - la spécification de servlet dit explicitement que l'injection n'est pas prise en charge, à l'exception des haricots gérés.


La pièce manquante est vraiment d'utiliser un servlet déjà injecté pour créer les mappages dynamiques. Merci Glen



3
votes

Le problème semble lié à Ce bogue signalé qui est encore non résolu. La résolution des ressources fonctionne simplement pour les haricots gérés tels que définis par la spécification JSF, mais pas pour les haricots gérés CDI. Il suffit d'annoter simplement vos classes de servlet dynamiques avec @ javax.faces.bean.managedbean devrait résoudre le problème (oui, sa solution assez laid): xxx

Testé avec JEE6 (OFC) et JBoss 7.1.1 et 7.2.0 (EAP 6.1.0 alpha).

EDIT : Le problème avec des servlets mappés dynamiques est en fait assez profond dans la base JBoss Architecture. Ils utilisent JBossweb (une version forcée de Tomcat) comme la mise en œuvre de son servlet et dans les courages de son code de gestion contextuelle, il est déterminé à instancider d'instancier de nouveaux composants via injection ou régulière neuf . AFAIK À la date de la date, vos servlets devront être annotés de manière à être traités pour qu'ils soient traités par injection: j'avais mentionné @ Managedbean dans ma réponse originale, mais on dirait d'annoter avec @websservlet Works.


3 commentaires

Toute solution sans annoter chaque servlet? = (


@FagnerBrack - Pas que j'ai trouvé jusqu'à présent. La question que vous n'avez pas accès à la source de servlet? Ou qu'il y a simplement beaucoup d'entre eux?


En fait, je crée une convention de mappage à Dinamicaly Créer des chemins URI HTTP selon un emplacement JSP et servlet donné (système de fichiers). L'utilisation principale de la Java EE est pour la gestion de la fin de la fin. Dans ce projet, je n'utilise pas JSF en raison du caractère restrictif de celui-ci et de tirer parti de la chaudière HTML5, JQuery, EXCEPTIONJS, BOOTSTRAP (personnalisée) et toute la refroidissement de front-end, JSF n'entraînait pas. Le problème principal sur l'utilisation de l'annotation est que Je devrais l'appliquer à chaque classe à l'avenir au lieu de déléguer une telle tâche pour un processus automatique. Juste commodité.