为什么会重复出现:
at com.kenfor.exutil.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:152)
        at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:70)
        at com.kenfor.exutil.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:152)
        at com.caucho.server.dispatch.FilterFilterChain.doFilter(FilterFilterChain.java:70)
谁能告诉我啊。

解决方案 »

  1.   

    本来proxool是很有口碑的连接池 ,怎么会导致   at org.logicalcobwebs.proxool.FatalSqlExceptionHelper.testException(FatalSqlExceptionHelper.java:116)中testException运行没完没了呢。
      

  2.   

    回复:iihero(阿黑哥)   应该不是filter的引起的,如果是filter的话,那所有的页面都会很容易进入死循环。
      

  3.   

    下面就是这个永远不结束的方法,我看了一下源代码,虽然有循环部分,但也不导致死循环,
    大伙帮我分析一下,具体是什么原因会导致下面的代码一直执行? 
    /**
         * Test to see if an exception is a fatal one
         * @param cpd the definition so we can find out what a fatal exception looks like
         * @param t the exception to test
         * @param level the recursion level (max 20)
         * @return true if it is fatal
         */
        protected static boolean testException(ConnectionPoolDefinitionIF cpd, Throwable t, int level) {
            boolean fatalSqlExceptionDetected = false;
            Iterator i = cpd.getFatalSqlExceptions().iterator();
            while (i.hasNext()) {
                if (t.getMessage() != null && t.getMessage().indexOf((String) i.next()) > -1) {
                    // This SQL exception indicates a fatal problem with this connection.
                    fatalSqlExceptionDetected = true;
                }
            }        // If it isn't fatal, then try testing the contained exception
            if (!fatalSqlExceptionDetected && level < 20) {
                Throwable cause = getCause(t);
                if (cause != null) {
                    fatalSqlExceptionDetected = testException(cpd, cause, level + 1);
                }
            }        return fatalSqlExceptionDetected;
        }
      

  4.   

    while (i.hasNext()) {
                if (t.getMessage() != null && t.getMessage().indexOf((String) i.next()) > -1) {
                    // This SQL exception indicates a fatal problem with this connection.
                    fatalSqlExceptionDetected = true;
                }
            }t.getMessage() != null这句话不成立的话,就没机会调用i.next()
    就死循环了。
      

  5.   

    在网上大家都对proxool赞赏有加,但是我们的项目出现如此严重的错误,实属不应该,
    请兄弟们帮我查明此原因,不让我再去怀疑proxool的过错了,把清白留proxool。
      

  6.   

    回复:zhmt(不爽你就用分砸我!!!) 
      
       t.getMessage() != null不成立,也应该会再次调用i.hasNext()吧
      

  7.   

    你说的错了,&& 运算是从左到右,左边的不成立,直接就返回false了,不再计算右边的。所以不调用i.next()。楼主要加强基础。
      

  8.   

    当 t.getMessage() != null不成立时,是“t.getMessage().indexOf((String) i.next()) > -1”没机会执行。不是i.hasNext
      

  9.   

    回复: zhmt(不爽你就用分砸我!!!)     我还是不明白,t.getMessage() != null这句话不成立的话,就会导致死循环。
      

  10.   

    就算“t.getMessage().indexOf((String) i.next()) > -1不知道,也不会导致死循环啊。
      

  11.   

    我上面的那段代码是从proxool中取出来的,如果这么容易就死循环了,那我就要怀疑这个东西的安全性啦。
      

  12.   

    resin-tcp-connection-*:80-6075" daemon prio=1 tid=0x0857aac8 nid=0x7fb0 runnable 这是个守护线程,(daemon),一直运行的话,是很正常的。可能问题不在这里,你的是什么性能问题啊?
      

  13.   

    好,那我就说说背景 :
     
      我维护的是个网站项目,网站经常服务器cpu 99%,并且上去了就不下来了,开始我就确定是
    死循环的问题,但是找不到根据,前两天我用kill -3 pid,每隔5分钟Thread Dump一下,发现
    上面的线程一直在虚拟机(JVM)里面运行者。那只有死循环才不会退出的。
       我不知道我讲清楚没?
      

  14.   

    daemon是守护进程,但是不应该不结束。
      

  15.   

    你确信是这个线程启动后cpu才到100%的吗?
      

  16.   

    我查了一下它的源码,这个类是用来检查一个异常是否是严重异常,它能一直运行说明你的应用导致了很多sql异常。如果这个pool是经过大家的检验的话,可能你的应用中,哪一部分的sql调用很有问题。
      

  17.   

    是的,但是很多异常也会有个数量限制啊,可能处理校验的速度慢啊,而不会出现,死循环啊。
    在页面上传入的sql语句难免有些问题,我测试过,一般情况下,系统会自动处理的,但是我想在就不明白,什么情况下,什么样的SQL语句会导致死循环。
      

  18.   

    你看了有多少个这样线程了吗?
    可能不是死循环,而是线程结束后又被启动起来。或者是启动了多个这样的线程。
    如果不是我感才说的那个死循环的,就不可能出现死循环了(next和hasNext要成对使用才不会死在那,如果只使用hasNext而不使用next,那么iterator是不往下走的,就会死了。)。
    另外它的递归调用也不会超过20层,所以也不会死。
      

  19.   

    回复:zhmt(不爽你就用分砸我!!!) 你说的有道理,如果 t.getMessage() ==null的话,就会陷入死循环。但是我看我们的代码都是按照JDBC规范来写的啊。  下面我贴些原码,帮我看看有什么问题。
      

  20.   

    public HashMap getdbValue(PoolBean pool) throws Exception
      {
        if(pool.getLog().isDebugEnabled())
          pool.getLog().debug("star getdbValue");    String system_name = pool.getDatabaseInfo().getSystemName();
        HashMap result = null;
        String temp_sql = createSql();
        if(temp_sql == null)
          throw new SQLException("not sql statement");    Statement stmt = null;
        ResultSet rs = null;
        Connection con = null;
        try
        {
          con = pool.getNoInfoConnection();// .getConnection();
          con.setReadOnly(true);
          stmt = con.createStatement();
          rs = stmt.executeQuery(temp_sql);
    //      rs = stmt.executeQuery(sql);
          if (rs != null) {
            ResultSetMetaData rsmd = rs.getMetaData();
            int colCount = rsmd.getColumnCount();
            if (rs.next()) {
              result = new HashMap();
              for (int i = 1; i <= colCount; i++) {
                String name = rsmd.getColumnName(i);
                name = name.toLowerCase();
                String type_name = rsmd.getColumnTypeName(i).toLowerCase();
    //          System.out.println("field name : " + name + " , type_anme : " + type_name);
                if ("text".equals(type_name)) {
                  //当字段类型为text时,如果直接用rs.getObject(i)取数据,在jtds1.0版本中不能直接取出,改为以下方式即可  2005-07-22 张贵平
                  String tt_str = rs.getString(i);
    //            System.out.println("text -- "+tt_str);
                  if (tt_str == null)
                    tt_str = "";
                  else
                    tt_str = tt_str.trim();
                  result.put(name.trim(), tt_str);
                }
                else {
                  Object obj_value = rs.getObject(i);
                  if (obj_value instanceof java.lang.String) {
                    String t_str = null;
                    if (obj_value == null)
                      t_str = "";
                    else
                      t_str = String.valueOf(obj_value).trim();
                    result.put(name.trim(), t_str);
                  }
                  else {
                    result.put(name.trim(), obj_value);
                  }
                }
              }
            }
            rsmd = null;
          }
          rs.close();
          stmt.close();
          con.setReadOnly(false);
          con.close();
        }
        catch(SQLException e)
        {
          //CloseCon.Close(con);
          pool.getLog().error(system_name+","+e.getMessage()+",sql:"+temp_sql);
          throw new SQLException("database perform error : " + e.getMessage());
        }
        finally
        {
          CloseCon.Close(con);
        }    return result;  }从线程堆栈上看$java.sql.Statement$$EnhancerByCGLIB$$1a91e2dc.close(<generated>)
    ,是从stmt.close()进去的。
      

  21.   

    觉得不规范
    rs.close();
          stmt.close();
          con.setReadOnly(false);
          con.close();以上这些东西都要放在finnally块中的。我没用过PoolBean,不知道怎么用,觉得数据库的操作好像没多大问题。你倒网上搜索资料看看吧。
      

  22.   

    你看下Filter里面的跳转是不是错了。
      

  23.   

    回复:zhmt(不爽你就用分砸我!!!)   PoolBean  是我们自己写的一个类,主要是做跟连接池的衔接工作。 是的,不是很规范,但是这样也应该不会导致proxool死循环。
      

  24.   

    我们自己的Filter类,看看有什么问题。public class SetCharacterEncodingFilter implements Filter {  Log log = LogFactory.getLog(this.getClass().getName());    // ----------------------------------------------------- Instance Variables    /**
         * The default character encoding to set for requests that pass through
         * this filter.
         */
        protected String encoding = null;
        /**
         * The filter configuration object we are associated with.  If this value
         * is null, this filter instance is not currently configured.
         */
        protected FilterConfig filterConfig = null;    /**
         * 上传文件的最大大小
         */
        protected int fileMaxLength = 200*1024; //200K    /**
         * Should a character encoding specified by the client be ignored?
         */
        protected boolean ignore = true;
        /**
         * Take this filter out of service.
         */
        public void destroy() {        this.encoding = null;
            this.filterConfig = null;    }
        /**
         * Select and set (if specified) the character encoding to be used to
         * interpret request parameters for this request.
         *
         * @param request The servlet request we are processing
         * @param result The servlet response we are creating
         * @param chain The filter chain we are processing
         *
         * @exception IOException if an input/output error occurs
         * @exception ServletException if a servlet error occurs
         */
        public void doFilter(ServletRequest request, ServletResponse response,
                             FilterChain chain)
            throws IOException, ServletException {        // Conditionally select and set the character encoding to be used        HttpServletRequest t_re = (HttpServletRequest) request;        String re_uri = trimString(t_re.getRequestURI());
            String re_host = trimString(t_re.getServerName());
            String qu_str = trimString(t_re.getQueryString());
            if (re_uri.indexOf(".do") > 0)
            {
              if (log.isInfoEnabled())
                log.info(re_host + re_uri + "?" + qu_str);
         
           try
            {          if (ignore || (request.getCharacterEncoding() == null)) {
                String encoding = selectEncoding(request);
                if (encoding != null)
                  request.setCharacterEncoding(encoding);
              }
              // Pass control on to the next filter
              chain.doFilter(request, response);
            }
            catch(Exception e)
            {
    //          e.printStackTrace();
              String error_mes = e.getMessage();
              String strServerName = null;
              String strQueryString = null;
              String requestUrl = null;
              String remoteAddr = null;
              String referer = "";
              if(error_mes.indexOf("reset")<0 )
              {
                try {
                  strServerName = t_re.getServerName();
                  strQueryString = t_re.getQueryString();
                  requestUrl = t_re.getRequestURI();
     //             strQueryString = CodeTransfer.ISOToUnicode(strQueryString);
                  referer = t_re.getHeader("referer");
                  remoteAddr = t_re.getRemoteAddr();
                }
                catch (Exception e1) {}
                if (error_mes != null && !"null".equals(error_mes)&& error_mes.length() > 0) {
                  log.error(",exception:" +
                            error_mes + strServerName + " , " + strQueryString + " , " +
                            requestUrl + " , " + referer);
    //              System.out.println("exception at filter:" +
    //                                 error_mes);
                }          }
              if(log.isInfoEnabled())
                log.info(strServerName + " , " + strQueryString+ " , " + requestUrl + " , " + referer);
            }    }
        /**
         * Place this filter into service.
         *
         * @param filterConfig The filter configuration object
         */
        public void init(FilterConfig filterConfig) throws ServletException {        this.filterConfig = filterConfig;
            this.encoding = filterConfig.getInitParameter("encoding");
            String value = filterConfig.getInitParameter("ignore");
            String file_max_length = filterConfig.getInitParameter("file_max_length");
            if(file_max_length!=null && file_max_length.length() >0)
            {
              fileMaxLength = com.kenfor.util.MyUtil.getStringToInt(file_max_length,200)*1024;
            }        if (value == null)
                this.ignore = true;
            else if (value.equalsIgnoreCase("true"))
                this.ignore = true;
            else if (value.equalsIgnoreCase("yes"))
                this.ignore = true;
            else
                this.ignore = false;    }    /**
         * Select an appropriate character encoding to be used, based on the
         * characteristics of the current request and/or filter initialization
         * parameters.  If no character encoding should be set, return
         * <code>null</code>.
         * <p>
         * The default implementation unconditionally returns the value configured
         * by the <strong>encoding</strong> initialization parameter for this
         * filter.
         *
         * @param request The servlet request we are processing
         */
        protected String selectEncoding(ServletRequest request) {        return (this.encoding);    }
        private String trimString(String value)
        {
          String result = "";
          if(value !=null)
            result = value.trim();      return result;
        }
    }
      

  25.   

    如果真的是proxool,那我应该感到欣慰,如果是我们写的代码不当引起的,但我就真的无地之容了。
      

  26.   

    呵呵,这个我也搞不清楚,楼主最好把你们的那个poolBean自己测试一下。
    能找到那种情况下出那个错误是最好的。看看循环使用的时候是否也抛出这个异常,如果这样的话就查查哪的问题吧。如果不出错,可能就是sql写的有问题了。