1*f1fbf3c2SXin Li /* 2*f1fbf3c2SXin Li * Javassist, a Java-bytecode translator toolkit. 3*f1fbf3c2SXin Li * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved. 4*f1fbf3c2SXin Li * 5*f1fbf3c2SXin Li * The contents of this file are subject to the Mozilla Public License Version 6*f1fbf3c2SXin Li * 1.1 (the "License"); you may not use this file except in compliance with 7*f1fbf3c2SXin Li * the License. Alternatively, the contents of this file may be used under 8*f1fbf3c2SXin Li * the terms of the GNU Lesser General Public License Version 2.1 or later, 9*f1fbf3c2SXin Li * or the Apache License Version 2.0. 10*f1fbf3c2SXin Li * 11*f1fbf3c2SXin Li * Software distributed under the License is distributed on an "AS IS" basis, 12*f1fbf3c2SXin Li * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 13*f1fbf3c2SXin Li * for the specific language governing rights and limitations under the 14*f1fbf3c2SXin Li * License. 15*f1fbf3c2SXin Li */ 16*f1fbf3c2SXin Li package scoped; 17*f1fbf3c2SXin Li 18*f1fbf3c2SXin Li import java.io.File; 19*f1fbf3c2SXin Li import java.lang.reflect.Method; 20*f1fbf3c2SXin Li import java.math.BigDecimal; 21*f1fbf3c2SXin Li import java.net.URL; 22*f1fbf3c2SXin Li import java.net.URLClassLoader; 23*f1fbf3c2SXin Li import java.util.Arrays; 24*f1fbf3c2SXin Li import java.util.Map; 25*f1fbf3c2SXin Li import java.util.stream.LongStream; 26*f1fbf3c2SXin Li 27*f1fbf3c2SXin Li import javassist.ClassPool; 28*f1fbf3c2SXin Li import javassist.CtClass; 29*f1fbf3c2SXin Li import javassist.CtConstructor; 30*f1fbf3c2SXin Li import javassist.CtField; 31*f1fbf3c2SXin Li import javassist.CtMethod; 32*f1fbf3c2SXin Li import javassist.scopedpool.ScopedClassPool; 33*f1fbf3c2SXin Li import javassist.scopedpool.ScopedClassPoolRepository; 34*f1fbf3c2SXin Li import javassist.scopedpool.ScopedClassPoolRepositoryImpl; 35*f1fbf3c2SXin Li import javassist.scopedpool.SoftValueHashMap; 36*f1fbf3c2SXin Li import junit.framework.TestCase; 37*f1fbf3c2SXin Li 38*f1fbf3c2SXin Li 39*f1fbf3c2SXin Li /** 40*f1fbf3c2SXin Li * ScopedRepositoryTest. 41*f1fbf3c2SXin Li * 42*f1fbf3c2SXin Li * @author <a href="[email protected]">Adrian Brock</a> 43*f1fbf3c2SXin Li * @version $Revision$ 44*f1fbf3c2SXin Li */ 45*f1fbf3c2SXin Li public class ScopedRepositoryTestCase extends TestCase 46*f1fbf3c2SXin Li { 47*f1fbf3c2SXin Li private static final ScopedClassPoolRepository repository = ScopedClassPoolRepositoryImpl.getInstance(); 48*f1fbf3c2SXin Li testJDKClasses()49*f1fbf3c2SXin Li public void testJDKClasses() throws Exception 50*f1fbf3c2SXin Li { 51*f1fbf3c2SXin Li ClassPool poolClass = repository.findClassPool(Class.class.getClassLoader()); 52*f1fbf3c2SXin Li assertNotNull(poolClass); 53*f1fbf3c2SXin Li ClassPool poolString = repository.findClassPool(String.class.getClassLoader()); 54*f1fbf3c2SXin Li assertNotNull(poolString); 55*f1fbf3c2SXin Li assertEquals(poolClass, poolString); 56*f1fbf3c2SXin Li } 57*f1fbf3c2SXin Li testScopedClasses()58*f1fbf3c2SXin Li public void testScopedClasses() throws Exception 59*f1fbf3c2SXin Li { 60*f1fbf3c2SXin Li ClassLoader cl = getURLClassLoader("test-classes14-jar1"); 61*f1fbf3c2SXin Li ClassPool pool1 = repository.findClassPool(cl); 62*f1fbf3c2SXin Li CtClass clazz = pool1.get("scoped.jar1.TestClass1"); 63*f1fbf3c2SXin Li assertNotNull(clazz); 64*f1fbf3c2SXin Li ClassPool poolClass = repository.findClassPool(Class.class.getClassLoader()); 65*f1fbf3c2SXin Li assertNotNull(poolClass); 66*f1fbf3c2SXin Li assertNotSame(pool1, poolClass); 67*f1fbf3c2SXin Li } 68*f1fbf3c2SXin Li testUnscopedAnnotationUsage()69*f1fbf3c2SXin Li public void testUnscopedAnnotationUsage() throws Exception 70*f1fbf3c2SXin Li { 71*f1fbf3c2SXin Li CtClass clazz = getCtClass(UnscopedAnnotationUsage.class); 72*f1fbf3c2SXin Li checkTestAnnotation(clazz, "notDefault"); 73*f1fbf3c2SXin Li } 74*f1fbf3c2SXin Li testUnscopedAnnotationDefaultUsage()75*f1fbf3c2SXin Li public void testUnscopedAnnotationDefaultUsage() throws Exception 76*f1fbf3c2SXin Li { 77*f1fbf3c2SXin Li CtClass clazz = getCtClass(UnscopedAnnotationDefaultUsage.class); 78*f1fbf3c2SXin Li checkTestAnnotation(clazz, "defaultValue"); 79*f1fbf3c2SXin Li } 80*f1fbf3c2SXin Li testScopedAnnotationUsage()81*f1fbf3c2SXin Li public void testScopedAnnotationUsage() throws Exception 82*f1fbf3c2SXin Li { 83*f1fbf3c2SXin Li ClassLoader cl = getURLClassLoader("test-classes14-jar1"); 84*f1fbf3c2SXin Li CtClass clazz = getCtClass("scoped.jar1.ScopedAnnotationUsage", cl); 85*f1fbf3c2SXin Li checkTestAnnotation(clazz, "notDefault"); 86*f1fbf3c2SXin Li } 87*f1fbf3c2SXin Li testScopedAnnotationDefaultUsage()88*f1fbf3c2SXin Li public void testScopedAnnotationDefaultUsage() throws Exception 89*f1fbf3c2SXin Li { 90*f1fbf3c2SXin Li ClassLoader cl = getURLClassLoader("test-classes14-jar1"); 91*f1fbf3c2SXin Li CtClass clazz = getCtClass("scoped.jar1.ScopedAnnotationDefaultUsage", cl); 92*f1fbf3c2SXin Li checkTestAnnotation(clazz, "defaultValue"); 93*f1fbf3c2SXin Li } 94*f1fbf3c2SXin Li testFullyScopedAnnotationUsage()95*f1fbf3c2SXin Li public void testFullyScopedAnnotationUsage() throws Exception 96*f1fbf3c2SXin Li { 97*f1fbf3c2SXin Li ClassLoader cl = getURLClassLoader("test-classes14-jar1"); 98*f1fbf3c2SXin Li CtClass clazz = getCtClass("scoped.jar1.FullyScopedAnnotationUsage", cl); 99*f1fbf3c2SXin Li checkScopedAnnotation(cl, clazz, "notDefault"); 100*f1fbf3c2SXin Li } 101*f1fbf3c2SXin Li testFullyScopedAnnotationDefaultUsage()102*f1fbf3c2SXin Li public void testFullyScopedAnnotationDefaultUsage() throws Exception 103*f1fbf3c2SXin Li { 104*f1fbf3c2SXin Li ClassLoader cl = getURLClassLoader("test-classes14-jar1"); 105*f1fbf3c2SXin Li CtClass clazz = getCtClass("scoped.jar1.FullyScopedAnnotationDefaultUsage", cl); 106*f1fbf3c2SXin Li checkScopedAnnotation(cl, clazz, "defaultValue"); 107*f1fbf3c2SXin Li } 108*f1fbf3c2SXin Li testSoftValueHashMap()109*f1fbf3c2SXin Li public void testSoftValueHashMap() throws Exception { 110*f1fbf3c2SXin Li Map<String,Class<?>> map = new SoftValueHashMap<>(); 111*f1fbf3c2SXin Li Class<?> cls = this.getClass(); 112*f1fbf3c2SXin Li assertTrue(map.put(cls.getName(), cls) == null); 113*f1fbf3c2SXin Li assertTrue(map.put(cls.getName(), cls) == cls); 114*f1fbf3c2SXin Li assertTrue(map.size() == 1); 115*f1fbf3c2SXin Li assertTrue(map.get(cls.getName()) == cls); 116*f1fbf3c2SXin Li assertTrue(map.values().iterator().next() == cls); 117*f1fbf3c2SXin Li assertTrue(map.entrySet().iterator().next().getValue() == cls); 118*f1fbf3c2SXin Li assertTrue(map.containsValue(cls)); 119*f1fbf3c2SXin Li assertTrue(map.remove(cls.getName()) == cls); 120*f1fbf3c2SXin Li assertTrue(map.size() == 0); 121*f1fbf3c2SXin Li } 122*f1fbf3c2SXin Li testSoftCache()123*f1fbf3c2SXin Li public void testSoftCache() throws Exception { 124*f1fbf3c2SXin Li // Overload the heap to test that the map auto cleans 125*f1fbf3c2SXin Li Map<String,long[]> map = new SoftValueHashMap<>(); 126*f1fbf3c2SXin Li // 12+8*30000000 = +- 252 MB 127*f1fbf3c2SXin Li long[] data = LongStream.range(0, 30000000).toArray(); 128*f1fbf3c2SXin Li int current = map.size(); 129*f1fbf3c2SXin Li while (current <= map.size()) { 130*f1fbf3c2SXin Li current = map.size(); 131*f1fbf3c2SXin Li for (int ii = 0; ii < 5; ii++) { 132*f1fbf3c2SXin Li map.put(current+"-"+ii, Arrays.copyOf(data, data.length)); 133*f1fbf3c2SXin Li } 134*f1fbf3c2SXin Li } 135*f1fbf3c2SXin Li assertTrue(current > map.size()); 136*f1fbf3c2SXin Li } 137*f1fbf3c2SXin Li getCtClass(Class<?> clazz)138*f1fbf3c2SXin Li protected CtClass getCtClass(Class<?> clazz) throws Exception 139*f1fbf3c2SXin Li { 140*f1fbf3c2SXin Li return getCtClass(clazz.getName(), clazz.getClassLoader()); 141*f1fbf3c2SXin Li } 142*f1fbf3c2SXin Li getCtClass(String name, ClassLoader cl)143*f1fbf3c2SXin Li protected CtClass getCtClass(String name, ClassLoader cl) throws Exception 144*f1fbf3c2SXin Li { 145*f1fbf3c2SXin Li ClassPool pool = repository.findClassPool(cl); 146*f1fbf3c2SXin Li assertNotNull(pool); 147*f1fbf3c2SXin Li CtClass clazz = pool.get(name); 148*f1fbf3c2SXin Li assertNotNull(clazz); 149*f1fbf3c2SXin Li return clazz; 150*f1fbf3c2SXin Li } 151*f1fbf3c2SXin Li checkTestAnnotation(CtClass ctClass, String value)152*f1fbf3c2SXin Li protected void checkTestAnnotation(CtClass ctClass, String value) throws Exception 153*f1fbf3c2SXin Li { 154*f1fbf3c2SXin Li checkTestAnnotation(ctClass.getAnnotations(), value); 155*f1fbf3c2SXin Li checkTestAnnotation(getFieldAnnotations(ctClass), value); 156*f1fbf3c2SXin Li checkTestAnnotation(getConstructorAnnotations(ctClass), value); 157*f1fbf3c2SXin Li checkTestAnnotation(getConstructorParameterAnnotations(ctClass), value); 158*f1fbf3c2SXin Li checkTestAnnotation(getMethodAnnotations(ctClass), value); 159*f1fbf3c2SXin Li checkTestAnnotation(getMethodParameterAnnotations(ctClass), value); 160*f1fbf3c2SXin Li } 161*f1fbf3c2SXin Li checkTestAnnotation(Object[] annotations, String value)162*f1fbf3c2SXin Li protected void checkTestAnnotation(Object[] annotations, String value) throws Exception 163*f1fbf3c2SXin Li { 164*f1fbf3c2SXin Li assertNotNull(annotations); 165*f1fbf3c2SXin Li assertEquals(1, annotations.length); 166*f1fbf3c2SXin Li assertNotNull(annotations[0]); 167*f1fbf3c2SXin Li assertTrue(annotations[0] instanceof TestAnnotation); 168*f1fbf3c2SXin Li TestAnnotation annotation = (TestAnnotation) annotations[0]; 169*f1fbf3c2SXin Li assertEquals(value, annotation.something()); 170*f1fbf3c2SXin Li } 171*f1fbf3c2SXin Li checkScopedAnnotation(ClassLoader cl, CtClass ctClass, String value)172*f1fbf3c2SXin Li protected void checkScopedAnnotation(ClassLoader cl, CtClass ctClass, String value) throws Exception 173*f1fbf3c2SXin Li { 174*f1fbf3c2SXin Li Class<?> annotationClass = cl.loadClass("scoped.jar1.ScopedTestAnnotation"); 175*f1fbf3c2SXin Li checkScopedAnnotation(annotationClass, ctClass.getAnnotations(), value); 176*f1fbf3c2SXin Li checkScopedAnnotation(annotationClass, getFieldAnnotations(ctClass), value); 177*f1fbf3c2SXin Li checkScopedAnnotation(annotationClass, getConstructorAnnotations(ctClass), value); 178*f1fbf3c2SXin Li checkScopedAnnotation(annotationClass, getConstructorParameterAnnotations(ctClass), value); 179*f1fbf3c2SXin Li checkScopedAnnotation(annotationClass, getMethodAnnotations(ctClass), value); 180*f1fbf3c2SXin Li checkScopedAnnotation(annotationClass, getMethodParameterAnnotations(ctClass), value); 181*f1fbf3c2SXin Li } 182*f1fbf3c2SXin Li checkScopedAnnotation(Class<?> annotationClass, Object[] annotations, String value)183*f1fbf3c2SXin Li protected void checkScopedAnnotation(Class<?> annotationClass, Object[] annotations, String value) throws Exception 184*f1fbf3c2SXin Li { 185*f1fbf3c2SXin Li assertNotNull(annotations); 186*f1fbf3c2SXin Li assertEquals(1, annotations.length); 187*f1fbf3c2SXin Li assertNotNull(annotations[0]); 188*f1fbf3c2SXin Li assertTrue(annotationClass.isInstance(annotations[0])); 189*f1fbf3c2SXin Li 190*f1fbf3c2SXin Li Method method = annotationClass.getMethod("something", new Class<?>[0]); 191*f1fbf3c2SXin Li assertEquals(value, method.invoke(annotations[0], (Object[]) null)); 192*f1fbf3c2SXin Li } 193*f1fbf3c2SXin Li getFieldAnnotations(CtClass clazz)194*f1fbf3c2SXin Li protected Object[] getFieldAnnotations(CtClass clazz) throws Exception 195*f1fbf3c2SXin Li { 196*f1fbf3c2SXin Li CtField field = clazz.getField("aField"); 197*f1fbf3c2SXin Li assertNotNull(field); 198*f1fbf3c2SXin Li return field.getAnnotations(); 199*f1fbf3c2SXin Li } 200*f1fbf3c2SXin Li getMethodAnnotations(CtClass clazz)201*f1fbf3c2SXin Li protected Object[] getMethodAnnotations(CtClass clazz) throws Exception 202*f1fbf3c2SXin Li { 203*f1fbf3c2SXin Li CtMethod method = clazz.getMethod("doSomething", "(I)V"); 204*f1fbf3c2SXin Li assertNotNull(method); 205*f1fbf3c2SXin Li return method.getAnnotations(); 206*f1fbf3c2SXin Li } 207*f1fbf3c2SXin Li getMethodParameterAnnotations(CtClass clazz)208*f1fbf3c2SXin Li protected Object[] getMethodParameterAnnotations(CtClass clazz) throws Exception 209*f1fbf3c2SXin Li { 210*f1fbf3c2SXin Li CtMethod method = clazz.getMethod("doSomething", "(I)V"); 211*f1fbf3c2SXin Li assertNotNull(method); 212*f1fbf3c2SXin Li Object[] paramAnnotations = method.getParameterAnnotations(); 213*f1fbf3c2SXin Li assertNotNull(paramAnnotations); 214*f1fbf3c2SXin Li assertEquals(1, paramAnnotations.length); 215*f1fbf3c2SXin Li return (Object[]) paramAnnotations[0]; 216*f1fbf3c2SXin Li } 217*f1fbf3c2SXin Li getConstructorAnnotations(CtClass clazz)218*f1fbf3c2SXin Li protected Object[] getConstructorAnnotations(CtClass clazz) throws Exception 219*f1fbf3c2SXin Li { 220*f1fbf3c2SXin Li CtConstructor constructor = clazz.getConstructor("(I)V"); 221*f1fbf3c2SXin Li assertNotNull(constructor); 222*f1fbf3c2SXin Li return constructor.getAnnotations(); 223*f1fbf3c2SXin Li } 224*f1fbf3c2SXin Li getConstructorParameterAnnotations(CtClass clazz)225*f1fbf3c2SXin Li protected Object[] getConstructorParameterAnnotations(CtClass clazz) throws Exception 226*f1fbf3c2SXin Li { 227*f1fbf3c2SXin Li CtConstructor constructor = clazz.getConstructor("(I)V"); 228*f1fbf3c2SXin Li assertNotNull(constructor); 229*f1fbf3c2SXin Li Object[] paramAnnotations = constructor.getParameterAnnotations(); 230*f1fbf3c2SXin Li assertNotNull(paramAnnotations); 231*f1fbf3c2SXin Li assertEquals(1, paramAnnotations.length); 232*f1fbf3c2SXin Li return (Object[]) paramAnnotations[0]; 233*f1fbf3c2SXin Li } 234*f1fbf3c2SXin Li getURLClassLoader(String context)235*f1fbf3c2SXin Li protected ClassLoader getURLClassLoader(String context) throws Exception 236*f1fbf3c2SXin Li { 237*f1fbf3c2SXin Li String output = "."; 238*f1fbf3c2SXin Li File file = new File(output + File.separator + context); 239*f1fbf3c2SXin Li URL url = file.toURI().toURL(); 240*f1fbf3c2SXin Li return new URLClassLoader(new URL[] { url }); 241*f1fbf3c2SXin Li } 242*f1fbf3c2SXin Li } 243