You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Weblogic 10.3.6与Spring-web 4.0.3部署DataSource获取异常求助

解决Weblogic 10.3.6部署Spring项目时偶发JNDI DataSource查找失败的问题

我碰到过类似Weblogic和Spring整合的坑,结合你的问题场景和报错信息,整理了几个排查和解决的方向:

首先明确核心问题:你的Spring 4.0.3.RELEASE项目在Jetty上部署正常,但在Weblogic 10.3.6上偶发因JNDI查找不到数据源导致entityManagerFactory创建失败,重启有时能解决——这大概率是Weblogic的资源初始化时机、容器上下文适配或者类加载的问题,下面分点说明:

一、先搞定Weblogic端的JNDI数据源配置与部署顺序

  • 调整部署优先级:如果你的war包比JNDI数据源先启动,Spring初始化时数据源还没准备好,自然查不到。可以在Weblogic控制台的「部署」页面点击「排序」,把JDBC数据源拉到war包前面,确保Spring启动前数据源已完成初始化。
  • 核对JNDI名称与访问权限:报错显示Resolved 'dummy'但找不到myDB,先去Weblogic控制台的「JDBC数据源」页面,确认配置的JNDI全名是不是dummy.myDB,避免拼写错误。另外要检查数据源的「目标服务器」是否包含你部署项目的服务器,否则全局数据源无法被项目访问。

二、优化Spring的JNDI查找逻辑,适配Weblogic容器

你现在手动创建InitialContext的方式不太适配Weblogic这类Java EE容器,建议换成Spring原生的JNDI工具类,稳定性更高:

方式1:用JndiObjectFactoryBean替代手动查找

@Bean
public DataSource createWeblogicDatasource() {
    JndiObjectFactoryBean jndiFactory = new JndiObjectFactoryBean();
    // 直接读取配置文件中的JNDI名称
    jndiFactory.setJndiName(environment.getProperty("dsName"));
    // 开启资源引用,适配Weblogic的容器上下文规范
    jndiFactory.setResourceRef(true);
    // 关闭启动时立即查找,改为第一次使用时再查询,避开部署时资源未就绪的问题
    jndiFactory.setLookupOnStartup(false);
    // 缓存查找结果,避免重复查询
    jndiFactory.setCache(true);
    jndiFactory.afterPropertiesSet();
    return (DataSource) jndiFactory.getObject();
}

这种方式无需手动指定INITIAL_CONTEXT_FACTORY和PROVIDER_URL,Weblogic会自动注入容器上下文,比手动实现更可靠。

方式2:用@JndiLookup注解(Spring 4.0+支持)

你的Spring版本是4.0.3,刚好支持这个注解,写法更简洁:

@JndiLookup(jndiName = "${dsName}", resourceRef = true)
private DataSource dataSource;

同样能自动适配Weblogic的JNDI环境,减少手动代码的出错概率。

三、排查Weblogic的类加载冲突问题

Weblogic 10.3.6基于Java EE 5规范,而Spring 4.0.3兼容Java EE 6,可能存在类加载冲突:

  • 清理war包中的冗余依赖:确保war包不包含Weblogic已自带的类,比如javax.naming、javax.servlet等。可以在pom.xml中将这些依赖的scope改为provided:
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>javax.naming</groupId>
    <artifactId>jndi</artifactId>
    <version>1.2.1</version>
    <scope>provided</scope>
</dependency>
  • 调整类加载顺序:在Weblogic控制台进入项目部署→「部署描述符」→「Web应用程序」,将类加载顺序改为「父类加载器最后(Child First)」,避免Weblogic的旧版本类覆盖Spring的类,导致JNDI查找逻辑异常。

四、给JNDI查找加重试机制,应对偶发的资源未就绪

既然问题是偶发的,可以在原查找逻辑中添加重试,给Weblogic的数据源初始化留够时间:

@Bean
private DataSource createWeblogicDatasource() throws NamingException {
    String contextFactory = environment.getProperty("jndiDriver");
    String dsServer = environment.getProperty("dsServer");
    String dsPort = environment.getProperty("dsPort");
    String dsName = environment.getProperty("dsName");
    String contextUrl = "t3://" + dsServer + ":" + dsPort;
    Hashtable ht = new Hashtable();
    ht.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory);
    ht.put(Context.PROVIDER_URL, contextUrl);

    int retryCount = 3; // 重试3次
    int retryDelay = 2000; // 每次间隔2秒
    for (int i = 0; i < retryCount; i++) {
        try {
            Context ctx = new InitialContext(ht);
            DataSource dataSource = (DataSource) ctx.lookup(dsName);
            if (dataSource != null) {
                return dataSource;
            }
        } catch (NamingException e) {
            if (i == retryCount - 1) {
                // 最后一次重试失败,再抛出异常
                throw e;
            }
            try {
                Thread.sleep(retryDelay);
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt();
            }
        }
    }
    throw new NamingException("重试" + retryCount + "次后仍无法找到数据源");
}

这样即使第一次查找失败,也能多尝试几次,大概率能避开Weblogic数据源初始化的时间差问题。

内容的提问来源于stack exchange,提问作者Francesco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:51:18