Que fait java: comp / env / do?

116

J'ai juste passé trop de temps de ma journée à essayer de trouver des erreurs lors de la connexion d'un bean d'usine JNDI. Le problème s'est avéré être qu'au lieu de cela ...

<bean id="someId" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="java:comp/env/jdbc/loc"/>
</bean>

J'avais en fait écrit ceci ...

<bean id="someId" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="jdbc/loc"/>
</bean>

J'en déduis que java:comp/env/peut - être fait référence à une variable d'environnement et fait en sorte que, finalement, mon fichier de contexte soit examiné. La seule différence est java:comp/env/. De la bouche d'un expert, qu'est-ce que cela fait?

Sans le java:comp/env/préfixe dans la valeur, j'obtiendrais une erreur qui dit "Le nom jdbc n'est pas lié dans ce contexte" .

Danny
la source
3
Lequel avez-vous utilisé au départ? Votre question implique que vous utilisiez incorrectement le deuxième exemple ( jdbc/locet java:comp/env/jdbc/locest donc correct), tandis que la réponse de cherouvim implique que vous utilisiez incorrectement le premier exemple ( java:comp/env/jdbc/locet jdbc/locest donc correct). Quoi qu'il en soit, la vraie réponse est: cela dépend du contexte actuel .
BalusC
1
Celui qui ne fonctionnait pas manquait en effet de java: comp / env / jdbc / loc, comme implicite. Le fichier de contexte pointé incluait la ressource "loc". Quelles sont les possibilités pour les contextes «actuels»?
Danny

Réponses:

100

Citant https://web.archive.org/web/20140227201242/http://v1.dione.zcu.cz/java/docs/jndi-1.2/tutorial/beyond/misc/policy.html

À la racine du contexte de l'espace de noms se trouve une liaison avec le nom «comp», qui est liée à un sous-arbre réservé aux liaisons liées aux composants. Le nom «comp» est l'abréviation de composant. Il n'y a pas d'autres liaisons au niveau du contexte racine. Cependant, le contexte racine est réservé pour l'expansion future de la stratégie, en particulier pour nommer les ressources qui ne sont pas liées au composant lui-même mais à d'autres types d'entités telles que les utilisateurs ou les services. Par exemple, les futures politiques pourraient vous permettre de nommer des utilisateurs et des organisations / services en utilisant des noms tels que «java: user / alice» et «java: org / engineering».

Dans le contexte "comp", il existe deux liaisons: "env" et "UserTransaction". Le nom «env» est lié à une sous-arborescence réservée aux liaisons liées à l'environnement du composant, telles que définies par son descripteur de déploiement. "env" est l'abréviation de l'environnement. Le J2EE recommande (mais n'exige pas) la structure suivante pour l'espace de noms "env".

Ainsi, la liaison que vous avez faite à partir de spring ou, par exemple, d'un descripteur de contexte tomcat va par défaut sous java: comp / env /

Par exemple, si votre configuration est:

<bean id="someId" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="foo"/>
</bean>

Ensuite, vous pouvez y accéder directement en utilisant:

Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/foo");

ou vous pouvez faire une étape intermédiaire pour ne pas avoir à spécifier "java: comp / env" pour chaque ressource que vous récupérez:

Context ctx = new InitialContext();
Context envCtx = (Context)ctx.lookup("java:comp/env");
DataSource ds = (DataSource)envCtx.lookup("foo");
cherouvim
la source
Je pensais avoir bien compris cela, mais d'autres commentaires m'ont fait réaliser que je l'avais fait à l'envers. Si le descripteur de contexte tomcat passait, par défaut, sous java: comp / env, cela ne signifierait-il pas que je peux omettre java: comp / env de la valeur? Dans mon cas, j'ai dû l'ajouter pour faire disparaître l'erreur «Le nom jdbc n'est pas lié dans ce contexte».
Danny
4
Vous liez en utilisant "foo" et la recherche en utilisant "java: comp / env / foo". Jetez un œil à blog.cherouvim.com/javax-sql-datasource-exposed-through-jndi
cherouvim
3
Le lien ci-dessus provient du didacticiel JNDI autonome, disponible à l'origine sur: docs.oracle.com/javase/jndi/tutorial/beyond/misc/policy.html .
Danilo Piazzalunga
et s'il y a plus / -es dans votre recherche? Comme: "java: com / env / foo / bar", votre valeur jndiName est-elle "foo / bar" ou "foo.bar"?
Pieter De Bie
La valeur correcte de jndiName serait "foo / bar" @PieterDeBrie.
tftdias
37

Il existe également une propriété resourceRefde JndiObjectFactoryBeanqui est, lorsqu'elle est définie sur true, utilisée pour ajouter automatiquement la chaîne java:comp/env/si elle n'est pas déjà présente.

<bean id="someId" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="jdbc/loc"/>
  <property name="resourceRef" value="true"/>
</bean>
Filip Spiridonov
la source
3

Après plusieurs tentatives et approfondissant le code source de Tomcat, j'ai découvert que la simple propriété useNaming = "false" faisait l'affaire !! Maintenant, Tomcat résout les noms java: / liferay au lieu de java: comp / env / liferay

Thiago Leão Moreira
la source
Pourriez-vous fournir un exemple complet, y compris la définition de la ressource? Je n'ai pas réussi à configurer cela avec succès avec Tomcat 8.5 - un exemple plus complet m'aiderait peut-être à voir mon erreur.
RobertG