tomcat8 - 主java的HttpServlet有效,但ServletContextListener无法访问mysql数据库

时间:2016-06-17 21:50:55

标签: java mysql tomcat intellij-idea

我正在使用ubuntu 16.04,tomcat8,mysql 5.7.12和activeMQ。我用Google搜索了很多。我通常不会找到关于我的确切情况的示例,但通常用于较旧的tomcat和mysql版本等。当上下文监听器工作时,我基本上会得到此错误(每隔15分钟检查一次certian活动)。我正在使用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'是我的数据库的名称。下面是我战争中的web.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>

最后在despiration中我将材料复制到META-INF / 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>

从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 个答案:

答案 0 :(得分:0)

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

            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-driver放在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>