【问题标题】:Tomcat vs Weblogic JNDI LookupTomcat 与 Weblogic JNDI 查找
【发布时间】:2010-09-08 00:59:15
【问题描述】:

我们使用的 Weblogic 服务器已配置为允许使用 JNDI 数据源名称,例如“appds”。

对于开发(本地主机),我们可能正在运行 Tomcat,当在 server.xml 的 部分中声明时,Tomcat 会将 JNDI 数据源挂在 JNDI 树中的“java:comp/env/jdbc/*”上。

问题: 在 Weblogic 中,JNDI 查找是“appds”,而在 Tomcat 中,似乎我必须提供正式的“java:comp/env/jdbc/appds”。恐怕 Tomcat 版本是一个隐含的标准,但不幸的是,我无法更改 Weblogic 的配置......所以这意味着我们最终会得到两个不同的 spring 配置文件(我们使用的是 spring 2.5)来促进不同的环境。

有没有一种优雅的方法来解决这个问题。我可以直接在 Tomcat 中查找 JNDI 名称吗? Spring 可以取个名字并在两个地方都看吗?谷歌搜索或建议会很棒。

【问题讨论】:

    标签: java tomcat jakarta-ee weblogic jndi


    【解决方案1】:

    如何在您的网络应用中使用单个 JNDI 名称

    我自己已经为此苦苦挣扎了几个月。最好的解决方案是让您的应用程序可移植,以便在 Tomcat 和 Weblogic 中拥有相同的 JNDI 名称。

    为此,您将web.xmlspring-beans.xml 更改为指向单个jndi 名称,并提供到每个供应商特定jndi 名称的映射。

    我已将每个文件放在下面。

    你需要:

    • web.xml 中的 <resource-ref /> 条目供您的应用使用单个名称
    • 一个文件 WEB-INF/weblogic.xml 用于将您的 jndi 名称映射到 WebLogic 管理的资源
    • 一个文件META-INF/context.xml将你的jndi名称映射到Tomcat管理的资源
      • 这可以在 Tomcat 安装中,也可以在您的应用中。

    作为一般规则,您的 jndi 名称最好在您的应用中使用,例如 jdbc/MyDataSourcejms/ConnFactory,并避免在它们前面加上 java:comp/env/

    此外,数据源和连接工厂最好由容器管理并与 JNDI 一起使用。这是common mistake to instantiate database connection pools in your application

    春天

    <?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(用于 Tomcat)

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

    【讨论】:

    • 有没有办法配置tomcat,以便它提供没有“java:comp/env/”的JNDI
    【解决方案2】:

    JndiLocatorSupport 有一个属性resourceRef。当设置为 true 时,“java:comp/env/”前缀将被自动添加。所以我相信在从Tomcat迁移到Weblogic时区分这个参数是正确的。

    【讨论】:

    • 有没有办法配置 tomcat 以便它提供没有 "java:comp/env/" 的 JNDI?否则,外部化的优势就会减少……
    【解决方案3】:

    我已经使用 Spring 处理了 Tomcat 和 WebLogic 的技巧。 Here 描述了它是如何为我工作的。

    【讨论】:

      【解决方案4】:

      以下配置适用于我的 Tomcat 和 Weblogic。

      春天:

      <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>
      

      在 Weblogic 管理控制台中创建一个名为 jdbc/AgriShare 的 JDBC 资源。在“目标”下,确保将数据源定位到您将应用程序部署到的服务器!。刚才这一点花了我一些时间......

      【讨论】:

        【解决方案5】:

        环境变量怎么样?将开发人员机器设置为 tomcat 名称,将生产机器设置为 Weblogic 名称。您甚至可以将代码设置为使用默认值 (WebLogic),以防变量不存在。

        【讨论】:

          【解决方案6】:

          你是如何在 spring 中引用资源的?

          这就是我们为 tomcat 准备的:

          上下文:

          <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"/>
          

          春天:

              <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"/>
          

          jee命名空间来自:

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

          【讨论】:

          • 为什么要使用 ActiveMQ 库来连接 weblogic?
          【解决方案7】:

          在应用程序本身中设置 DataSource 并没有那么疯狂 :) 如果应用程序要部署在网格上,我想说这甚至是强制性的。 River、GigaSpaces 或类似网站。

          注意:我并不是说连接设置必须在 WAR 内部进行硬编码,它们需要在部署时/运行时提供。这简化了云实例的管理,因为只需在原地进行配置。

          仅当多个应用程序部署在容器中并且它们可以使用共享资源时,在容器中配置资源才有意义。

          同样,在云类型的部署中,每个 servlet 容器实例只有一个应用程序。

          【讨论】:

            【解决方案8】:

            我的应用程序也有类似的问题,我就是这样解决的:

            1) WEB-INF/classes/application.properties 包含条目:

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

            2) 在 WLS 机器上,我在 /etc/sysenv 文件中有一个条目:

            ds.jndi=wlsds

            3) 我配置了 spring 来查找属性 ${ds.jndi} 的 JNDI,使用 PropertyPlaceholderConfigurer bean 和 classpath:application.propertiesfile:/etc/sysenv 作为位置。我还将ignoreResourceNotFound 设置为true,这样开发人员就不需要在他们的机器上使用/etc/sysenv

            4) 我使用 Cargo+Jetty 运行集成测试,但无法在那里正确设置 JNDI 环境。所以我也使用JndiObjectFactoryBeandefaultObject 属性配置了一个备用BasicDataSource

            【讨论】:

              猜你喜欢
              • 2011-05-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-03-20
              相关资源
              最近更新 更多