Pergunta

Os servidores Weblogic que estamos usando foram configurados para permitir nomes de fontes de dados JNDI como "appds".

Para desenvolvimento (localhost), podemos estar executando o Tomcat e quando declarado na seção <context> do server.xml, o Tomcat irá travar fontes de dados JNDI em "java:comp/env/jdbc/*" na árvore JNDI.

Problema: no Weblogic, a pesquisa JNDI é "appds", enquanto no Tomcat, parece que devo fornecer o formal "java:comp/env/jdbc/appds".Receio que a versão do Tomcat seja um padrão implícito, mas infelizmente não posso alterar a configuração do Weblogic ...isso significa que teremos dois arquivos de configuração diferentes do Spring (estamos usando o Spring 2.5) para facilitar os diferentes ambientes.

Existe uma maneira elegante de resolver isso.Posso procurar nomes JNDI diretamente no Tomcat?A Primavera pode pegar um nome e procurar nos dois lugares?Pesquisas ou sugestões do Google seriam ótimas.

Foi útil?

Solução

JndiLocatorSupport tem uma propriedade resourceRef.Ao definir isso como verdadeiro, o prefixo "java:comp/env/" será anexado automaticamente.Então acredito que seria correto diferenciar esse parâmetro ao passar do Tomcat para o Weblogic.

Outras dicas

Como usar um único nome JNDI em seu aplicativo web

Eu mesmo lutei com isso por alguns meses.A melhor solução é tornar seu aplicativo portátil para que você tenha o mesmo nome JNDI no Tomcat e no Weblogic.

Para fazer isso, você muda seu web.xml e spring-beans.xml para apontar para um único nome jndi e fornecer um mapeamento para cada nome jndi específico do fornecedor.

Coloquei cada arquivo abaixo.

Você precisa:

  • A <resource-ref /> entrada em web.xml para seu aplicativo usar um único nome
  • Um arquivo WEB-INF/weblogic.xml para mapear seu nome jndi para o recurso gerenciado pelo WebLogic
  • Um arquivo META-INF/context.xml para mapear seu nome jndi para o recurso gerenciado pelo Tomcat
    • Isso pode ser na instalação do Tomcat ou no seu aplicativo.

Como regra geral, prefira ter seus nomes jndi em seu aplicativo, como jdbc/MyDataSource e jms/ConnFactory e evite prefixá-los com java:comp/env/.

Além disso, as fontes de dados e os connection factorys são melhor gerenciados pelo contêiner e usados ​​com JNDI.É um erro comum ao instanciar pools de conexões de banco de dados em seu aplicativo.

primavera

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">

<jee:jndi-lookup jndi-name="jdbc/appds"
                 id="dataSource" />
</beans>

web.xml

<resource-ref>
    <description>My data source</description>
    <res-ref-name>jdbc/appds</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

weblogic.xml

<?xml version="1.0" encoding="UTF-8" ?>
<weblogic-web-app
    xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://xmlns.oracle.com/weblogic/weblogic-web-app http://http://www.oracle.com/technology/weblogic/weblogic-web-app/1.1/weblogic-web-app.xsd">

<resource-description>
    <jndi-name>appds</jndi-name>
    <res-ref-name>jdbc/appds</res-ref-name>
</resource-description>
</weblogic-web-app>

META-INF/context.xml (para Tomcat)

<Context>
    <ResourceLink global="jdbc/appds" name="jdbc/appds" type="javax.sql.DataSource"/>
</Context>

Consegui fazer o truque com Tomcat e WebLogic usando Spring. Aqui é uma descrição de como funcionou para mim.

A configuração a seguir funciona no Tomcat e no Weblogic para mim.

Na primavera:

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
   <!-- This will prepend 'java:comp/env/' for Tomcat, but still fall back to the short name for Weblogic -->
   <property name="resourceRef" value="true" /> 
   <property name="jndiName" value="jdbc/AgriShare" />
</bean>

No Weblogic Admin Console, crie um recurso JDBC chamado jdbc/AgriShare.Em 'Metas', CERTIFIQUE-SE DE DIRECIONAR A FONTE DE DADOS PARA O SERVIDOR EM QUE ESTÁ IMPLEMENTANDO SEU APLICATIVO!.Este ponto em particular me custou algum tempo agora...

Que tal uma variável de ambiente?Defina as máquinas dos desenvolvedores com o nome tomcat e a produção com o nome Weblogic.Você pode até configurar seu código para usar um código padrão (WebLogic) caso a variável não exista.

Como você está referenciando o recurso na primavera?

Isto é o que temos para o Tomcat:

contexto:

<Resource name="jms/ConnectionFactory" auth="Container" type="org.apache.activemq.ActiveMQConnectionFactory" description="
JMS Connection Factory"
        factory="org.apache.activemq.jndi.JNDIReferenceFactory" brokerURL="tcp://localhost:61615" brokerName="StandaloneAc
tiveMQBroker"/>

primavera:

    <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">

<jee:jndi-lookup jndi-name="jms/ConnectionFactory" id="connectionFactory" resource-ref="true"
                         expected-type="javax.jms.ConnectionFactory" lookup-on-startup="false"/>

O namespace jee vem de:

http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd

Configurar o DataSource no aplicativo em si não é tão maluco :) Eu diria que é até obrigatório se o aplicativo for implantado em uma grade.Rio, GigaSpaces ou similar.

Observação:Não digo que as configurações de conexão devam ser codificadas dentro do WAR, elas precisam ser fornecidas no tempo de implantação/tempo de execução.Isso simplifica o gerenciamento de instâncias de nuvem, pois só há local para configuração.

Configurar recursos no contêiner só faz sentido se vários aplicativos estiverem implantados lá e puderem usar recursos compartilhados.

Novamente, em implantações do tipo nuvem, há apenas um aplicativo por instância de contêiner de servlet.

Meu aplicativo também teve um problema semelhante e foi assim que resolvi:

1) WEB-INF/classes/application.properties contém a entrada:

ds.jndi=java:comp/env/jdbc/tcds

2) Na máquina WLS, tenho uma entrada no /etc/sysenv arquivo:

ds.jndi=wlsds

3) Configurei o spring para pesquisar o JNDI na propriedade ${ds.jndi}, usando um PropertyPlaceholderConfigurer feijão com classpath:application.properties e file:/etc/sysenv como locais.Eu também configurei o ignoreResourceNotFound para true para que os desenvolvedores não precisem ter /etc/sysenv em suas máquinas.

4) Executei um teste de integração usando Cargo+Jetty e não consegui configurar corretamente um ambiente JNDI lá.Então eu tenho um substituto BasicDataSource configurado também usando o defaultObject propriedade de JndiObjectFactoryBean.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top