Was macht Java: comp / env / do?

116

Ich habe einfach zu viel Zeit meines Tages damit verbracht, einige Fehler herauszufinden, als ich eine JNDI-Factory-Bean angeschlossen habe. Das Problem stellte sich heraus, dass stattdessen ...

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

Ich hatte das tatsächlich geschrieben ...

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

Ich schließe daraus, dass das java:comp/env/möglicherweise auf eine Umgebungsvariable verweist und es so macht, dass letztendlich meine Kontextdatei betrachtet wird. Der einzige Unterschied ist java:comp/env/. Was macht das aus dem Mund eines Experten?

Ohne das java:comp/env/Präfix im Wert würde ich eine Fehlermeldung erhalten, die besagt, dass "Name jdbc in diesem Kontext nicht gebunden ist" .

Danny
quelle
3
Welches haben Sie ursprünglich verwendet? Ihre Frage impliziert, dass Sie das zweite Beispiel falsch verwendet haben ( jdbc/locund somit java:comp/env/jdbc/locrichtig sind), während die Antwort von Cherouvim impliziert, dass Sie das erste Beispiel falsch verwendet haben ( java:comp/env/jdbc/locund somit jdbc/locrichtig sind). Unabhängig davon lautet die eigentliche Antwort: Es hängt vom aktuellen Kontext ab.
BalusC
1
Demjenigen, der nicht funktionierte, fehlte tatsächlich Java: comp / env / jdbc / loc, wie impliziert. Die Kontextdatei, auf die verwiesen wurde, enthielt die Ressource "loc". Was sind die Möglichkeiten für "aktuelle" Kontexte?
Danny

Antworten:

100

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

Im Stammkontext des Namespace befindet sich eine Bindung mit dem Namen "comp", die an einen Teilbaum gebunden ist, der für komponentenbezogene Bindungen reserviert ist. Der Name "comp" steht für component. Es gibt keine anderen Bindungen im Stammkontext. Der Stammkontext ist jedoch für die zukünftige Erweiterung der Richtlinie reserviert, insbesondere für die Benennung von Ressourcen, die nicht an die Komponente selbst, sondern an andere Entitätstypen wie Benutzer oder Abteilungen gebunden sind. In zukünftigen Richtlinien können Sie beispielsweise Benutzer und Organisationen / Abteilungen mithilfe von Namen wie "java: user / alice" und "java: org / engineering" benennen.

Im Kontext "comp" gibt es zwei Bindungen: "env" und "UserTransaction". Der Name "env" ist an einen Teilbaum gebunden, der für die umgebungsbezogenen Bindungen der Komponente reserviert ist, wie im Bereitstellungsdeskriptor definiert. "env" steht für Umwelt. Das J2EE empfiehlt (erfordert jedoch nicht) die folgende Struktur für den Namespace "env".

Die Bindung, die Sie aus dem Frühjahr oder beispielsweise aus einem Tomcat-Kontextdeskriptor vorgenommen haben, wird standardmäßig unter Java angezeigt: comp / env /

Zum Beispiel, wenn Ihre Konfiguration ist:

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

Dann können Sie direkt darauf zugreifen, indem Sie:

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

oder Sie können einen Zwischenschritt ausführen, damit Sie nicht für jede Ressource, die Sie abrufen, "java: comp / env" angeben müssen:

Context ctx = new InitialContext();
Context envCtx = (Context)ctx.lookup("java:comp/env");
DataSource ds = (DataSource)envCtx.lookup("foo");
Cherouvim
quelle
Ich dachte, ich hätte das richtig verstanden, aber weitere Kommentare ließen mich erkennen, dass ich es rückwärts getan hatte. Wenn der Tomcat-Kontextdeskriptor standardmäßig unter java: comp / env angezeigt würde, würde das nicht bedeuten, dass ich java: comp / env aus dem Wert weglassen kann? In meinem Fall musste ich es hinzufügen, damit der Fehler "Name jdbc ist in diesem Kontext nicht gebunden" verschwindet.
Danny
4
Sie binden mit "foo" und suchen mit "java: comp / env / foo". Werfen
cherouvim
3
Der obige Link stammt aus dem eigenständigen JNDI-Tutorial, das ursprünglich verfügbar war unter: docs.oracle.com/javase/jndi/tutorial/beyond/misc/policy.html .
Danilo Piazzalunga
Was ist, wenn Ihre Suche mehr / -es enthält? Wie: "java: com / env / foo / bar", ist Ihr jndiName-Wert "foo / bar" oder "foo.bar"?
Pieter De Bie
Der korrekte jndiName-Wert würde "foo / bar" @PieterDeBrie sein.
Tftdias
37

Es gibt auch eine Eigenschaft resourceRefvon JndiObjectFactoryBeandem heißt, wenn auf true, verwendet , um automatisch die Zeichenfolge voranstellen , java:comp/env/wenn es nicht bereits vorhanden ist.

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

Nach mehreren Versuchen und tiefer in Tomcats Quellcode habe ich herausgefunden, dass die einfache Eigenschaft useNaming = "false" den Trick gemacht hat !! Jetzt löst Tomcat die Namen java: / liferay anstelle von java: comp / env / liferay auf

Thiago Leão Moreira
quelle
Können Sie ein vollständiges Beispiel einschließlich der Ressourcendefinition bereitstellen? Ich habe es nicht geschafft, dies mit Tomcat 8.5 erfolgreich einzurichten - ein umfassenderes Beispiel würde mir vielleicht helfen, meinen Fehler zu erkennen.
RobertG