JBoss EAP 7.3中OracleDS数据源JNDI查找失败问题如何解决?
Red Hat JBoss EAP 7.3 数据源JNDI查找失败问题解决
问题背景
使用Red Hat JBoss EAP 7.3服务器,连接管理器Java代码尝试通过JNDI查找java:/OracleDS数据源时,抛出NameNotFoundException,提示无法找到jboss.naming.context.java.jboss.exported.OracleDS服务,进而引发NullPointerException。
连接管理器代码
public static synchronized Connection getSISConnection() { Connection conn = null; Context ctx; try { Properties props = new Properties(); System.out.println("Initializing connection0000..."); // Set the context factory for WildFly props.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory"); System.out.println("INITIAL_CONTEXT_FACTORY set."); // Set the provider URL for remote JNDI access props.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080"); // Ensure this is the correct port for JNDI access-- remote://127.0.0.1:4447 System.out.println("PROVIDER_URL set."); // Set security credentials props.put(Context.SECURITY_PRINCIPAL, "admin"); // Your JBoss username props.put(Context.SECURITY_CREDENTIALS, "admin@123"); // Your JBoss password // Create the initial context ctx = new InitialContext(props); // Perform the lookup for the datasource DataSource ds = (DataSource) ctx.lookup("java:/OracleDS"); // Ensure this JNDI name is correct if (ds != null) { conn = ds.getConnection(); conn.setAutoCommit(false); System.out.println("Connection established successfully."); } else { System.err.println("Datasource lookup failed."); } return conn; } catch (NamingException e) { System.err.println("NamingException: " + e.getMessage()); e.printStackTrace(); return null; } catch (Exception e) { System.err.println("Exception: " + e.getMessage()); e.printStackTrace(); return null; } }
错误日志片段
17:23:03,366 ERROR [stderr] (ServerService Thread Pool -- 77) NamingException: OracleDS -- service jboss.naming.context.java.jboss.exported.OracleDS 17:23:03,367 ERROR [stderr] (ServerService Thread Pool -- 77) javax.naming.NameNotFoundException: OracleDS -- service jboss.naming.context.java.jboss.exported.OracleDS ... 17:23:03,368 ERROR [stderr] (ServerService Thread Pool -- 77) java.lang.NullPointerException: Cannot invoke "java.sql.Connection.prepareStatement(String)" because "conn" is null
排查步骤
- 验证数据源配置
- 打开JBoss配置文件(
standalone.xml或domain.xml),检查数据源的jndi-name属性是否为java:/OracleDS,同时确认是否添加了exported="true"(仅远程访问需要)。
- 打开JBoss配置文件(
- 区分本地/远程访问场景
- 若应用部署在JBoss内部,无需使用远程JNDI工厂和
http-remoting地址,容器会自动提供本地JNDI上下文。
- 若应用部署在JBoss内部,无需使用远程JNDI工厂和
- 检查数据源状态
- 登录JBoss管理控制台(默认地址
http://localhost:9990),查看数据源是否处于Enabled状态,测试连接是否正常。
- 登录JBoss管理控制台(默认地址
- 确认JNDI名称大小写
- JBoss的JNDI名称大小写敏感,确保代码中的查找名称与配置文件完全一致。
修复方案
场景1:应用部署在JBoss EAP内部
移除远程JNDI相关配置,直接使用本地上下文查找,代码调整如下:
public static synchronized Connection getSISConnection() { Connection conn = null; try { // 本地应用无需手动配置JNDI属性,容器自动提供上下文 Context ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("java:/OracleDS"); if (ds != null) { conn = ds.getConnection(); conn.setAutoCommit(false); System.out.println("Connection established successfully."); } else { System.err.println("Datasource lookup failed."); } return conn; } catch (NamingException e) { System.err.println("NamingException: " + e.getMessage()); e.printStackTrace(); return null; } catch (SQLException e) { System.err.println("SQLException: " + e.getMessage()); e.printStackTrace(); return null; } }
更规范的方式是使用依赖注入(适用于Servlet、EJB等容器管理组件):
@Resource(lookup = "java:/OracleDS") private DataSource ds; public Connection getSISConnection() { Connection conn = null; try { conn = ds.getConnection(); conn.setAutoCommit(false); return conn; } catch (SQLException e) { System.err.println("SQLException: " + e.getMessage()); e.printStackTrace(); return null; } }
场景2:作为远程客户端访问JBoss数据源
- 修改JBoss数据源配置,添加
exported="true"暴露到远程JNDI上下文:
<datasource jndi-name="java:/OracleDS" pool-name="OracleDS" enabled="true" use-java-context="true" exported="true"> <!-- 数据库驱动、连接URL、用户名密码等配置 --> </datasource>
- 调整代码中的JNDI查找名称,需要添加
java:jboss/exported前缀:
public static synchronized Connection getSISConnection() { Connection conn = null; Context ctx; try { Properties props = new Properties(); props.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory"); props.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080"); props.put(Context.SECURITY_PRINCIPAL, "admin"); props.put(Context.SECURITY_CREDENTIALS, "admin@123"); ctx = new InitialContext(props); // 远程查找导出的数据源,需添加jboss/exported前缀 DataSource ds = (DataSource) ctx.lookup("java:jboss/exported/java:/OracleDS"); if (ds != null) { conn = ds.getConnection(); conn.setAutoCommit(false); System.out.println("Connection established successfully."); } else { System.err.println("Datasource lookup failed."); } return conn; } catch (NamingException e) { System.err.println("NamingException: " + e.getMessage()); e.printStackTrace(); return null; } catch (SQLException e) { System.err.println("SQLException: " + e.getMessage()); e.printStackTrace(); return null; } }
额外注意事项
- 确保Oracle数据库驱动已正确部署到JBoss的
modules目录(推荐方式),或作为应用依赖打包。 - 验证
admin用户是否具有访问数据源的权限,远程访问时需确保用户拥有jboss:admin或相关权限组。
内容的提问来源于stack exchange,提问作者Berlin
相关产品推荐
相关产品推荐

