<h2>Changes</h2> | <h2>Changes</h2> | ||||
<p>-version 3.21 | |||||
<ul> | |||||
<li>JIRA JASSIST-244 | |||||
</ul> | |||||
</p> | |||||
<p>-version 3.20 on June 25, 2015 | <p>-version 3.20 on June 25, 2015 | ||||
<ul> | <ul> | ||||
<li>JIRA JASSIST-241, 242, 246. | <li>JIRA JASSIST-241, 242, 246. |
for (int i = 0; i < methods.length; i++) | for (int i = 0; i < methods.length; i++) | ||||
if (!Modifier.isPrivate(methods[i].getModifiers())) { | if (!Modifier.isPrivate(methods[i].getModifiers())) { | ||||
Method m = methods[i]; | Method m = methods[i]; | ||||
String key = m.getName() + ':' + RuntimeSupport.makeDescriptor(m); // see keyToDesc(). | |||||
String key = m.getName() + ':' + RuntimeSupport.makeDescriptor(m); // see keyToDesc(). | |||||
if (key.startsWith(HANDLER_GETTER_KEY)) | if (key.startsWith(HANDLER_GETTER_KEY)) | ||||
hasGetHandler = true; | hasGetHandler = true; | ||||
// JIRA JASSIST-85 | // JIRA JASSIST-85 | ||||
// put the method to the cache, retrieve previous definition (if any) | // put the method to the cache, retrieve previous definition (if any) | ||||
Method oldMethod = (Method)hash.put(key, methods[i]); | |||||
Method oldMethod = (Method)hash.put(key, m); | |||||
// JIRA JASSIST-244 | |||||
// ignore a bridge method with the same signature that the overridden one has. | |||||
if (null != oldMethod && isBridge(m) | |||||
&& !Modifier.isPublic(oldMethod.getDeclaringClass().getModifiers()) | |||||
&& !Modifier.isAbstract(oldMethod.getModifiers()) && !isOverloaded(i, methods)) | |||||
hash.put(key, oldMethod); | |||||
// check if visibility has been reduced | // check if visibility has been reduced | ||||
if (null != oldMethod && Modifier.isPublic(oldMethod.getModifiers()) | if (null != oldMethod && Modifier.isPublic(oldMethod.getModifiers()) | ||||
&& !Modifier.isPublic(methods[i].getModifiers()) ) { | |||||
&& !Modifier.isPublic(m.getModifiers()) ) { | |||||
// we tried to overwrite a public definition with a non-public definition, | // we tried to overwrite a public definition with a non-public definition, | ||||
// use the old definition instead. | // use the old definition instead. | ||||
hash.put(key, oldMethod); | hash.put(key, oldMethod); | ||||
} | } | ||||
} | } | ||||
private static boolean isOverloaded(int index, Method[] methods) { | |||||
String name = methods[index].getName(); | |||||
for (int i = 0; i < methods.length; i++) | |||||
if (i != index) | |||||
if (name.equals(methods[i].getName())) | |||||
return true; | |||||
return false; | |||||
} | |||||
private static final String HANDLER_GETTER_KEY | private static final String HANDLER_GETTER_KEY | ||||
= HANDLER_GETTER + ":()"; | = HANDLER_GETTER + ":()"; | ||||
public static class WriteReplace2 implements Serializable { | public static class WriteReplace2 implements Serializable { | ||||
public Object writeReplace(int i) { return new Integer(i); } | public Object writeReplace(int i) { return new Integer(i); } | ||||
} | } | ||||
String value244; | |||||
public void testJIRA244() throws Exception { | |||||
ProxyFactory factory = new ProxyFactory(); | |||||
factory.setSuperclass(Extended244.class); | |||||
Extended244 e = (Extended244)factory.create(null, null, new MethodHandler() { | |||||
@Override | |||||
public Object invoke(Object self, Method thisMethod, | |||||
Method proceed, Object[] args) throws Throwable { | |||||
value244 += thisMethod.getDeclaringClass().getName(); | |||||
return proceed.invoke(self); | |||||
} | |||||
}); | |||||
value244 = ""; | |||||
assertEquals("base", e.base()); | |||||
System.out.println(value244); | |||||
assertEquals(Extended244.class.getName(), value244); | |||||
value244 = ""; | |||||
assertEquals("ext", e.extended()); | |||||
System.out.println(value244); | |||||
assertEquals(Extended244.class.getName(), value244); | |||||
value244 = ""; | |||||
assertEquals("base2ext2", e.base2()); | |||||
System.out.println(value244); | |||||
assertEquals(Extended244.class.getName(), value244); | |||||
} | |||||
// if Base244 is private, then Extended244 has a bridge method for base(). | |||||
private static abstract class Base244 { | |||||
public String base() { return "base"; } | |||||
public String base2() { return "base2"; } | |||||
} | |||||
public static class Extended244 extends Base244 { | |||||
public String extended() { return "ext"; } | |||||
public String base2() { return super.base2() + "ext2"; } | |||||
} | |||||
} | } |
public static void testJIRA189() throws Exception { | public static void testJIRA189() throws Exception { | ||||
Class persistentClass = Target189.PublishedArticle.class; | Class persistentClass = Target189.PublishedArticle.class; | ||||
ProxyFactory factory = new ProxyFactory(); | ProxyFactory factory = new ProxyFactory(); | ||||
factory.writeDirectory = "."; | |||||
// factory.writeDirectory = "."; | |||||
factory.setUseCache(false); | factory.setUseCache(false); | ||||
factory.setSuperclass(persistentClass); | factory.setSuperclass(persistentClass); | ||||
factory.setInterfaces(new Class[] { Target189.TestProxy.class }); | factory.setInterfaces(new Class[] { Target189.TestProxy.class }); | ||||
public void testJIRA127() throws Exception { | public void testJIRA127() throws Exception { | ||||
ProxyFactory proxyFactory = new ProxyFactory(); | ProxyFactory proxyFactory = new ProxyFactory(); | ||||
proxyFactory.writeDirectory = "."; | |||||
// proxyFactory.writeDirectory = "."; | |||||
proxyFactory.setInterfaces(new Class[]{ Target127.Sub.class }); | proxyFactory.setInterfaces(new Class[]{ Target127.Sub.class }); | ||||
Target127.Sub proxy = (Target127.Sub)proxyFactory.create(new Class[0], new Object[0], new MethodHandler() { | 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 { | public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable { |