【问题标题】:why does the javax.naming.NamingException occur here?为什么这里会出现 javax.naming.NamingException?
【发布时间】:2012-04-29 05:12:03
【问题描述】:

当我运行以下内容时:

package NonServletFiles;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import javax.sql.DataSource;
import javax.naming.*;

public class GetTagsFromDatabase {

public GetTagsFromDatabase() {

}

public String[] getTags() {

    String tags[] = null;
    try {
        Context context = new InitialContext();
        DataSource ds = (DataSource)context.lookup("java:comp/env/jdbc/photog"); // <<----- line 23
        Connection connection = ds.getConnection();
        String sqlQuery = "select NAMEOFTHETAG from tagcollection";
        PreparedStatement statement = connection.prepareStatement(sqlQuery);
        ResultSet set = statement.executeQuery();

        int i = 0;
        while(set.next()) {
            tags[i] = set.getString("NameOfTheTag");
            System.out.println(tags[i]);
            i++;
        }
    }catch(Exception exc) {
        exc.printStackTrace();
    }

    return tags;
}

public static void main(String args[]) {
    new GetTagsFromDatabase().getTags(); // <<----- line 43
}
}

我得到以下异常:

javax.naming.NamingException: Lookup failed for 'java:comp/env/jdbc/photog' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.url.pkgs=com.sun.enterprise.naming, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl} [Root exception is javax.naming.NamingException: Invocation exception: Got null ComponentInvocation ]
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
at NonServletFiles.GetTagsFromDatabase.getTags(GetTagsFromDatabase.java:23)
at NonServletFiles.GetTagsFromDatabase.main(GetTagsFromDatabase.java:43)

Caused by: javax.naming.NamingException: Invocation exception: Got null ComponentInvocation 
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.getComponentId(GlassfishNamingManagerImpl.java:873)
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:742)
at com.sun.enterprise.naming.impl.JavaURLContext.lookup(JavaURLContext.java:172)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:498)
... 4 more

我不知道这个异常的原因,所有其他需要使用 url java:comp/env/jdbc/photog 连接到数据库的 servlet 都可以正常工作。

【问题讨论】:

  • 你能发布一个 servlet 的代码,这个连接可以工作吗?
  • @Amit Bhargava 你为什么需要那个?
  • 嗯,我希望找到两者之间的一些差异,这可以解释为什么它在这种情况下不起作用。

标签: java jdbc naming


【解决方案1】:

堆栈跟踪提示您正在使用 Glassfish。删除 java:comp/env/ 部分。它已经是默认的 JNDI 上下文根。只有在 Tomcat 中,您才需要明确指定它。此外,您应该在 webapp 上下文中调用它,而不是作为带有 main() 的普通 Java 应用程序。


与具体问题无关,您真的需要获得DataSource每次吗?我会创建一个助手类,它只在 webapp 的启动或静态初始化程序中获取一次。它的应用程序广泛且线程安全。每次您需要触发 SQL 查询时,确实只需要获取 Connection(并关闭它!您没有关闭它,所以您正在泄漏数据库资源)。

【讨论】:

  • 为什么 Tomcat 单独需要 java:comp/env 部分?我想通了。
  • @asgs:不知道。 Tomcat的家伙们是这样决定的。无论如何,Tomcat 并不是一个成熟的 Java EE 容器。
  • @asgs:您可能会发现这个(旧)教程很有用balusc.blogspot.com/2008/07/dao-tutorial-data-layer.html(主要针对 Tomcat,是的,但它应该让您了解正确执行基本 JDBC)。或者,如果您已经在使用 Glassfish 或任何其他完整的 Java EE 容器,您也可以选择 JPA。不再有 JDBC 样板代码。
  • 我一直在使用 java:com/env/ 和 glassfish,效果很好。例如,我调用了一个创建表格的辅助类方法,查找中的 url 与我的问题中的相同。删除java:comp/env/ 后,虽然我没有得到任何异常,但我也看不到输出。而是在输出中打开输入流!我使用 main 的原因只是为了测试我的输出是否正常
猜你喜欢
  • 2011-03-31
  • 2014-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-01
  • 2015-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多