javassist; 缺失

huangapple go评论105阅读模式
英文:

javassist ; is missing

问题

能否有人告诉我我的代码有什么问题
在使用javassist插入代码时出现错误造成错误缺少;”;
但是我仔细检查了没有漏掉任何;这里是否有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();
英文:

Could anyone tell what is wrong with my code ?
when using javassist to insert code , it show error "Caused by: compile error: ; is missing";
But I double check , there no ; missing at all. Is there some limitation of javassist here?

        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();

答案1

得分: 6

insertBefore的javadoc如下:

https://www.javassist.org/html/javassist/CtBehavior.html#insertBefore(java.lang.String)

参数:src - 表示插入的字节码的源代码。
它必须是单个语句或代码块。

因此,请使用花括号将代码包装起来,以使其成为单个代码块。

英文:

The javadoc for insertBefore says:

https://www.javassist.org/html/javassist/CtBehavior.html#insertBefore(java.lang.String)

> Parameters: src - the source code representing the inserted bytecode.
> It must be a single statement or block.

So, wrap the code in curly braces so it is a single block.

答案2

得分: 1

我通过替换 for 循环解决了我的错误。

似乎 javaassit 不支持方便的 for 循环,必须将其改成 for(int i= 0; i< lenth; i++) 格式;

还要感谢 @kutschem,代码还需要用大括号括起来。

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 &lt; bindings.getBindValues().length; i++ ) sql = sql.replaceFirst(\"\\\\?\", new String(bindings.getBindValues()[i].getByteValue()));\n" +
        "    System.out.println(sql);\n" +
        "}");

byteCode = cc.toBytecode();
英文:

I solved my bug by replacing the for loop.

It seems javaassit not support convient for loop, it has to be change it into for(int i= 0; i< lenth; i++) format;

And thanks to @kutschem , the code also need to be wrapped by curly braces.

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

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

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

        byteCode = cc.toBytecode();

答案3

得分: 0

除了像 @kutschem 所说的那样将您的代码用大括号括起来,我还有一个关于如何更轻松地连接字符串的想法,而不使用 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 自 Java 8 起可用。控制台输出将会是:

{
  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 的用法,用于将 ? 替换为固定值。

英文:

In addition to wrapping your code into curly braces like @kutschem said, I also have an idea for you how to concatenate your string more easily, without using a StringBuilder. As a positive side effect, you also get line breaks:

<!-- language: java -->

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

String.join is available since Java 8. The console output would be:

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

To me, your code looks okay syntactically, especially the replaceFirst meant to replace ? by a fixed value.

huangapple
  • 本文由 发表于 2020年9月4日 16:28:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/63737553.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定