有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

tomcat8主java HttpServlet工作,但ServletContextListener无法访问mysql数据库

我正在使用ubuntu 16.04、tomcat8、mysql 5.7.12和activeMQ做一些事情。我在谷歌上搜索了很多。我通常找不到关于我的具体情况的例子,但通常是针对较旧的tomcat和mysql版本,等等。我基本上是在上下文侦听器工作时(每隔15分钟检查一次特定的活动)出现这个错误的。我正在使用IntelliJ社区版和maven

javax.naming.NameNotFoundException: Name [comp/env/jdbc/acnn] is not bound in this Context. Unable to find [comp].
at org.apache.naming.NamingContext.lookup(NamingContext.java:819)
at org.apache.naming.NamingContext.lookup(NamingContext.java:166)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:157)
at javax.naming.InitialContext.lookup(InitialContext.java:417)
at org.davidliebman.desktop.audio.ACNNDataBase.getConnection(ACNNDataBase.java:87)
at org.davidliebman.desktop.audio.ACNNDataBase.doUpdate(ACNNDataBase.java:199)
at org.davidliebman.desktop.audio.ACNNDataBase.deleteUserPlaying(ACNNDataBase.java:386)
at org.davidliebman.server.audio.ACNNContextListener$DB.run(ACNNContextListener.java:39)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
java.lang.NullPointerException

“acnn”是我的数据库的名称。下面是我的网站。我的战争中的xml文件:

<web-app
    xmlns="http://java.sun.com/xml/ns/javaee"
    metadata-complete="false"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">

<servlet>
       <servlet-name>ACNNServer</servlet-name>
       <servlet-class>org..server.audio.ACNNServer</servlet-class>
</servlet>

<servlet-mapping>
       <servlet-name>ACNNServer</servlet-name>
       <url-pattern>/ACNNServer</url-pattern>
</servlet-mapping>


<listener>
    <listener-class>
        org..server.audio.ACNNContextListener
    </listener-class>
</listener>


<resource-ref>
    <description>ACNN DB</description>
    <res-ref-name>jdbc/acnn</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

</web-app>

这是我的conf/server部分。xml

<GlobalNamingResources>
<!-- Editable user database that can also be used by
     UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
          type="org.apache.catalina.UserDatabase"
          description="User database that can be updated and saved"
          factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
          pathname="conf/tomcat-users.xml" />

 <Resource name="jdbc/acnn" auth="Container" type="javax.sql.DataSource"
           maxTotal="100" maxIdle="30" maxWaitMillis="10000"
           username="xxx" password="xxx" driverClassName="com.mysql.jdbc.Driver"
           url="jdbc:mysql://localhost:3306/acnn"
            removeAbandonedOnBorrow="true" 
            removeAbandonedOnMaintenance="true" 
            removeAbandonedTimeout="60" 
            logAbandoned="true" />

<ResourceLink name="jdbc/acnn"
            global="jdbc/acnn"
            type="javax.sql.DataSource" />
</GlobalNamingResources>

下面是conf/context的匹配部分。xml文件

<Context allowLinking="true">

<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

<Resource name="jdbc/acnn" auth="Container" type="javax.sql.DataSource"
           maxTotal="100" maxIdle="30" maxWaitMillis="10000"
           username="xxx" password="xxx" driverClassName="com.mysql.jdbc.Driver"
           url="jdbc:mysql://localhost:3306/acnn"
            removeAbandonedOnBorrow="true" 
            removeAbandonedOnMaintenance="true" 
            removeAbandonedTimeout="60" 
            logAbandoned="true" />

<ResourceLink name="jdbc/acnn"
         global="jdbc/acnn"
          type="javax.sql.DataSource" />

</Context>

最后,我将材料复制到META-INF/上下文中。xml文件。我认为它被忽略了。不确定

<Context allowLinking="true">


<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>


<Resource name="jdbc/acnn" auth="Container" type="javax.sql.DataSource"
           maxTotal="100" maxIdle="30" maxWaitMillis="10000"
           username="xxx" password="xxx" driverClassName="com.mysql.jdbc.Driver"
           url="jdbc:mysql://localhost:3306/acnn"
            removeAbandonedOnBorrow="true" 
            removeAbandonedOnMaintenance="true" 
            removeAbandonedTimeout="60" 
            logAbandoned="true" />

