Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

调用存储过程后LogFilter出现空指针异常,问题原因分析并且找到 #1486

Closed
zhanglei602 opened this issue Nov 17, 2016 · 9 comments

Comments

@zhanglei602
Copy link

存储过程如下:

{#{FLAG,mode=OUT,jdbcType=DECIMAL} = call pkg_ly.f_ly
                    (#{P_LYDD,mode=IN,jdbcType=CLOB},
                    #{P_KHDH,mode=OUT,jdbcType=VARCHAR},
                    #{P_ERROR,mode=OUT,jdbcType=VARCHAR})}

出现问题的代码如下:
LogFilter类的下面这段代码有问题,请看加粗标记的地方

private void logExecutableSql(StatementProxy statement, String sql) {
      if(this.isStatementExecutableSqlLogEnable()) {
          int parametersSize = statement.getParametersSize();
          if(parametersSize == 0) {
              this.statementLog("{conn-" + statement.getConnectionProxy().getId() + ", " + this.stmtId(statement) + "} executed. \n" + sql);
          } else {
              ArrayList parameters = new ArrayList(parametersSize);
              for(int dbType = 0; dbType < parametersSize; ++dbType) {
                  JdbcParameter formattedSql = statement.getParameter(dbType);
                  **//下面这行报错,formattedSql空指针异常**
                  parameters.add(formattedSql.getValue());
              }
              String var7 = statement.getConnectionProxy().getDirectDataSource().getDbType();
              String var8 = SQLUtils.format(sql, var7, parameters);
              this.statementLog("{conn-" + statement.getConnectionProxy().getId() + ", " + this.stmtId(statement) + "} executed. \n" + var8);
          }
      }
  }

分析:
实际上入参只有1个,但是parametersSize等于2,原因如下:
PreparedStatementProxyImpl这个类的setParameter这个方法

 void setParameter(int jdbcIndex, JdbcParameter parameter) {
        int index = jdbcIndex - 1;
        if(jdbcIndex > this.parametersSize) {
            this.parametersSize = jdbcIndex;
        }

        if(this.parametersSize >= this.parameters.length) {
            this.parameters = (JdbcParameter[])Arrays.copyOf(this.parameters, this.parametersSize + 16);
        }

        this.parameters[index] = parameter;
        if(this.paramMap != null) {
            this.paramMap = null;
        }

    }

由于入参是在第二个位置,所以jdbcIndex的值为2,最后parameterSize的值就为2,正常情况如果不是存储过程那么jdbcIndex是没有问题的。目前我在重写了logfilter类,解决,但是真正要解决的是在调用这个类的时候PreparedStatementProxyImpl要考虑存储过程的情况

@zhanglei602
Copy link
Author

bug

@wenshao
Copy link
Member

wenshao commented Nov 20, 2016

请提供一下版本,没有版本不好对代码行号

@zhanglei602
Copy link
Author

1.0.25

@wenshao
Copy link
Member

wenshao commented Nov 20, 2016

行号还是不对,能提供出错的堆栈信息么?

@zhanglei602
Copy link
Author

我想起来了,我是反编译的,我明天上班下载源码在给你

@zhanglei602
Copy link
Author

 private void logExecutableSql(StatementProxy statement, String sql) {
        if (!isStatementExecutableSqlLogEnable()) {
            return;
        }

        int parametersSize = statement.getParametersSize();
        if (parametersSize == 0) {
            statementLog("{conn-" + statement.getConnectionProxy().getId() + ", " + stmtId(statement) + "} executed. \n"
                         + sql);
            return;
        }

        List<Object> parameters = new ArrayList<Object>(parametersSize);
        for (int i = 0; i < parametersSize; ++i) {
            JdbcParameter jdbcParam = statement.getParameter(i);
            parameters.add(jdbcParam.getValue());
        }

        String dbType = statement.getConnectionProxy().getDirectDataSource().getDbType();
        String formattedSql = SQLUtils.format(sql, dbType, parameters);
        statementLog("{conn-" + statement.getConnectionProxy().getId() + ", " + stmtId(statement) + "} executed. \n"
                     + formattedSql);
    }

这个方法的 parameters.add(jdbcParam.getValue());
jdbcParam这个变量为null,
错误的行号是542

@wenshao
Copy link
Member

wenshao commented Nov 23, 2016

你也知道问题所在了,提交一个pull request?参与进来一起改进吧

@wenshao wenshao added this to the 1.0.27 milestone Nov 23, 2016
wenshao added a commit that referenced this issue Nov 26, 2016
@wenshao
Copy link
Member

wenshao commented Nov 26, 2016

已经修复,请使用1.0.27版本 https://github.com/alibaba/druid/releases/tag/1.0.27

@wenshao wenshao closed this as completed Nov 26, 2016
@zhanglei602
Copy link
Author

我刚准备改,被你改了,我可以参与其他的需求或者BUG修改吗?

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

2 participants