英文:
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 < 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("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();
答案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("\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
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("\\?", 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论