<ResourceLink name="jdbc/acnn"
         global="jdbc/acnn"
          type="javax.sql.DataSource" />

</Context>

当从HttpServlet而不是从ServletContextListener运行时,实际代码如下所示:

    public class ACNNDataBase {
    ...

    private Connection getConnection() {
        Connection conn = null;
        try {
            InitialContext ctx = new InitialContext();
            DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/acnn");
            conn = ds.getConnection();
        }
        catch (Exception e) { e.printStackTrace();}
        return conn;
    }
    public void getVersion() {

        String command = "SELECT VERSION()";
        String rs = doQuery(command);
        System.out.println(rs);

    }

    public String doQuery(String command) {
        try {
            Connection con = getConnection();
            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery(command);

            String value = "";

            while (rs.next()) {
                System.out.println(rs.getString(1));
                value = rs.getString(1);
            }
        } catch (Exception ex) {
            ex.printStackTrace();

        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (st != null) {
                    st.close();
                }
                if (con != null) {
                    con.close();
                }


            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return value;
    }
    ...
}

下面是调用db函数的类:

public class ACNNContextListener implements ServletContextListener{

    private int FIFTEEN_MINUTES = 15;

    public void contextInitialized(ServletContextEvent servletContextEvent) {
        Timer timer = new Timer(true);
        timer.scheduleAtFixedRate(new DB(), 0, FIFTEEN_MINUTES * 60 * 1000);
    }

    public void contextDestroyed(ServletContextEvent servletContextEvent) {
    }

    class DB extends TimerTask{

        public void run () {

            ACNNDataBase db = new ACNNDataBase();
            db.getVersion();
        }
    }
}

就这些。任何帮助都将不胜感激。谢谢


共 (1) 个答案

  1. # 1 楼答案

    我刚刚在我的机器上测试了它,主要技巧是:

                InitialContext ctx = new InitialContext();
                Context envCtx = (Context) ctx.lookup("java:comp/env");             
                DataSource d = (DataSource) envCtx.lookup("jdbc/acnn");
    

    详细信息: 您只需执行以下操作:
    -为配置只保留META-INF/context.xml
    -将节保留在web.xml
    -从tomcat/conf/web中删除所有配置(将其恢复为默认值)。xml,tomcat/conf/server。xml和tomcat/conf/context。xml

    -在侦听器中,获取连接,如本例所示:

    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.Hashtable;
    import java.util.Timer;
    import java.util.TimerTask;
    
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NameClassPair;
    import javax.naming.NamingEnumeration;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    import javax.sql.DataSource;
    
    public class ACNNContextListener implements ServletContextListener {
        private int FIFTEEN_MINUTES = 15;
    
        public void contextInitialized(ServletContextEvent servletContextEvent) {
            Timer timer = new Timer(true);
            timer.scheduleAtFixedRate(new DB(), 0, FIFTEEN_MINUTES * 60 * 1000);
        }
    
        public void contextDestroyed(ServletContextEvent servletContextEvent) {
        }
    
        class DB extends TimerTask {
    
            public void run() {
                try {
                    InitialContext ctx = new InitialContext();
                    Context envCtx = (Context) ctx.lookup("java:comp/env");
    
                    DataSource d = (DataSource) envCtx.lookup("jdbc/acnn");
                    Connection connection = d.getConnection();
                    connection.close();
                    System.out.println("Done");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    • 另外,请确保将tomcat jdbc驱动程序放在tomcat/lib文件夹中 编辑:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
      <listener>
          <listener-class>
              a.b.c.ACNNContextListener
          </listener-class>
      </listener>
      <resource-ref>
          <description>ACNN DB</description>
          <res-ref-name>jdbc/acnn</res-ref-name>
          <res-type>javax.sql.DataSource</res-type>
          <res-auth>Container</res-auth>
      </resource-ref>
    </web-app>
    

    我的完整META-INF/context。xml:

        <Context allowLinking="true">       
        <Resource name="jdbc/acnn" auth="Container" type="javax.sql.DataSource" maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="root" password="123456" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/scd" removeAbandonedOnBorrow="true"        removeAbandonedOnMaintenance="true" removeAbandonedTimeout="60" logAbandoned="true" />
        <ResourceLink name="jdbc/acnn" global="jdbc/acnn" type="javax.sql.DataSource" />
    </Context>