Tomcat 8,axis2 webservices aar,spring jndi未绑定在上下文中

Posted

技术标签:

【中文标题】Tomcat 8,axis2 webservices aar,spring jndi未绑定在上下文中【英文标题】:Tomcat 8, axis2 webservices aar, spring jndi not bound in context 【发布时间】:2016-07-12 10:51:55 【问题描述】:

我一直在处理一个问题,即在运行axis2 web 服务的上下文中找不到JNDI 名称。当我使用 spring 时,这个问题只出现在 Tomcat 8 中。 一些细节:(我将提供相关的元素) 1.services.xml

<service name="ScoreService" class="com.bpl.ws.service.ScoreServiceInitializer">
<description>Simple test service</description>
<parameter name="ServiceObjectSupplier" locked="false">org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier</parameter>
<parameter name="SpringBeanName" locked="false">scoreService</parameter>

2。 server.xml:

      <Host name="localhost"  appBase="webapps" xmlBase="C:\Applications\apache-tomcat-8.0.30-windows-x64\context"
        unpackWARs="true" autoDeploy="true">

    上下文.xml

        <JarResources className="org.apache.catalina.webresources.DirResourceSet"
               base="C:\Applications\apache-tomcat-8.0.30-windows-x64\commonLib" webAppMount="/WEB-INF/lib"/>
    

4.上下文文件中的JNDI资源:

<Resource name="jdbc/ADS" auth="Container"
  factory="com.bpl.ws.EncryptedJdbcDataSourceFactory"
  type="javax.sql.DataSource"
  driverClassName="oracle.jdbc.OracleDriver"
  url="jdbc:oracle:thin:@xxxxxxx.com:3203/xxxx"
  username="xxxxx"
  password="xxxx"
  initialSize="10"
  logAbandoned="false"
  maxActive="20"
  maxIdle="10"
  maxWait="10000"
  removeAbandoned="true"
  removeAbandonedTimeout="120"
  jdbcInterceptors="QueryTimeoutInterceptor(queryTimeout=10)"
  testOnBorrow="true"
  validationInterval="30000"
  validationQuery="Select 1 from dual"/>

如 services.xml 文件列表所示,我使用了一个初始化器类,加载 spring 上下文的代码如下所示: 4.ScoreSerivceInitializer

public void startUp(ConfigurationContext ignore, AxisService service) 
    System.out.println("SCORESERVICE:: Starting up..");
    DataSource ds;


        ClassLoader cloader = service.getClassLoader();
        Thread.currentThread().setContextClassLoader(cloader);
        System.out.println("SCORESERVICE:: spring context starting up");
        spContext = new ClassPathXmlApplicationContext(new String[] "DST-Context.xml",false);
        spContext.setClassLoader(cloader);


        try 
            spContext.refresh();
    spring context.xml (DST-Context.xml)

DST-Context.xml 条目如下所示:

<bean id="applicationContext"
    class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />

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

    Tomcat 日志:

    [WARN] 上下文初始化期间遇到异常 - 取消刷新尝试:org.springframework.beans.factory.BeanCreationException:创建类路径资源 [DST-Context.xml] 中定义的名称为“datasource”的 bean 时出错:调用 init方法失败;嵌套异常是 javax.naming.NameNotFoundException:名称 [java:comp/env/jdbc/ADS] 未绑定在此上下文中。找不到 [java:comp].org.springframework.beans.factory.BeanCreationException:在类路径资源 [DST-Context.xml] 中定义名称为“datasource”的 bean 创建错误:调用 init 方法失败;嵌套异常是 javax.naming.NameNotFoundException: 名称 [java:comp/env/jdbc/ADS] 未绑定在此上下文中。找不到 [java:comp]。

在不改变任何配置的情况下,如果我改变 ScoreServiceInitializer 来做到这一点:

initCtx = new InitialContext();

        envCtx = (Context) initCtx.lookup("java:comp/env"); 

        ds = (DataSource)
                  envCtx.lookup("jdbc/ADS");

一切正常。正如您在此处看到的,我没有使用任何 spring,并且 jndi 数据源在上下文中。

如果我在 Tomcat 7 中使用 spring config 部署代码,它可以正常工作。 spring 上下文似乎是问题,但已经研究了一段时间,似乎无法弄清楚为什么 Tomcat 8 与 Tomcat 7 有不同的行为。我知道 Tomcat8 在资源方面改变了一些行为已配置并且 dbcp 现在是 dbcp2 并且我已经相应地更新了配置文件。 任何帮助是极大的赞赏。如果需要任何其他信息,请告诉我。

【问题讨论】:

这个问题只在windows环境下。相同的 aar 和相同的设置适用于 unix 环境。 可能很愚蠢的问题:你为什么要和ClassLoaders 玩游戏? @ChristopherSchultz:我假设这个问题是因为这两行:ClassLoader cloader = service.getClassLoader(); Thread.currentThread().setContextClassLoader(cloader);如果我不这样做,Spring 将无法找到打包在 aar 中的 applicationcontext 文件。 Webapp won't run uder Tomcat 8.0.23的可能重复 与axis2 1.5.1完全相同的问题,升级到axis2 1.6.1抛出NoClassDefFoundError: org/springframework/context/ApplicationContextAware 【参考方案1】:

@bplso 我在axis2项目上将tomcat7升级到tomcat8.5时遇到了同样的问题,请尝试图片中给出的步骤。它可能会解决您的问题。 !

Step 1: Specify the connection resource in server.xml inside <GlobalNamingResources> like 
<Resource name="jdbc/name" 
global="jdbc/name" 
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
auth="Container" 
type="javax.sql.DataSource" 
username="xxx" 
password="YYY" 
driverClassName="net.sourceforge.jtds.jdbc.Driver" 
url="jdbc:jtds:sqlserver://host:port/dbname" 
maxTotal="10" 
maxIdle="10" 
maxWaitMillis="10000" /> 


Step 2: Specify the resource reference in web.xml inside the <web-app> like 

<resource-ref> 
<description> This is a reference to the global Resource for SQL database connetion. </description> 
<res-ref-name>jdbc/name</res-ref-name> 
<res-type>javax.sql.DataSource</res-type> 
<res-auth>Container</res-auth> 
</resource-ref> 


Step 3: Create a context.xml file and paste it in your project/META-INF/ path as below 

<?xml version=.1.0 encoding="UTF-8.?> 
<Context> 
<ResourceLink name="jdbc/name" global="jdbc/name" type="javax.sgl.DataSource" 
</Context>

【讨论】:

以上是关于Tomcat 8,axis2 webservices aar,spring jndi未绑定在上下文中的主要内容,如果未能解决你的问题,请参考以下文章

JAVA记录-WebService开发部署

eclispe+axis2+webservice入门

用JAX-WS在Tomcat中发布WebService

AXIS2远程调用WebService示例(Eclipse+AXIS)

使用Axis2调用WebService服务

Axis2生成wsdl客户端代码并实现webservice调用