From a0f4d935a20ffeefcfe4c66730ec702b7fff0928 Mon Sep 17 00:00:00 2001 From: chibash Date: Tue, 18 Nov 2014 15:43:31 +0900 Subject: [PATCH] fixed JASSIST-235. Now CtClass.getEnclosingMethod() is deprecated due to its potential bug. --- Readme.html | 2 +- src/main/javassist/CtClass.java | 23 ++++++++++++++++++- src/main/javassist/CtClassType.java | 18 +++++++++++---- .../bytecode/EnclosingMethodAttribute.java | 12 ++++++++-- src/test/Test.java | 6 +++-- src/test/javassist/JvstTest2.java | 11 +++++++++ src/test/test2/Anon.java | 11 +++++++++ 7 files changed, 72 insertions(+), 11 deletions(-) diff --git a/Readme.html b/Readme.html index 320660a0..354af82a 100644 --- a/Readme.html +++ b/Readme.html @@ -283,7 +283,7 @@ see javassist.Dump.

-version 3.19

diff --git a/src/main/javassist/CtClass.java b/src/main/javassist/CtClass.java index f34a565a..9e4ca20c 100644 --- a/src/main/javassist/CtClass.java +++ b/src/main/javassist/CtClass.java @@ -762,8 +762,29 @@ public abstract class CtClass { * * @return null if this class is not a local class or an anonymous * class. + * @deprecated The enclosing method might be a constructor. + * Use {@link #getEnclosingBehavior()}. + * @see #getEnclosingBehavior() */ - public CtMethod getEnclosingMethod() throws NotFoundException { + public final CtMethod getEnclosingMethod() throws NotFoundException { + CtBehavior b = getEnclosingBehavior(); + if (b == null) + return null; + else if (b instanceof CtMethod) + return (CtMethod)b; + else + throw new NotFoundException(b.getLongName() + " is enclosing " + getName()); + } + + /** + * Returns the immediately enclosing method of this class. + * It might be not a method but a constructor. + * This method works only with JDK 1.5 or later. + * + * @return null if this class is not a local class or an anonymous + * class. + */ + public CtBehavior getEnclosingBehavior() throws NotFoundException { return null; } diff --git a/src/main/javassist/CtClassType.java b/src/main/javassist/CtClassType.java index 4d10b5dd..4df382a9 100644 --- a/src/main/javassist/CtClassType.java +++ b/src/main/javassist/CtClassType.java @@ -772,17 +772,25 @@ class CtClassType extends CtClass { return null; } - public CtMethod getEnclosingMethod() throws NotFoundException { + public CtBehavior getEnclosingBehavior() throws NotFoundException { ClassFile cf = getClassFile2(); EnclosingMethodAttribute ema = (EnclosingMethodAttribute)cf.getAttribute( EnclosingMethodAttribute.tag); - if (ema != null) { + if (ema == null) + return null; + else { CtClass enc = classPool.get(ema.className()); - return enc.getMethod(ema.methodName(), ema.methodDescriptor()); + String name = ema.methodName(); + switch (name) { + case MethodInfo.nameInit: + return enc.getConstructor(ema.methodDescriptor()); + case MethodInfo.nameClinit: + return enc.getClassInitializer(); + default: + return enc.getMethod(name, ema.methodDescriptor()); + } } - - return null; } public CtClass makeNestedClass(String name, boolean isStatic) { diff --git a/src/main/javassist/bytecode/EnclosingMethodAttribute.java b/src/main/javassist/bytecode/EnclosingMethodAttribute.java index d59955dd..4f422fd7 100644 --- a/src/main/javassist/bytecode/EnclosingMethodAttribute.java +++ b/src/main/javassist/bytecode/EnclosingMethodAttribute.java @@ -20,6 +20,8 @@ import java.io.DataInputStream; import java.io.IOException; import java.util.Map; +import javassist.CtConstructor; + /** * EnclosingMethod_attribute. */ @@ -98,12 +100,18 @@ public class EnclosingMethodAttribute extends AttributeInfo { /** * Returns the method name specified by method_index. + * If the method is a class initializer (static constructor), + * {@link MethodInfo#nameClinit} is returned. */ public String methodName() { ConstPool cp = getConstPool(); int mi = methodIndex(); - int ni = cp.getNameAndTypeName(mi); - return cp.getUtf8Info(ni); + if (mi == 0) + return MethodInfo.nameClinit; + else { + int ni = cp.getNameAndTypeName(mi); + return cp.getUtf8Info(ni); + } } /** diff --git a/src/test/Test.java b/src/test/Test.java index 83fe2954..a6d31c68 100644 --- a/src/test/Test.java +++ b/src/test/Test.java @@ -8,7 +8,9 @@ public class Test { } ClassPool cp = ClassPool.getDefault(); - CtClass str = cp.get("java.lang.String"); + CtClass inner3 = cp.get("test2.Anon$Anon2.1"); + CtBehavior ct = inner3.getEnclosingBehavior(); +/* CtClass str = cp.get("java.lang.String"); CtClass cc = cp.get("Test"); cc.getClassFile().setMajorVersion(javassist.bytecode.ClassFile.JAVA_4); CtMethod m = cc.getDeclaredMethod("bar"); @@ -16,7 +18,7 @@ public class Test { m.insertAfter(" dismiss( aVar );" , true); cc.getClassFile().setMajorVersion(javassist.bytecode.ClassFile.JAVA_7); m.insertBefore("aVar = initVar();"); - cc.writeFile(); + cc.writeFile();*/ } public void bar(int i) { foo(i); } diff --git a/src/test/javassist/JvstTest2.java b/src/test/javassist/JvstTest2.java index ad039c8c..411c1e97 100644 --- a/src/test/javassist/JvstTest2.java +++ b/src/test/javassist/JvstTest2.java @@ -523,6 +523,17 @@ public class JvstTest2 extends JvstTestRoot { assertEquals(out, inner.getEnclosingMethod().getDeclaringClass()); } + + assertNull(out.getEnclosingMethod()); + assertNull(out.getEnclosingBehavior()); + + CtClass inner2 = sloader.get("test2.Anon$Anon2$1"); + assertTrue(inner2.getEnclosingBehavior() instanceof CtConstructor); + assertEquals(sloader.get("test2.Anon$Anon2"), inner2.getEnclosingBehavior().getDeclaringClass()); + CtClass inner3 = sloader.get("test2.Anon$Anon3$1"); + assertTrue(inner3.getEnclosingBehavior() instanceof CtConstructor); + assertTrue(((CtConstructor)inner3.getEnclosingBehavior()).isClassInitializer()); + assertEquals(sloader.get("test2.Anon$Anon3"), inner3.getEnclosingBehavior().getDeclaringClass()); } public void testMethodInInner() throws Exception { diff --git a/src/test/test2/Anon.java b/src/test/test2/Anon.java index a6ccd8f0..56223436 100644 --- a/src/test/test2/Anon.java +++ b/src/test/test2/Anon.java @@ -4,4 +4,15 @@ public class Anon { public Object make() { return new Object() { int k; }; } + + public static class Anon2 { + Object obj; + public Anon2() { + obj = new Object() { int k; }; + } + } + + public static class Anon3 { + public static Object sobj = new Object() { int p; }; + } } -- 2.39.5