Recherche JNDI Tomcat vs Weblogic
Question
Les serveurs Weblogic que nous utilisons ont été configurés pour autoriser les noms de sources de données JNDI tels que "appds".
Pour le développement (localhost), nous pourrions exécuter Tomcat et lorsqu'il est déclaré dans la section <context> de server.xml, Tomcat bloquera les sources de données JNDI sur "java:comp/env/jdbc/*" dans l'arborescence JNDI.
Problème: dans Weblogic, la recherche JNDI est "appds" tandis que dans Tomcat, il semble que je doive fournir le "java:comp/env/jdbc/appds" formel.J'ai bien peur que la version Tomcat soit un standard implicite mais malheureusement, je ne peux pas changer la config de Weblogic...cela signifie donc que nous nous retrouvons avec deux fichiers de configuration Spring différents (nous utilisons Spring 2.5) pour faciliter les différents environnements.
Existe-t-il une manière élégante de résoudre ce problème.Puis-je rechercher les noms JNDI directement dans Tomcat ?Spring peut-il prendre un nom et regarder aux deux endroits ?Des recherches ou des suggestions Google seraient formidables.
La solution
JndiLocatorSupport
a une propriété resourceRef
.Lorsque vous définissez cette valeur sur true, le préfixe "java:comp/env/" sera automatiquement ajouté.Je pense donc qu'il serait correct de différencier ce paramètre lors du passage de Tomcat à Weblogic.
Autres conseils
Comment utiliser un seul nom JNDI dans votre application Web
J'ai moi-même eu du mal avec ça pendant quelques mois.La meilleure solution consiste à rendre votre application portable afin que vous ayez le même nom JNDI dans Tomcat et Weblogic.
Pour ce faire, vous modifiez votre web.xml
et spring-beans.xml
pour pointer vers un seul nom jndi et fournir un mappage vers le nom jndi spécifique à chaque fournisseur.
J'ai placé chaque fichier ci-dessous.
Vous avez besoin:
- UN
<resource-ref />
entrée dans web.xml pour que votre application utilise un seul nom - Un fichier
WEB-INF/weblogic.xml
pour mapper votre nom jndi à la ressource gérée par WebLogic - Un fichier
META-INF/context.xml
pour mapper votre nom jndi à la ressource gérée par Tomcat- Cela peut être soit dans l'installation de Tomcat, soit dans votre application.
En règle générale, préférez avoir vos noms jndi dans votre application comme jdbc/MyDataSource
et jms/ConnFactory
et évitez de les préfixer avec java:comp/env/
.
De plus, les sources de données et les usines de connexions sont mieux gérées par le conteneur et utilisées avec JNDI.C'est un erreur courante pour instancier des pools de connexions à la base de données dans votre application.
printemps
<?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 (pour Tomcat)
<Context>
<ResourceLink global="jdbc/appds" name="jdbc/appds" type="javax.sql.DataSource"/>
</Context>
J'ai réussi l'astuce avec Tomcat et WebLogic en utilisant Spring. Ici est une description de la façon dont cela a fonctionné pour moi.
La configuration suivante fonctionne pour moi dans Tomcat et Weblogic.
Au printemps:
<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>
Dans Weblogic Admin Console, créez une ressource JDBC nommée jdbc/AgriShare
.Sous « Cibles », ASSUREZ-VOUS DE CIBLER LA SOURCE DE DONNÉES SUR LE SERVEUR SUR LEQUEL VOUS DÉPLOYEZ VOTRE APPLICATION !.Ce point particulier m'a coûté du temps tout à l'heure...
Que diriez-vous d'une variable environnementale ?Définissez les machines des développeurs avec le nom Tomcat et la production avec le nom Weblogic.Vous pouvez même définir votre code pour utiliser celui par défaut (WebLogic) au cas où la variable n'existerait pas.
Comment référencez-vous la ressource au printemps ?
Voici ce que nous avons pour Tomcat :
contexte:
<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"/>
printemps:
<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"/>
L'espace de noms jee vient de :
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd
Configurer DataSource dans l'application elle-même n'est pas si fou :) Je dirais que c'est même obligatoire si l'application est destinée à être déployée sur une grille.River, GigaSpaces ou similaire.
Note:Je ne dis pas que les paramètres de connexion doivent être codés en dur dans WAR, ils doivent être fournis au moment du déploiement/de l'exécution.Cela simplifie la gestion des instances cloud puisqu'il n'y a que sur place à configurer.
La configuration des ressources sur le conteneur n'a de sens que si plusieurs applications y sont déployées et qu'elles peuvent utiliser des ressources partagées.
Encore une fois, dans les déploiements de type cloud, il n'y a qu'une seule application par instance de conteneur de servlet.
Mon application avait également un problème similaire et voici comment je l'ai résolu :
1) WEB-INF/classes/application.properties
contient l'entrée :
ds.jndi=java:comp/env/jdbc/tcds
2) Sur la machine WLS, j'ai une entrée dans le /etc/sysenv
déposer:
ds.jndi=wlsds
3) J'ai configuré Spring pour rechercher le JNDI par rapport à la propriété ${ds.jndi}
, utilisant un PropertyPlaceholderConfigurer
haricot avec classpath:application.properties
et file:/etc/sysenv
comme lieux.J'ai également réglé le ignoreResourceNotFound
à true
afin que les développeurs n'aient pas besoin d'avoir /etc/sysenv
sur leurs machines.
4) J'ai exécuté un test d'intégration à l'aide de Cargo+Jetty et je n'ai pas pu y configurer correctement un environnement JNDI.J'ai donc une solution de repli BasicDataSource
configuré également à l'aide du defaultObject
propriété de JndiObjectFactoryBean
.