java—javassist;缺少

iaqfqrcu  于 2021-07-05  发布在  Java
关注(0)|答案(3)|浏览(628)

有人能告诉我代码出了什么问题吗?当使用javassist插入代码时,会显示错误“由:compile error:;“缺少”;但我仔细检查,没有;完全不见了。javassist在这里有什么限制吗?

ClassPool cp = ClassPool.getDefault();
        cp.importPackage("com.mysql.cj");

        CtClass cc = cp.get(clzname);
        CtMethod ms = cc.getDeclaredMethod(
                "execute");
        StringBuilder sb = new StringBuilder();
        sb.append("String sql = ((PreparedQuery) this.query).getOriginalSql();");
        sb.append("QueryBindings bindings = ((PreparedQuery) this.query).getQueryBindings();\n" +
                "        for (BindValue o : bindings.getBindValues()) {\n" +
                "            sql = sql.replaceFirst(\"\\\\?\", new String(o.getByteValue()));\n" +
                "        }");

        sb.append(
                "System.out.println( sql);");

        ms.insertBefore(sb.toString());
        byteCode = cc.toBytecode();
lsmepo6l

lsmepo6l1#

我通过替换for循环解决了我的bug。
javaassit似乎不支持convent for循环,必须将其改为for(int i=0;i<长度;i++)格式;
多亏了@kutschem,代码还需要用大括号 Package 。

ClassPool cp = ClassPool.getDefault();
        cp.importPackage("com.mysql.cj");

        CtClass cc = cp.get(clzname);
        CtMethod ms = cc.getDeclaredMethod(
                "execute");

        ms.insertBefore("{\n" +
                "            String sql = ((PreparedQuery) this.query).getOriginalSql();\n" +
                "            QueryBindings bindings = ((PreparedQuery) this.query).getQueryBindings();\n" +
                "            for (int i =0; i < bindings.getBindValues().length; i++ ) sql = sql.replaceFirst(\"\\\\?\", new String(bindings.getBindValues()[i].getByteValue()));\n" +
                "            System.out.println(sql);\n" +
                "        }");

        byteCode = cc.toBytecode();
0md85ypi

0md85ypi2#

insertbefore的javadoc说:
https://www.javassist.org/html/javassist/ctbehavior.html#insertbefore(java.lang.string)
参数:src-表示插入字节码的源代码。它必须是单个语句或块。
因此,将代码用大括号括起来,使其成为单个块。

kdfy810k

kdfy810k3#

除了像@kutschem所说的那样将代码 Package 成大括号外,我还为您提供了一个如何更轻松地连接字符串而不使用 StringBuilder . 作为一个积极的副作用,你也得到了换行:

String codeToBeInserted = String.join("\n",
  "{",
  "  String sql = ((PreparedQuery) this.query).getOriginalSql();",
  "  QueryBindings bindings = ((PreparedQuery) this.query).getQueryBindings();",
  "  for (BindValue o : bindings.getBindValues()) {",
  "    sql = sql.replaceFirst(\"\\\\?\", new String(o.getByteValue()));",
  "  }",
  "  System.out.println(sql);",
  "}"
);
System.out.println(codeToBeInserted);
``` `String.join` 从Java8开始提供。控制台输出为:

{
String sql = ((PreparedQuery) this.query).getOriginalSql();
QueryBindings bindings = ((PreparedQuery) this.query).getQueryBindings();
for (BindValue o : bindings.getBindValues()) {
sql = sql.replaceFirst("\?", new String(o.getByteValue()));
}
System.out.println(sql);
}

对我来说,你的代码在语法上看起来不错,尤其是 `replaceFirst` 意在取代 `?` 一个固定的值。

相关问题