O que java: comp / env / faz?

116

Passei muito tempo do meu dia tentando descobrir alguns erros ao conectar algum bean de fábrica JNDI. O problema acabou sendo que, em vez disso ...

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

Eu realmente tinha escrito isso ...

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

Eu deduzo que o java:comp/env/ talvez faça referência a alguma variável de ambiente e faça com que, em última instância, meu arquivo de contexto seja examinado. A única diferença é java:comp/env/. Da boca de um especialista, o que isso faz?

Sem o java:comp/env/prefixo no valor, eu obteria um erro que dizia "O nome jdbc não está vinculado a este contexto" .

Danny
fonte
3
Qual você usou inicialmente? Sua pergunta implica que você estava usando incorretamente o segundo exemplo ( jdbc/loce, portanto, java:comp/env/jdbc/locestá correto), enquanto a resposta de cherouvim implica que você estava usando incorretamente o primeiro exemplo ( java:comp/env/jdbc/loce, portanto, jdbc/locestá correto). Independentemente disso, a verdadeira resposta é: depende do contexto atual .
BalusC
1
Aquele que não funcionou estava realmente faltando java: comp / env / jdbc / loc, conforme implícito. O arquivo de contexto apontado inclui o recurso "loc". Quais são as possibilidades para contextos "atuais"?
Danny

Respostas:

100

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

No contexto raiz do namespace está uma associação com o nome "comp", que está ligada a uma subárvore reservada para associações relacionadas ao componente. O nome "comp" é uma abreviação de componente. Não há outras ligações no contexto raiz. No entanto, o contexto raiz é reservado para a expansão futura da política, especificamente para nomear recursos que estão vinculados não ao próprio componente, mas a outros tipos de entidades, como usuários ou departamentos. Por exemplo, políticas futuras podem permitir que você nomeie usuários e organizações / departamentos usando nomes como "java: user / alice" e "java: org / engineering".

No contexto "comp", existem duas ligações: "env" e "UserTransaction". O nome "env" está vinculado a uma subárvore reservada para as ligações relacionadas ao ambiente do componente, conforme definido por seu descritor de implantação. "env" é a abreviação de ambiente. O J2EE recomenda (mas não requer) a seguinte estrutura para o namespace "env".

Portanto, a ligação que você fez a partir do spring ou, por exemplo, de um descritor de contexto do tomcat vai por padrão em java: comp / env /

Por exemplo, se sua configuração for:

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

Em seguida, você pode acessá-lo diretamente usando:

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

ou você pode fazer uma etapa intermediária para não precisar especificar "java: comp / env" para cada recurso recuperado:

Context ctx = new InitialContext();
Context envCtx = (Context)ctx.lookup("java:comp/env");
DataSource ds = (DataSource)envCtx.lookup("foo");
Cherouvim
fonte
Achei que tinha entendido isso corretamente, mas outros comentários me fizeram perceber que eu tinha feito isso ao contrário. Se o descritor de contexto do tomcat fosse, por padrão, em java: comp / env, isso não significaria que posso omitir o java: comp / env do valor? No meu caso, tive que adicioná-lo para eliminar o erro "O nome jdbc não está vinculado a este contexto".
Danny
4
Você vincula usando "foo" e pesquisa usando "java: comp / env / foo". Dê uma olhada em blog.cherouvim.com/javax-sql-datasource-exposed-through-jndi
cherouvim
3
O link acima é do tutorial JNDI independente, originalmente disponível em: docs.oracle.com/javase/jndi/tutorial/beyond/misc/policy.html .
Danilo Piazzalunga
e se houver mais / -es em sua pesquisa? Por exemplo: "java: com / env / foo / bar", seu valor jndiName é "foo / bar" ou "foo.bar"?
Pieter De Bie
O valor correto de jndiName seria "foo / bar" @PieterDeBrie.
tftdias
37

Também existe uma propriedade resourceRefde JndiObjectFactoryBeanque, quando definida como true, é usada para preceder automaticamente a string java:comp/env/se ela ainda não estiver presente.

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

Depois de várias tentativas e me aprofundando no código-fonte do Tomcat, descobri que a propriedade simples useNaming = "false" funcionou !! Agora o Tomcat resolve nomes java: / liferay em vez de java: comp / env / liferay

Thiago Leão Moreira
fonte
Você poderia fornecer um exemplo completo, incluindo a definição do recurso? Não consegui configurar isso com sucesso com o Tomcat 8.5 - um exemplo mais abrangente me ajudaria a ver meu erro, talvez.
RobertG