aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Readme.html5
-rw-r--r--build.xml2
-rw-r--r--javassist.jarbin675292 -> 679163 bytes
-rw-r--r--src/main/javassist/bytecode/ClassFile.java5
-rw-r--r--src/main/javassist/util/proxy/ProxyFactory.java40
-rw-r--r--src/test/javassist/JvstTest2.java6
-rw-r--r--src/test/test/javassist/proxy/JBPAPP9257Test.java4
-rw-r--r--src/test/test1/Delegator.java2
-rw-r--r--src/test/testproxy/ProxyTester.java38
-rw-r--r--src/test/testproxy/Target127.java20
-rw-r--r--src/test/testproxy/Target189.java74
11 files changed, 173 insertions, 23 deletions
diff --git a/Readme.html b/Readme.html
index 259e4aa0..a96638e8 100644
--- a/Readme.html
+++ b/Readme.html
@@ -281,6 +281,11 @@ see javassist.Dump.
<h2>Changes</h2>
+<p>-version 3.18
+<ul>
+JIRA JASSIST-183, 189, 162.
+</ul>
+
<p>-version 3.17.1 on December 3, 2012
<ul>
<li>JIRA JASSIST-177, 178, 182
diff --git a/build.xml b/build.xml
index 48ea299b..391fbb5a 100644
--- a/build.xml
+++ b/build.xml
@@ -154,7 +154,7 @@ to ${build.classes.dir}.</echo>
</target>
<target name="jar" depends="compile14">
- <jar jarfile="${target.jar}" manifest="${src.dir}/META-INF/MANIFEST.MF">
+ <jar jarfile="${target.jar}" update="true" manifest="${src.dir}/META-INF/MANIFEST.MF">
<fileset dir="${build.classes.dir}">
<include name="**/*.class"/>
</fileset>
diff --git a/javassist.jar b/javassist.jar
index 2a98f983..5f207309 100644
--- a/javassist.jar
+++ b/javassist.jar
Binary files differ
diff --git a/src/main/javassist/bytecode/ClassFile.java b/src/main/javassist/bytecode/ClassFile.java
index 307cc0e8..a7d53fc9 100644
--- a/src/main/javassist/bytecode/ClassFile.java
+++ b/src/main/javassist/bytecode/ClassFile.java
@@ -690,12 +690,15 @@ public final class ClassFile {
if (notBridgeMethod(minfo))
return true;
else {
+ // if the bridge method with the same signature
+ // already exists, replace it.
it.remove();
return false;
}
}
else
- return notBridgeMethod(minfo) && notBridgeMethod(newMethod);
+ return false;
+ // return notBridgeMethod(minfo) && notBridgeMethod(newMethod);
}
/* For a bridge method, see Sec. 15.12.4.5 of JLS 3rd Ed.
diff --git a/src/main/javassist/util/proxy/ProxyFactory.java b/src/main/javassist/util/proxy/ProxyFactory.java
index 957ba8f1..88636c01 100644
--- a/src/main/javassist/util/proxy/ProxyFactory.java
+++ b/src/main/javassist/util/proxy/ProxyFactory.java
@@ -800,9 +800,9 @@ public class ProxyFactory {
{
checkClassAndSuperName();
+ hasGetHandler = false; // getMethods() may set this to true.
HashMap allMethods = getMethods(superClass, interfaces);
signatureMethods = new ArrayList(allMethods.entrySet());
- hasGetHandler = allMethods.get(HANDLER_GETTER_KEY) != null;
Collections.sort(signatureMethods, sorter);
}
@@ -981,17 +981,22 @@ public class ProxyFactory {
Map.Entry e = (Map.Entry)it.next();
String key = (String)e.getKey();
Method meth = (Method)e.getValue();
- int mod = meth.getModifiers();
- if (testBit(signature, index)) {
- override(className, meth, prefix, index,
- keyToDesc(key, meth), cf, cp, forwarders);
- }
+ if (ClassFile.MAJOR_VERSION < ClassFile.JAVA_5 || !isBridge(meth))
+ if (testBit(signature, index)) {
+ override(className, meth, prefix, index,
+ keyToDesc(key, meth), cf, cp, forwarders);
+ }
+
index++;
}
return index;
}
+ private static boolean isBridge(Method m) {
+ return m.isBridge();
+ }
+
private void override(String thisClassname, Method meth, String prefix,
int index, String desc, ClassFile cf, ConstPool cp, ArrayList forwarders)
throws CannotCompileException
@@ -1083,7 +1088,9 @@ public class ProxyFactory {
return name.substring(0, i);
}
- private static HashMap getMethods(Class superClass, Class[] interfaceTypes) {
+ /* getMethods() may set hasGetHandler to true.
+ */
+ private HashMap getMethods(Class superClass, Class[] interfaceTypes) {
HashMap hash = new HashMap();
HashSet set = new HashSet();
for (int i = 0; i < interfaceTypes.length; i++)
@@ -1093,7 +1100,7 @@ public class ProxyFactory {
return hash;
}
- private static void getMethods(HashMap hash, Class clazz, Set visitedClasses) {
+ private void getMethods(HashMap hash, Class clazz, Set visitedClasses) {
// This both speeds up scanning by avoiding duplicate interfaces and is needed to
// ensure that superinterfaces are always scanned before subinterfaces.
if (!visitedClasses.add(clazz))
@@ -1107,12 +1114,19 @@ public class ProxyFactory {
if (parent != null)
getMethods(hash, parent, visitedClasses);
+ /* Java 5 or later allows covariant return types.
+ * It also allows contra-variant parameter types
+ * if a super class is a generics with concrete type arguments
+ * such as Foo<String>. So the method-overriding rule is complex.
+ */
Method[] methods = SecurityActions.getDeclaredMethods(clazz);
for (int i = 0; i < methods.length; i++)
if (!Modifier.isPrivate(methods[i].getModifiers())) {
Method m = methods[i];
- // JIRA JASSIST-127 (covariant return types).
- String key = m.getName() + ':' + RuntimeSupport.makeDescriptor(m.getParameterTypes(), null);
+ String key = m.getName() + ':' + RuntimeSupport.makeDescriptor(m); // see keyToDesc().
+ if (key.startsWith(HANDLER_GETTER_KEY))
+ hasGetHandler = true;
+
// JIRA JASSIST-85
// put the method to the cache, retrieve previous definition (if any)
Method oldMethod = (Method)hash.put(key, methods[i]);
@@ -1127,11 +1141,11 @@ public class ProxyFactory {
}
}
- private static final String HANDLER_GETTER_KEY = HANDLER_GETTER + ":()";
+ private static final String HANDLER_GETTER_KEY
+ = HANDLER_GETTER + ":()";
private static String keyToDesc(String key, Method m) {
- String params = key.substring(key.indexOf(':') + 1);
- return RuntimeSupport.makeDescriptor(params, m.getReturnType());
+ return key.substring(key.indexOf(':') + 1);
}
private static MethodInfo makeConstructor(String thisClassName, Constructor cons,
diff --git a/src/test/javassist/JvstTest2.java b/src/test/javassist/JvstTest2.java
index 71704e08..ad039c8c 100644
--- a/src/test/javassist/JvstTest2.java
+++ b/src/test/javassist/JvstTest2.java
@@ -436,14 +436,14 @@ public class JvstTest2 extends JvstTestRoot {
public void testAddMethod() throws Exception {
CtClass cc = sloader.get("test2.AddMethod");
- CtMethod m = CtNewMethod.make(
- "public void f() { return 1; }", cc);
+ CtMethod m = CtNewMethod.make(
+ "public int f() { return 1; }", cc);
try {
cc.addMethod(m);
fail();
}
catch (CannotCompileException e) {}
- CtMethod m2 = CtNewMethod.make(
+ CtMethod m2 = CtNewMethod.make(
"public void f(int i, int j) { return 1; }", cc);
cc.addMethod(m2);
try {
diff --git a/src/test/test/javassist/proxy/JBPAPP9257Test.java b/src/test/test/javassist/proxy/JBPAPP9257Test.java
index 0de07298..2cf2687a 100644
--- a/src/test/test/javassist/proxy/JBPAPP9257Test.java
+++ b/src/test/test/javassist/proxy/JBPAPP9257Test.java
@@ -27,13 +27,14 @@ public class JBPAPP9257Test extends TestCase {
// method.
}
};
- Foo foo = (Foo) c.newInstance();
+ Foo foo = (Foo)c.newInstance();
try {
((ProxyObject)foo).setHandler(mi);
fail("foo is a ProxyObject!");
} catch (ClassCastException e) {}
((Proxy)foo).setHandler(mi);
assertEquals("I'm doing something!", foo.doSomething());
+ assertEquals("This is a secret handler!", foo.getHandler());
}
public void testGetHandler2() throws Exception {
@@ -61,5 +62,6 @@ public class JBPAPP9257Test extends TestCase {
} catch (ClassCastException e) {}
((Proxy)foo).setHandler(mi);
assertEquals("do something!", foo.doSomething());
+ assertEquals("return a string!", foo.getHandler());
}
}
diff --git a/src/test/test1/Delegator.java b/src/test/test1/Delegator.java
index c3108b96..9ca93b8e 100644
--- a/src/test/test1/Delegator.java
+++ b/src/test/test1/Delegator.java
@@ -1,7 +1,7 @@
package test1;
class SuperDelegator {
- public int f(int p) { return p + 1; }
+ public int f(int p) { return p + 1; }
public static int g(int p) { return p + 1; }
}
diff --git a/src/test/testproxy/ProxyTester.java b/src/test/testproxy/ProxyTester.java
index fe956f5e..6d5559b6 100644
--- a/src/test/testproxy/ProxyTester.java
+++ b/src/test/testproxy/ProxyTester.java
@@ -26,9 +26,9 @@ public class ProxyTester extends TestCase {
public Object invoke(Object self, Method m, Method proceed,
Object[] args) throws Exception {
- System.out.println("intercept: " + m + ", proceed: " + proceed
- + ", modifier: "
- + Modifier.toString(proceed.getModifiers()));
+ System.out.println("intercept: " + m + ", proceed: " + proceed);
+ System.out.println(" modifier: "
+ + Modifier.toString(proceed.getModifiers()));
counter++;
return proceed.invoke(self, args);
}
@@ -396,6 +396,38 @@ public class ProxyTester extends TestCase {
public Object writeReplace(int i) { return new Integer(i); }
}
+ public static void testJIRA189() throws Exception {
+ Class persistentClass = Target189.PublishedArticle.class;
+ ProxyFactory factory = new ProxyFactory();
+ factory.writeDirectory = ".";
+ factory.setUseCache(false);
+ factory.setSuperclass(persistentClass);
+ factory.setInterfaces(new Class[] { Target189.TestProxy.class });
+ Class cl = factory.createClass();
+ Target189.TestProxy proxy = (Target189.TestProxy)cl.newInstance();
+ Target189.TestMethodHandler methodHandler = new Target189.TestMethodHandler();
+ ((ProxyObject)proxy).setHandler(methodHandler);
+ ((Target189.Article)proxy).getIssue();
+ assertTrue(methodHandler.wasInvokedOnce());
+ methodHandler.reset();
+ Target189.PublishedArticle article = (Target189.PublishedArticle)proxy;
+ article.getIssue();
+ assertTrue(methodHandler.wasInvokedOnce());
+ }
+
+ public void testJIRA127() throws Exception {
+ ProxyFactory proxyFactory = new ProxyFactory();
+ proxyFactory.writeDirectory = ".";
+ proxyFactory.setInterfaces(new Class[]{ Target127.Sub.class });
+ Target127.Sub proxy = (Target127.Sub)proxyFactory.create(new Class[0], new Object[0], new MethodHandler() {
+ public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
+ return null;
+ }
+ });
+ ((Target127.Super)proxy).item(); // proxyFactory must generate a bridge method.
+ ((Target127.Sub)proxy).item();
+ }
+
public static void main(String[] args) {
// javassist.bytecode.ClassFile.MAJOR_VERSION = javassist.bytecode.ClassFile.JAVA_6;
junit.textui.TestRunner.run(ProxyTester.class);
diff --git a/src/test/testproxy/Target127.java b/src/test/testproxy/Target127.java
new file mode 100644
index 00000000..aeb6fe25
--- /dev/null
+++ b/src/test/testproxy/Target127.java
@@ -0,0 +1,20 @@
+package testproxy;
+
+public class Target127 {
+ public interface Item { }
+ public interface CovariantItem extends Item { }
+
+ public interface Super {
+ Item item();
+ }
+
+ public interface Sub extends Super {
+ CovariantItem item();
+ }
+
+ public static class RealSub implements Sub {
+ public CovariantItem item() {
+ return null;
+ }
+ }
+}
diff --git a/src/test/testproxy/Target189.java b/src/test/testproxy/Target189.java
new file mode 100644
index 00000000..ebe7805e
--- /dev/null
+++ b/src/test/testproxy/Target189.java
@@ -0,0 +1,74 @@
+package testproxy;
+
+import javassist.util.proxy.MethodHandler;
+import java.lang.reflect.Method;
+
+public class Target189 {
+ public interface TestProxy {
+ }
+
+ public static class TestMethodHandler implements MethodHandler {
+
+ int invoked = 0;
+
+ public Object invoke(Object self, Method thisMethod, Method proceed,
+ Object[] args) throws Throwable {
+ invoked++;
+ return proceed.invoke(self, args);
+ }
+
+ public boolean wasInvokedOnce() {
+ return invoked == 1;
+ }
+
+ public void reset() {
+ invoked = 0;
+ }
+ }
+
+ public static class Issue {
+
+ private Integer id;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+ }
+
+ public static class PublishedIssue extends Issue {
+ }
+
+ public static abstract class Article {
+ private Integer id;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public abstract Issue getIssue();
+ }
+
+ public static class PublishedArticle extends Article {
+
+ private PublishedIssue issue;
+
+ @Override
+ public PublishedIssue getIssue() {
+ return issue;
+ }
+
+ public void setIssue(PublishedIssue issue) {
+ this.issue = issue;
+ }
+
+ }
+
+}