为什么这里会出现javax.naming.NamingException?

为什么这里会出现javax.naming.NamingException?,java,jdbc,naming,Java,Jdbc,Naming,当我运行以下命令时: 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() { }

当我运行以下命令时:

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
}
}

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

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



与具体问题无关您真的需要每次都获取
数据源吗?我将创建一个helper类,该类在webapp启动时或在静态初始值设定项中仅获取一次。它具有广泛的应用范围和线程安全性。每次您需要启动SQL查询时,实际上只需要获取连接(并关闭它!您没有关闭它,因此您正在泄漏数据库资源)。

您可以发布此连接所适用的servlet的代码吗?@Amit Bhargava为什么需要它?嗯,我希望找到两者之间的一些差异,从而解释为什么在本例中它不起作用。为什么Tomcat单独需要
java:comp/env
部分?我很难想象。@asgs:不知道。Tomcat的家伙们决定这么做。Tomcat并不是一个成熟的JavaEE容器。@asgs:您可能会发现这个(旧的)教程很有用(主要是针对Tomcat的,是的,但它应该让您了解如何正确地使用基本的JDBC)。或者,如果您已经在使用Glassfish或任何其他完整的JavaEE容器,您也可以选择JPA。不再有JDBC样板代码了。我一直在glassfish上使用
java:com/env/
,效果很好。例如,我调用了一个帮助器类方法,该方法生成一个表,其中查找中的url与我的问题中的url相同。在删除
java:comp/env/
之后,虽然我没有得到任何异常,但我也没有看到输出。而是在输出中打开一个输入流!我使用main的原因只是为了测试我是否能够获得良好的输出
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