clone on a member array causes an NPE in MemberResolver when instrumenting
--------------------------------------------------------------------------
Key: JASSIST-61
URL:
http://jira.jboss.com/jira/browse/JASSIST-61
Project: Javassist
Issue Type: Bug
Environment: Javassist 3.7.1 (latest from cvs HEAD)
Eclipse Version: 3.3.1.1, Build id: M20071023-1652 running in the JRE included with
JDK1.6.0_03 on winXP and compiler compliance set to 5.0.
Show »
Javassist 3.7.1 (latest from cvs HEAD) Eclipse Version: 3.3.1.1, Build id: M20071023-1652
running in the JRE included with JDK1.6.0_03 on winXP and compiler compliance set to 5.0.
Reporter: Yanic Inghelbrecht
Assigned To: Shigeru Chiba
In the instrumentation of JHotDraw, I encountered an NPE in
javassist.compiler.MemberResolver#lookupMethod(...).
When replacing a method call with a trivial block, a null pointer exception occurs in
MemberResolver if that method calls clone() on a member array. The method that is being
looked up is the clone method.
The simplest testcase to reproduce this bug consists of two classes : Client (to be
instrumented) and Main (does the instrumentation).
It produces the following stack trace :
Exception in thread "main" java.lang.ClassNotFoundException: caught an exception
while obtaining a class file for test_clone_member_array.Client
at javassist.Loader.findClass(Loader.java:359)
at javassist.Loader.loadClass(Loader.java:311)
at java.lang.ClassLoader.loadClass(Unknown Source)
at test_clone_member_array.Main.main(Main.java:25)
Caused by: java.lang.NullPointerException
at javassist.compiler.MemberResolver.lookupMethod(MemberResolver.java:110)
at javassist.compiler.MemberResolver.lookupMethod(MemberResolver.java:96)
at javassist.compiler.TypeChecker.atMethodCallCore(TypeChecker.java:704)
at javassist.compiler.TypeChecker.atCallExpr(TypeChecker.java:681)
at javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:156)
at javassist.compiler.ast.CallExpr.accept(CallExpr.java:45)
at javassist.compiler.Javac$1.setReturnType(Javac.java:459)
at javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:146)
at javassist.compiler.ast.CallExpr.accept(CallExpr.java:45)
at javassist.compiler.TypeChecker.atVariableAssign(TypeChecker.java:248)
at javassist.compiler.TypeChecker.atAssignExpr(TypeChecker.java:217)
at javassist.compiler.ast.AssignExpr.accept(AssignExpr.java:38)
at javassist.compiler.CodeGen.doTypeCheck(CodeGen.java:241)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:329)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
at javassist.compiler.CodeGen.atStmnt(CodeGen.java:350)
at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
at javassist.compiler.Javac.compileStmnt(Javac.java:568)
at javassist.expr.MethodCall.replace(MethodCall.java:234)
at test_clone_member_array.Main$MyTranslator.edit(Main.java:48)
at javassist.expr.ExprEditor.loopBody(ExprEditor.java:191)
at javassist.expr.ExprEditor.doit(ExprEditor.java:90)
at javassist.CtBehavior.instrument(CtBehavior.java:548)
at test_clone_member_array.Main$MyTranslator.modify(Main.java:40)
at test_clone_member_array.Main$MyTranslator.onLoad(Main.java:35)
at javassist.Loader.findClass(Loader.java:340)
... 3 more
The source code for this testcase :
// ----- file Client.java
package test_clone_member_array;
public class Client {
private Object[] oa;
public void test() throws Exception {
this.oa.clone();
}
}
// ----- file Main.java
package test_clone_member_array;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Loader;
import javassist.NotFoundException;
import javassist.Translator;
import javassist.expr.ExprEditor;
import javassist.expr.MethodCall;
public class Main {
public static void main(String[] args) throws Exception {
ClassPool pool = new ClassPool(true);
Loader cl = new Loader();
try {
cl.addTranslator(pool, new MyTranslator());
} catch (Exception e) {
e.printStackTrace();
return;
}
// load the Client class
Class clientClass=cl.loadClass("test_clone_member_array.Client");
// create an instance
Object client=clientClass.newInstance();
}
static public class MyTranslator extends ExprEditor implements Translator {
public void onLoad(ClassPool pool, String classname) throws NotFoundException,
CannotCompileException {
CtClass cc = pool.get(classname);
modify(cc);
}
public void modify(CtClass c) throws CannotCompileException {
for (CtMethod m : c.getMethods()) {
m.instrument(this);
}
}
@Override
public void edit(MethodCall mc) throws CannotCompileException {
// no changes, for simplicity's sake
String block = "{$_=$proceed($$);}";
mc.replace(block);
}
public void start(ClassPool pool) throws NotFoundException, CannotCompileException {
// do nothing
}
}
}
I hope it's an easy fix for you, I did not find a usable workaround.
Thanks in advance.
Best regards,
Yanic
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira