2010-10-14 20 views
4

Cette questiong concerne Java EE 6, en utilisant glassfish v3 embedded-all.Java EE 6 - EJB conteneurs embarqués tests

J'ai un test unitaire qui utilise EJBContainer pour tester mon EJB sans état. Le problème est que je ne parviens pas à regarder l'EJB (à distance) en utilisant JNDI:

setup() { 

    ctx = EJBContainer.createEJBContainer().getContext(); 

} 

... 

test() { 

BookService bookService = (BookService)ctx.lookup("java:global/BookServiceEJB!com.something.service.BookService"); 

... 

} 

@Stateless 
public class BookServiceEJB implements BookService { 
... 
} 

@Remote 
public interface BookService { 
... 
} 

donne l'exception:

javax.naming.NamingException: Lookup failed for 'java:global/BookServiceEJB!com.something.service.BookService' in SerialContext [Root exception is javax.naming.NameNotFoundException: BookServiceEJB!com.something.service.BookService not found] 

... 

caused by: javax.naming.NameNotFoundException: BookServiceEJB!com.something.service.BookService not found 

J'ai essayé plusieurs chemins de ressources JNDI:

par exemple

java:global/BookServiceEJB 

java:global/BookService 

même:

java:global/BookShelf-1.0-SNAPSHOT/BookServiceEJB 

etc ...

nothings fonctionne

Je n'ont pas de fichiers xml déploiement configurés, seulement persistence.xml dans META-INF.

Le test utilise Maven Surefire:

mvn clean test 

Toute aide est grandement appréciée!

Remarque: deploy complet GlassFish serveur fonctionne (en utilisant appclient et @EJB injection)

+0

Remarque: un déploiement complet sur le serveur Glassfish fonctionne (en utilisant appclient et @EJB injection) – Dzhu

Répondre

6

Après beaucoup de recherche, a trouvé la solution qui fonctionne pour moi ...

Vous devrez configurez EJBContainer avec la propriété: EJBContainer.MODULES et l'emplacement où se trouvent les classes de module (si vous utilisez maven, 'target/classes').

par exemple.

... 
props = new Properties(); 
props.put(EJBContainer.MODULES, new File("target/classes")); 
ec = EJBContainer.createEJBContainer(props); 
... 

Si votre EJB utilise JPA, theres un autre problème que vous ne serez pas en mesure de définir une source de données dans le conteneur embarqué, doivent donc utiliser la valeur par défaut ds: « default jdbc/__ ».

donc par exemple mon persistence.xml ressemble à ceci:

<?xml version="1.0" encoding="UTF-8"?> 

<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
    version="1.0"> 

    <persistence-unit name="bookshelf" transaction-type="JTA"> 
     <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
     <class>com.blah.domain.Book</class> 
     <jta-data-source>jdbc/__default</jta-data-source> 
     <properties> 
      <property name="eclipselink.logging.level" value="INFO"/> 
     </properties> 
    </persistence-unit> 

</persistence> 

Je n'ai pas compris comment configurer le test de conteneur embarqué à utiliser une DS (jdbc/__ par défaut), et mon application à utiliser un autre (par exemple JDBC/booksDS)

voir: http://www.mentby.com/glassfish/embedded-testing-woes.html

voir: http://forums.java.net/jive/thread.jspa?messageID=395759

Pour être honnête, je ne sais pas pourquoi les gens s'inquiètent avec Java EE lorsque des solutions comme le printemps est tellement plus simple ...

Il a été très frustrant et beaucoup de temps perdu ... espérons que cela aide.

+0

en outre, le nom JNDI sera au format: 'java: global/classes/EJBClass! Com.fully.qualified.remote. EJBRemoteInterface '- c'est-à-dire qu'il n'y a pas de composants app/module dans la chaîne jndi. – Dzhu

+0

après avoir défini jta-data-source dans persistence.xml également recevoir une erreur ... Exception interne: java.sql.SQLException: Erreur lors de l'allocation d'une connexion. Cause: La connexion n'a pas pu être allouée car: java.net.ConnectException: Erreur lors de la connexion au serveur localhost sur le port 1527 avec le message Connexion refusée: connect. Code d'erreur: 0 \t à org.eclipse.persistence.exceptions.DatabaseException.sqlException (DatabaseException.java:309) –

2

J'ai écrit un petit tutoriel sur l'utilisation du conteneur glassfish 3.1 incorporé, résolvant également le problème d'avoir besoin d'un fichier persistence.xml différent pour les tests. Réparer également les plantages de conteneurs avec des interfaces distantes et des services web. Vous pouvez le vérifier à http://pschyska.blogspot.com/2011/06/unit-testing-ejb-31-with-netbeans-maven.html

+0

Je travaille actuellement par le même chapitre. J'ai trouvé votre entrée de blog extrêmement utile. Je vous remercie. – b3bop

3

Il y a quelques éléments que vous devez vérifier afin de vous assurer que vous pouvez charger le grain à travers le context.lookup éviter une NamingException.

  1. Assurez-vous d'avoir un haricot. Cela peut sembler évident, mais j'ai passé beaucoup de temps à essayer de comprendre pourquoi je n'ai pas pu obtenir une instance de mon service dans les tests. La raison en était que je manquais l'annotation sans état.

  2. Ajouter le module lors de la création du conteneur comme indiqué par @Dzhu. Pour Maven cours seront cible/cours, pour Maven essais sera cible/test-classes.

  3. Quelque chose ne va pas si vous trouvez un message comme SEVERE: EJB6005:No EJB modules found dans la console. Il vous indique qu'il n'y a pas de sans classes annotées

  4. Regardez la console glassfish intégrée! Là, vous verrez les noms de recherche pour vos haricots. Faites attention aux messages au format INFO: EJB5181:Portable JNDI names for EJB YourBean: [java:global/classes/YourBean!bean.package.YourBean, java:global/classes/YourBean]. Cela signifie que vous pouvez rechercher votre bean soit en appelant context.lookup("java:global/classes/YourBean!bean.package.YourBean") ou par le nom plus court context.lookup("java:global/classes/YourBean") qui peut être utile s'il n'y a pas de collisions de noms.

Espérons que cela aide quelqu'un. Il aurait été vraiment utile d'avoir eu ces conseils.