[jboss-jira] [JBoss JIRA] (JASSIST-221) Got NPE when replacing a method in `instrument()`

Goro Fuji (JIRA) issues at jboss.org
Sun May 4 23:13:56 EDT 2014


     [ https://issues.jboss.org/browse/JASSIST-221?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Goro Fuji updated JASSIST-221:
------------------------------

    Description: 
I'm trying to modify some code in static initializer with {{m.replace("$_ = ($r)false;")}}, but I got NPE:

{code}
Caused by: java.lang.NullPointerException
	at javassist.bytecode.ConstPool.getMethodrefNameAndType(ConstPool.java:418)
	at javassist.expr.MethodCall.getNameAndType(MethodCall.java:43)
	at javassist.expr.MethodCall.getMethodName(MethodCall.java:107)
	at com.github.gfx.debugassert.DebugAssertPlugin$2.edit(DebugAssertPlugin.groovy:82)
	at javassist.expr.ExprEditor.loopBody(ExprEditor.java:192)
	at javassist.expr.ExprEditor.doit(ExprEditor.java:91)
	at javassist.CtBehavior.instrument(CtBehavior.java:712)
	at javassist.CtBehavior$instrument.call(Unknown Source)
{code}

I guess it is because the static initializer has no method name, but ClassPool expects a method (behavior) should have a name.

ref. https://github.com/jboss-javassist/javassist/blob/master/src/main/javassist/bytecode/ConstPool.java#L418

The NEP is thrown there: https://github.com/gfx/Gradle-DebugAssertPlugin/blob/master/buildSrc/src/main/groovy/com/github/gfx/debugassert/DebugAssertPlugin.groovy#L82-82
(Currently I use a patched version of javassist which is stored in the repo, so the project works as expected.)

{code}
// line 77 at DebugAssertPlugin.groovy
CtClass c = classPool.getCtClass(className)
c.getClassInitializer()?.instrument(new ExprEditor() {
    @Override
    void edit(MethodCall m) throws CannotCompileException {
        if (m.className == "java.lang.Class" && m.methodName == "desiredAssertionStatus") {
            m.replace('{ $_ = ($r)true; }') // raises NPE!
        }
    }
})
{code}

FYI, I have correct results with the following patch:

{code}
diff --git a/src/main/javassist/bytecode/ConstPool.java b/src/main/javassist/bytecode/ConstPool.java
index f102421..9e62c89 100644
--- a/src/main/javassist/bytecode/ConstPool.java
+++ b/src/main/javassist/bytecode/ConstPool.java
@@ -265,6 +265,9 @@ public final class ConstPool {
      */
     public int getNameAndTypeName(int index) {
         NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index);
+        if (ntinfo == null) {
+            return 0;
+        }
         return ntinfo.memberName;
     }
 
@@ -415,6 +418,9 @@ public final class ConstPool {
      */
     public int getMethodrefNameAndType(int index) {
         MethodrefInfo minfo = (MethodrefInfo)getItem(index);
+        if (minfo == null) {
+            return 0;
+        }
         return minfo.nameAndTypeIndex;
     }
 
@@ -635,6 +641,9 @@ public final class ConstPool {
      */
     public String getUtf8Info(int index) {
         Utf8Info utf = (Utf8Info)getItem(index);
+        if (utf == null) {
+            return null;
+        }
         return utf.string;
     }
{code}


  was:
I'm trying to modify some code in static initializer with {{m.replace("$_ = ($r)false;")}}, but I got NPE:

{code}
Caused by: java.lang.NullPointerException
	at javassist.bytecode.ConstPool.getMethodrefNameAndType(ConstPool.java:418)
	at javassist.expr.MethodCall.getNameAndType(MethodCall.java:43)
	at javassist.expr.MethodCall.getMethodName(MethodCall.java:107)
	at com.github.gfx.javassistexamp.JavassistExample$2.edit(JavassistExample.groovy:29)
	at javassist.expr.ExprEditor.loopBody(ExprEditor.java:192)
	at javassist.expr.ExprEditor.doit(ExprEditor.java:91)
	at javassist.CtBehavior.instrument(CtBehavior.java:712)
	at javassist.CtBehavior$instrument.call(Unknown Source)
{code}

I guess it is because the static initializer has no method name, but ClassPool expects a method (behavior) should have a name.

ref. https://github.com/jboss-javassist/javassist/blob/master/src/main/javassist/bytecode/ConstPool.java#L418

The NEP is caused by here: https://github.com/gfx/Gradle-DebugAssertPlugin/blob/master/buildSrc/src/main/groovy/com/github/gfx/debugassert/DebugAssertPlugin.groovy#L82-82
(Currently I use a patched version of javassist which is stored in the repo, so the project works as expected.)

FYI, I have correct results with the following patch:

{code}
diff --git a/src/main/javassist/bytecode/ConstPool.java b/src/main/javassist/bytecode/ConstPool.java
index f102421..9e62c89 100644
--- a/src/main/javassist/bytecode/ConstPool.java
+++ b/src/main/javassist/bytecode/ConstPool.java
@@ -265,6 +265,9 @@ public final class ConstPool {
      */
     public int getNameAndTypeName(int index) {
         NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index);
+        if (ntinfo == null) {
+            return 0;
+        }
         return ntinfo.memberName;
     }
 
@@ -415,6 +418,9 @@ public final class ConstPool {
      */
     public int getMethodrefNameAndType(int index) {
         MethodrefInfo minfo = (MethodrefInfo)getItem(index);
+        if (minfo == null) {
+            return 0;
+        }
         return minfo.nameAndTypeIndex;
     }
 
@@ -635,6 +641,9 @@ public final class ConstPool {
      */
     public String getUtf8Info(int index) {
         Utf8Info utf = (Utf8Info)getItem(index);
+        if (utf == null) {
+            return null;
+        }
         return utf.string;
     }
{code}




> Got NPE when replacing a method in `instrument()` 
> --------------------------------------------------
>
>                 Key: JASSIST-221
>                 URL: https://issues.jboss.org/browse/JASSIST-221
>             Project: Javassist
>          Issue Type: Bug
>    Affects Versions: 3.18.1-GA
>         Environment: JDK8 (build 1.8.0-b132) / Mac OSX 10.9.2
>            Reporter: Goro Fuji
>            Assignee: Shigeru Chiba
>
> I'm trying to modify some code in static initializer with {{m.replace("$_ = ($r)false;")}}, but I got NPE:
> {code}
> Caused by: java.lang.NullPointerException
> 	at javassist.bytecode.ConstPool.getMethodrefNameAndType(ConstPool.java:418)
> 	at javassist.expr.MethodCall.getNameAndType(MethodCall.java:43)
> 	at javassist.expr.MethodCall.getMethodName(MethodCall.java:107)
> 	at com.github.gfx.debugassert.DebugAssertPlugin$2.edit(DebugAssertPlugin.groovy:82)
> 	at javassist.expr.ExprEditor.loopBody(ExprEditor.java:192)
> 	at javassist.expr.ExprEditor.doit(ExprEditor.java:91)
> 	at javassist.CtBehavior.instrument(CtBehavior.java:712)
> 	at javassist.CtBehavior$instrument.call(Unknown Source)
> {code}
> I guess it is because the static initializer has no method name, but ClassPool expects a method (behavior) should have a name.
> ref. https://github.com/jboss-javassist/javassist/blob/master/src/main/javassist/bytecode/ConstPool.java#L418
> The NEP is thrown there: https://github.com/gfx/Gradle-DebugAssertPlugin/blob/master/buildSrc/src/main/groovy/com/github/gfx/debugassert/DebugAssertPlugin.groovy#L82-82
> (Currently I use a patched version of javassist which is stored in the repo, so the project works as expected.)
> {code}
> // line 77 at DebugAssertPlugin.groovy
> CtClass c = classPool.getCtClass(className)
> c.getClassInitializer()?.instrument(new ExprEditor() {
>     @Override
>     void edit(MethodCall m) throws CannotCompileException {
>         if (m.className == "java.lang.Class" && m.methodName == "desiredAssertionStatus") {
>             m.replace('{ $_ = ($r)true; }') // raises NPE!
>         }
>     }
> })
> {code}
> FYI, I have correct results with the following patch:
> {code}
> diff --git a/src/main/javassist/bytecode/ConstPool.java b/src/main/javassist/bytecode/ConstPool.java
> index f102421..9e62c89 100644
> --- a/src/main/javassist/bytecode/ConstPool.java
> +++ b/src/main/javassist/bytecode/ConstPool.java
> @@ -265,6 +265,9 @@ public final class ConstPool {
>       */
>      public int getNameAndTypeName(int index) {
>          NameAndTypeInfo ntinfo = (NameAndTypeInfo)getItem(index);
> +        if (ntinfo == null) {
> +            return 0;
> +        }
>          return ntinfo.memberName;
>      }
>  
> @@ -415,6 +418,9 @@ public final class ConstPool {
>       */
>      public int getMethodrefNameAndType(int index) {
>          MethodrefInfo minfo = (MethodrefInfo)getItem(index);
> +        if (minfo == null) {
> +            return 0;
> +        }
>          return minfo.nameAndTypeIndex;
>      }
>  
> @@ -635,6 +641,9 @@ public final class ConstPool {
>       */
>      public String getUtf8Info(int index) {
>          Utf8Info utf = (Utf8Info)getItem(index);
> +        if (utf == null) {
> +            return null;
> +        }
>          return utf.string;
>      }
> {code}



--
This message was sent by Atlassian JIRA
(v6.2.3#6260)


More information about the jboss-jira mailing list