首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java Web 連線池 JNDI 查找失敗:NoInitialContextException 解決

     編輯:程式設計綜合問答

錯誤訊息

javax.naming.NoInitialContextException: 
Need to specify class name in environment or system property, 
or as an applet parameter, or in an application resource file: 
java.naming.factory.initial

原因

程式碼在 **非 Servlet 容器執行緒** (如 main 方法、獨立類別、單元測試、排程器) 中直接 `new InitialContext()`,但未提供 JNDI 環境屬性 (Context.INITIAL_CONTEXT_FACTORY)。Tomcat 容器內部 (Servlet/Filter/Listener) 已自動配置,無需手動指定。

解決方案

方案 A:僅在容器管理的元件中查找 (標準做法)

  • 將 `DataSource` 查找移至 `Servlet.init()`、`ServletContextListener.contextInitialized()`、Spring `@PostConstruct` 或 `@Resource` 注入中。**不要在普通 Java 類別建構子/靜態區塊中查找**。

方案 B:獨立程式/測試需手動配置環境 (不推薦生產用)

Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory"); // Tomcat 專用
env.put(Context.URL_PKG_PREFIXES, "org.apache.naming");
InitialContext ctx = new InitialContext(env);
// 再 ctx.lookup("java:comp/env/jdbc/conn")

需將 `tomcat-embed-core` / `catalina.jar` 加入類路徑,複雜且脆弱。

方案 C:Spring Boot / 現代框架自動配置 (推薦)

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args); // 自動配置 DataSource、JNDI、連線池
    }
}
@DataSourceDefinition(
    name = "java:comp/env/jdbc/conn",
    className = "com.mysql.cj.jdbc.Driver",
    url = "jdbc:mysql://localhost:3306/exchange",
    user = "root", password = "500235"
)

web.xml / context.xml 正確配置 (Tomcat 9+)

<!-- context.xml (在 META-INF/context.xml 或 conf/context.xml) -->
<Resource name="jdbc/conn"
          auth="Container"
          type="javax.sql.DataSource"
          factory="org.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactory"  <!-- DBCP2 -->
          driverClassName="com.mysql.cj.jdbc.Driver"
          url="jdbc:mysql://localhost:3306/exchange?useSSL=false&serverTimezone=UTC"
          username="root" password="500235"
          maxTotal="20" maxIdle="10" maxWaitMillis="1000"/>

Servlet 3.0+ 無需 `web.xml` 定義 ``,`@Resource` 或 JNDI 直接可用。

總結:JNDI 查找必須在容器初始化上下文中進行;獨立程式請改用框架自動配置或直接建立 DataSource Bean,勿硬編碼 InitialContext。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved