Browse Source

Merge pull request #159 from nickl-/scoped-pool

Fixes to javassist.scopepool
tags/rel_3_23_0_ga
Shigeru Chiba 6 years ago
parent
commit
b7e59d4dc0
No account linked to committer's email address

+ 13
- 13
src/main/javassist/scopedpool/ScopedClassPool.java View File

@@ -16,9 +16,9 @@

package javassist.scopedpool;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.security.ProtectionDomain;
import java.util.Iterator;
import java.util.Map;
import javassist.CannotCompileException;
import javassist.ClassPool;
@@ -37,11 +37,11 @@ import javassist.NotFoundException;
public class ScopedClassPool extends ClassPool {
protected ScopedClassPoolRepository repository;

protected WeakReference classLoader;
protected Reference<ClassLoader> classLoader;

protected LoaderClassPath classPath;

protected SoftValueHashMap softcache = new SoftValueHashMap();
protected Map<String,CtClass> softcache = new SoftValueHashMap<String,CtClass>();
boolean isBootstrapCl = true;

@@ -59,10 +59,10 @@ public class ScopedClassPool extends ClassPool {
* the original class pool
* @param repository
* the repository
*@deprecated
*/
protected ScopedClassPool(ClassLoader cl, ClassPool src,
ScopedClassPoolRepository repository) {
ScopedClassPoolRepository repository)
{
this(cl, src, repository, false);
}
@@ -78,11 +78,12 @@ public class ScopedClassPool extends ClassPool {
* @param isTemp
* Whether this is a temporary pool used to resolve references
*/
protected ScopedClassPool(ClassLoader cl, ClassPool src, ScopedClassPoolRepository repository, boolean isTemp)
protected ScopedClassPool(ClassLoader cl, ClassPool src,
ScopedClassPoolRepository repository, boolean isTemp)
{
super(src);
this.repository = repository;
this.classLoader = new WeakReference(cl);
this.classLoader = new WeakReference<ClassLoader>(cl);
if (cl != null) {
classPath = new LoaderClassPath(cl);
this.insertClassPath(classPath);
@@ -110,7 +111,7 @@ public class ScopedClassPool extends ClassPool {
}

protected ClassLoader getClassLoader0() {
return (ClassLoader)classLoader.get();
return classLoader.get();
}

/**
@@ -163,6 +164,7 @@ public class ScopedClassPool extends ClassPool {
* the class name
* @return the class
*/
@Override
protected CtClass getCached(String classname) {
CtClass clazz = getCachedLocally(classname);
if (clazz == null) {
@@ -186,11 +188,9 @@ public class ScopedClassPool extends ClassPool {
}

if (!isLocal) {
Map registeredCLs = repository.getRegisteredCLs();
Map<ClassLoader,ScopedClassPool> registeredCLs = repository.getRegisteredCLs();
synchronized (registeredCLs) {
Iterator it = registeredCLs.values().iterator();
while (it.hasNext()) {
ScopedClassPool pool = (ScopedClassPool)it.next();
for (ScopedClassPool pool:registeredCLs.values()) {
if (pool.isUnloadedClassLoader()) {
repository.unregisterClassLoader(pool
.getClassLoader());
@@ -289,7 +289,7 @@ public class ScopedClassPool extends ClassPool {
* @throws CannotCompileException
* for any error
*/
public Class toClass(CtClass ct, ClassLoader loader, ProtectionDomain domain)
public Class<?> toClass(CtClass ct, ClassLoader loader, ProtectionDomain domain)
throws CannotCompileException {
// We need to pass up the classloader stored in this pool, as the
// default implementation uses the Thread context cl.

+ 1
- 1
src/main/javassist/scopedpool/ScopedClassPoolRepository.java View File

@@ -81,7 +81,7 @@ public interface ScopedClassPoolRepository {
*
* @return the registered classloaders.
*/
Map getRegisteredCLs();
Map<ClassLoader,ScopedClassPool> getRegisteredCLs();

/**
* This method will check to see if a register classloader has been

+ 26
- 21
src/main/javassist/scopedpool/ScopedClassPoolRepositoryImpl.java View File

@@ -18,7 +18,7 @@ package javassist.scopedpool;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

@@ -43,8 +43,8 @@ public class ScopedClassPoolRepositoryImpl implements ScopedClassPoolRepository
boolean pruneWhenCached;

/** The registered classloaders */
protected Map registeredCLs = Collections
.synchronizedMap(new WeakHashMap());
protected Map<ClassLoader,ScopedClassPool> registeredCLs = Collections
.synchronizedMap(new WeakHashMap<ClassLoader,ScopedClassPool>());

/** The default class pool */
protected ClassPool classpool;
@@ -76,6 +76,7 @@ public class ScopedClassPoolRepositoryImpl implements ScopedClassPoolRepository
*
* @return the prune.
*/
@Override
public boolean isPrune() {
return prune;
}
@@ -85,6 +86,7 @@ public class ScopedClassPoolRepositoryImpl implements ScopedClassPoolRepository
*
* @param prune a new value.
*/
@Override
public void setPrune(boolean prune) {
this.prune = prune;
}
@@ -96,10 +98,12 @@ public class ScopedClassPoolRepositoryImpl implements ScopedClassPoolRepository
* @param src the original classpool.
* @return the classpool
*/
@Override
public ScopedClassPool createScopedClassPool(ClassLoader cl, ClassPool src) {
return factory.create(cl, src, this);
}

@Override
public ClassPool findClassPool(ClassLoader cl) {
if (cl == null)
return registerClassLoader(ClassLoader.getSystemClassLoader());
@@ -113,6 +117,7 @@ public class ScopedClassPoolRepositoryImpl implements ScopedClassPoolRepository
* @param ucl the classloader.
* @return the classpool
*/
@Override
public ClassPool registerClassLoader(ClassLoader ucl) {
synchronized (registeredCLs) {
// FIXME: Probably want to take this method out later
@@ -121,7 +126,7 @@ public class ScopedClassPoolRepositoryImpl implements ScopedClassPoolRepository
// a
// ClassPool.classpath
if (registeredCLs.containsKey(ucl)) {
return (ClassPool)registeredCLs.get(ucl);
return registeredCLs.get(ucl);
}
ScopedClassPool pool = createScopedClassPool(ucl, classpool);
registeredCLs.put(ucl, pool);
@@ -132,7 +137,8 @@ public class ScopedClassPoolRepositoryImpl implements ScopedClassPoolRepository
/**
* Get the registered classloaders.
*/
public Map getRegisteredCLs() {
@Override
public Map<ClassLoader,ScopedClassPool> getRegisteredCLs() {
clearUnregisteredClassLoaders();
return registeredCLs;
}
@@ -141,34 +147,31 @@ public class ScopedClassPoolRepositoryImpl implements ScopedClassPoolRepository
* This method will check to see if a register classloader has been
* undeployed (as in JBoss)
*/
@Override
public void clearUnregisteredClassLoaders() {
ArrayList toUnregister = null;
List<ClassLoader> toUnregister = null;
synchronized (registeredCLs) {
Iterator it = registeredCLs.values().iterator();
while (it.hasNext()) {
ScopedClassPool pool = (ScopedClassPool)it.next();
if (pool.isUnloadedClassLoader()) {
it.remove();
ClassLoader cl = pool.getClassLoader();
for (Map.Entry<ClassLoader,ScopedClassPool> reg:registeredCLs.entrySet()) {
if (reg.getValue().isUnloadedClassLoader()) {
ClassLoader cl = reg.getValue().getClassLoader();
if (cl != null) {
if (toUnregister == null) {
toUnregister = new ArrayList();
}
if (toUnregister == null)
toUnregister = new ArrayList<ClassLoader>();
toUnregister.add(cl);
}
registeredCLs.remove(reg.getKey());
}
}
if (toUnregister != null) {
for (int i = 0; i < toUnregister.size(); i++) {
unregisterClassLoader((ClassLoader)toUnregister.get(i));
}
}
if (toUnregister != null)
for (ClassLoader cl:toUnregister)
unregisterClassLoader(cl);
}
}

@Override
public void unregisterClassLoader(ClassLoader cl) {
synchronized (registeredCLs) {
ScopedClassPool pool = (ScopedClassPool)registeredCLs.remove(cl);
ScopedClassPool pool = registeredCLs.remove(cl);
if (pool != null)
pool.close();
}
@@ -178,10 +181,12 @@ public class ScopedClassPoolRepositoryImpl implements ScopedClassPoolRepository
// Noop - this is the end
}

@Override
public void setClassPoolFactory(ScopedClassPoolFactory factory) {
this.factory = factory;
}

@Override
public ScopedClassPoolFactory getClassPoolFactory() {
return factory;
}

+ 96
- 36
src/main/javassist/scopedpool/SoftValueHashMap.java View File

@@ -18,10 +18,14 @@ package javassist.scopedpool;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
* This Map will remove entries when the value in the map has been cleaned from
@@ -30,21 +34,21 @@ import java.util.Set;
* @version <tt>$Revision: 1.4 $</tt>
* @author <a href="mailto:bill@jboss.org">Bill Burke</a>
*/
public class SoftValueHashMap extends AbstractMap implements Map {
private static class SoftValueRef extends SoftReference {
public Object key;
public class SoftValueHashMap<K,V> implements Map<K,V> {
private static class SoftValueRef<K,V> extends SoftReference<V> {
public K key;

private SoftValueRef(Object key, Object val, ReferenceQueue q) {
private SoftValueRef(K key, V val, ReferenceQueue<V> q) {
super(val, q);
this.key = key;
}

private static SoftValueRef create(Object key, Object val,
ReferenceQueue q) {
private static <K,V> SoftValueRef<K,V> create(
K key, V val, ReferenceQueue<V> q) {
if (val == null)
return null;
else
return new SoftValueRef(key, val, q);
return new SoftValueRef<K,V>(key, val, q);
}

}
@@ -52,30 +56,37 @@ public class SoftValueHashMap extends AbstractMap implements Map {
/**
* Returns a set of the mappings contained in this hash table.
*/
public Set entrySet() {
@Override
public Set<Map.Entry<K, V>> entrySet() {
processQueue();
return hash.entrySet();
Set<Entry<K,V>> ret = new HashSet<Entry<K,V>>();
for (Entry<K,SoftValueRef<K,V>> e:hash.entrySet())
ret.add(new SimpleImmutableEntry<K,V> (
e.getKey(), e.getValue().get()));
return ret;
}

/* Hash table mapping WeakKeys to values */
private Map hash;
private Map<K,SoftValueRef<K,V>> hash;

/* Reference queue for cleared WeakKeys */
private ReferenceQueue queue = new ReferenceQueue();
private ReferenceQueue<V> queue = new ReferenceQueue<V>();

/*
* Remove all invalidated entries from the map, that is, remove all entries
* whose values have been discarded.
*/
private void processQueue() {
SoftValueRef ref;
while ((ref = (SoftValueRef)queue.poll()) != null) {
if (ref == (SoftValueRef)hash.get(ref.key)) {
// only remove if it is the *exact* same WeakValueRef
//
hash.remove(ref.key);
Object ref;
if (!hash.isEmpty())
while ((ref = queue.poll()) != null)
if (ref instanceof SoftValueRef) {
@SuppressWarnings("rawtypes")
SoftValueRef que =(SoftValueRef) ref;
if (ref == hash.get(que.key))
// only remove if it is the *exact* same SoftValueRef
hash.remove(que.key);
}
}
}

/* -- Constructors -- */
@@ -95,7 +106,7 @@ public class SoftValueHashMap extends AbstractMap implements Map {
* factor is nonpositive
*/
public SoftValueHashMap(int initialCapacity, float loadFactor) {
hash = new HashMap(initialCapacity, loadFactor);
hash = new ConcurrentHashMap<K,SoftValueRef<K,V>>(initialCapacity, loadFactor);
}

/**
@@ -109,7 +120,7 @@ public class SoftValueHashMap extends AbstractMap implements Map {
* If the initial capacity is less than zero
*/
public SoftValueHashMap(int initialCapacity) {
hash = new HashMap(initialCapacity);
hash = new ConcurrentHashMap<K,SoftValueRef<K,V>>(initialCapacity);
}

/**
@@ -117,7 +128,7 @@ public class SoftValueHashMap extends AbstractMap implements Map {
* initial capacity and the default load factor, which is <code>0.75</code>.
*/
public SoftValueHashMap() {
hash = new HashMap();
hash = new ConcurrentHashMap<K,SoftValueRef<K,V>>();
}

/**
@@ -129,7 +140,7 @@ public class SoftValueHashMap extends AbstractMap implements Map {
*
* @param t the map whose mappings are to be placed in this map.
*/
public SoftValueHashMap(Map t) {
public SoftValueHashMap(Map<K,V> t) {
this(Math.max(2 * t.size(), 11), 0.75f);
putAll(t);
}
@@ -142,6 +153,7 @@ public class SoftValueHashMap extends AbstractMap implements Map {
* <code>Map</code> interface, the time required by this operation is
* linear in the size of the map.</em>
*/
@Override
public int size() {
processQueue();
return hash.size();
@@ -150,6 +162,7 @@ public class SoftValueHashMap extends AbstractMap implements Map {
/**
* Returns <code>true</code> if this map contains no key-value mappings.
*/
@Override
public boolean isEmpty() {
processQueue();
return hash.isEmpty();
@@ -162,6 +175,7 @@ public class SoftValueHashMap extends AbstractMap implements Map {
* @param key
* The key whose presence in this map is to be tested.
*/
@Override
public boolean containsKey(Object key) {
processQueue();
return hash.containsKey(key);
@@ -177,12 +191,10 @@ public class SoftValueHashMap extends AbstractMap implements Map {
* @param key
* The key whose associated value, if any, is to be returned.
*/
public Object get(Object key) {
@Override
public V get(Object key) {
processQueue();
SoftReference ref = (SoftReference)hash.get(key);
if (ref != null)
return ref.get();
return null;
return valueOrNull(hash.get(key));
}

/**
@@ -200,12 +212,10 @@ public class SoftValueHashMap extends AbstractMap implements Map {
* @return The previous value to which this key was mapped, or
* <code>null</code> if if there was no mapping for the key
*/
public Object put(Object key, Object value) {
@Override
public V put(K key, V value) {
processQueue();
Object rtn = hash.put(key, SoftValueRef.create(key, value, queue));
if (rtn != null)
rtn = ((SoftReference)rtn).get();
return rtn;
return valueOrNull(hash.put(key, SoftValueRef.create(key, value, queue)));
}

/**
@@ -218,16 +228,66 @@ public class SoftValueHashMap extends AbstractMap implements Map {
* @return The value to which this key was mapped, or <code>null</code> if
* there was no mapping for the key.
*/
public Object remove(Object key) {
@Override
public V remove(Object key) {
processQueue();
return hash.remove(key);
return valueOrNull(hash.remove(key));
}

/**
* Removes all mappings from this map.
*/
@Override
public void clear() {
processQueue();
hash.clear();
}

/*
* Check whether the supplied value exists.
* @param Object the value to compare.
* @return true if it was found or null.
*/
@Override
public boolean containsValue(Object arg0) {
processQueue();
if (null == arg0)
return false;
for (SoftValueRef<K,V> e:hash.values())
if (null != e && arg0.equals(e.get()))
return true;
return false;
}

/* {@inheritDoc} */
@Override
public Set<K> keySet() {
processQueue();
return hash.keySet();
}
/* {@inheritDoc} */
@Override
public void putAll(Map<? extends K,? extends V> arg0) {
processQueue();
for (K key:arg0.keySet())
put(key, arg0.get(key));
}

/* {@inheritDoc} */
@Override
public Collection<V> values() {
processQueue();
List<V> ret = new ArrayList<V>();
for (SoftValueRef<K,V> e:hash.values())
ret.add(e.get());
return ret;
}
private V valueOrNull(SoftValueRef<K,V> rtn) {
if (null == rtn)
return null;
return rtn.get();
}
}

+ 242
- 0
src/test/scoped/ScopedRepositoryTestCase.java View File

@@ -0,0 +1,242 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package scoped;

import java.io.File;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.LongStream;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.scopedpool.ScopedClassPool;
import javassist.scopedpool.ScopedClassPoolRepository;
import javassist.scopedpool.ScopedClassPoolRepositoryImpl;
import javassist.scopedpool.SoftValueHashMap;
import junit.framework.TestCase;


/**
* ScopedRepositoryTest.
*
* @author <a href="adrian@jboss.com">Adrian Brock</a>
* @version $Revision$
*/
public class ScopedRepositoryTestCase extends TestCase
{
private static final ScopedClassPoolRepository repository = ScopedClassPoolRepositoryImpl.getInstance();
public void testJDKClasses() throws Exception
{
ClassPool poolClass = repository.findClassPool(Class.class.getClassLoader());
assertNotNull(poolClass);
ClassPool poolString = repository.findClassPool(String.class.getClassLoader());
assertNotNull(poolString);
assertEquals(poolClass, poolString);
}
public void testScopedClasses() throws Exception
{
ClassLoader cl = getURLClassLoader("test-classes14-jar1");
ClassPool pool1 = repository.findClassPool(cl);
CtClass clazz = pool1.get("scoped.jar1.TestClass1");
assertNotNull(clazz);
ClassPool poolClass = repository.findClassPool(Class.class.getClassLoader());
assertNotNull(poolClass);
assertNotSame(pool1, poolClass);
}
public void testUnscopedAnnotationUsage() throws Exception
{
CtClass clazz = getCtClass(UnscopedAnnotationUsage.class);
checkTestAnnotation(clazz, "notDefault");
}
public void testUnscopedAnnotationDefaultUsage() throws Exception
{
CtClass clazz = getCtClass(UnscopedAnnotationDefaultUsage.class);
checkTestAnnotation(clazz, "defaultValue");
}
public void testScopedAnnotationUsage() throws Exception
{
ClassLoader cl = getURLClassLoader("test-classes14-jar1");
CtClass clazz = getCtClass("scoped.jar1.ScopedAnnotationUsage", cl);
checkTestAnnotation(clazz, "notDefault");
}
public void testScopedAnnotationDefaultUsage() throws Exception
{
ClassLoader cl = getURLClassLoader("test-classes14-jar1");
CtClass clazz = getCtClass("scoped.jar1.ScopedAnnotationDefaultUsage", cl);
checkTestAnnotation(clazz, "defaultValue");
}
public void testFullyScopedAnnotationUsage() throws Exception
{
ClassLoader cl = getURLClassLoader("test-classes14-jar1");
CtClass clazz = getCtClass("scoped.jar1.FullyScopedAnnotationUsage", cl);
checkScopedAnnotation(cl, clazz, "notDefault");
}
public void testFullyScopedAnnotationDefaultUsage() throws Exception
{
ClassLoader cl = getURLClassLoader("test-classes14-jar1");
CtClass clazz = getCtClass("scoped.jar1.FullyScopedAnnotationDefaultUsage", cl);
checkScopedAnnotation(cl, clazz, "defaultValue");
}
public void testSoftValueHashMap() throws Exception {
Map<String,Class<?>> map = new SoftValueHashMap<>();
Class<?> cls = this.getClass();
assertTrue(map.put(cls.getName(), cls) == null);
assertTrue(map.put(cls.getName(), cls) == cls);
assertTrue(map.size() == 1);
assertTrue(map.get(cls.getName()) == cls);
assertTrue(map.values().iterator().next() == cls);
assertTrue(map.entrySet().iterator().next().getValue() == cls);
assertTrue(map.containsValue(cls));
assertTrue(map.remove(cls.getName()) == cls);
assertTrue(map.size() == 0);
}

public void testSoftCache() throws Exception {
// Overload the heap to test that the map auto cleans
Map<String,long[]> map = new SoftValueHashMap<>();
// 12+8*30000000 = +- 252 MB
long[] data = LongStream.range(0, 30000000).toArray();
int current = map.size();
while (current <= map.size()) {
current = map.size();
for (int ii = 0; ii < 5; ii++) {
map.put(current+"-"+ii, Arrays.copyOf(data, data.length));
}
}
assertTrue(current > map.size());
}
protected CtClass getCtClass(Class<?> clazz) throws Exception
{
return getCtClass(clazz.getName(), clazz.getClassLoader());
}
protected CtClass getCtClass(String name, ClassLoader cl) throws Exception
{
ClassPool pool = repository.findClassPool(cl);
assertNotNull(pool);
CtClass clazz = pool.get(name);
assertNotNull(clazz);
return clazz;
}
protected void checkTestAnnotation(CtClass ctClass, String value) throws Exception
{
checkTestAnnotation(ctClass.getAnnotations(), value);
checkTestAnnotation(getFieldAnnotations(ctClass), value);
checkTestAnnotation(getConstructorAnnotations(ctClass), value);
checkTestAnnotation(getConstructorParameterAnnotations(ctClass), value);
checkTestAnnotation(getMethodAnnotations(ctClass), value);
checkTestAnnotation(getMethodParameterAnnotations(ctClass), value);
}
protected void checkTestAnnotation(Object[] annotations, String value) throws Exception
{
assertNotNull(annotations);
assertEquals(1, annotations.length);
assertNotNull(annotations[0]);
assertTrue(annotations[0] instanceof TestAnnotation);
TestAnnotation annotation = (TestAnnotation) annotations[0];
assertEquals(value, annotation.something());
}
protected void checkScopedAnnotation(ClassLoader cl, CtClass ctClass, String value) throws Exception
{
Class<?> annotationClass = cl.loadClass("scoped.jar1.ScopedTestAnnotation");
checkScopedAnnotation(annotationClass, ctClass.getAnnotations(), value);
checkScopedAnnotation(annotationClass, getFieldAnnotations(ctClass), value);
checkScopedAnnotation(annotationClass, getConstructorAnnotations(ctClass), value);
checkScopedAnnotation(annotationClass, getConstructorParameterAnnotations(ctClass), value);
checkScopedAnnotation(annotationClass, getMethodAnnotations(ctClass), value);
checkScopedAnnotation(annotationClass, getMethodParameterAnnotations(ctClass), value);
}
protected void checkScopedAnnotation(Class<?> annotationClass, Object[] annotations, String value) throws Exception
{
assertNotNull(annotations);
assertEquals(1, annotations.length);
assertNotNull(annotations[0]);
assertTrue(annotationClass.isInstance(annotations[0]));
Method method = annotationClass.getMethod("something", new Class<?>[0]);
assertEquals(value, method.invoke(annotations[0], (Object[]) null));
}
protected Object[] getFieldAnnotations(CtClass clazz) throws Exception
{
CtField field = clazz.getField("aField");
assertNotNull(field);
return field.getAnnotations();
}
protected Object[] getMethodAnnotations(CtClass clazz) throws Exception
{
CtMethod method = clazz.getMethod("doSomething", "(I)V");
assertNotNull(method);
return method.getAnnotations();
}
protected Object[] getMethodParameterAnnotations(CtClass clazz) throws Exception
{
CtMethod method = clazz.getMethod("doSomething", "(I)V");
assertNotNull(method);
Object[] paramAnnotations = method.getParameterAnnotations();
assertNotNull(paramAnnotations);
assertEquals(1, paramAnnotations.length);
return (Object[]) paramAnnotations[0];
}
protected Object[] getConstructorAnnotations(CtClass clazz) throws Exception
{
CtConstructor constructor = clazz.getConstructor("(I)V");
assertNotNull(constructor);
return constructor.getAnnotations();
}
protected Object[] getConstructorParameterAnnotations(CtClass clazz) throws Exception
{
CtConstructor constructor = clazz.getConstructor("(I)V");
assertNotNull(constructor);
Object[] paramAnnotations = constructor.getParameterAnnotations();
assertNotNull(paramAnnotations);
assertEquals(1, paramAnnotations.length);
return (Object[]) paramAnnotations[0];
}
protected ClassLoader getURLClassLoader(String context) throws Exception
{
String output = ".";
File file = new File(output + File.separator + context);
URL url = file.toURI().toURL();
return new URLClassLoader(new URL[] { url });
}
}

+ 34
- 0
src/test/scoped/TestAnnotation.java View File

@@ -0,0 +1,34 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package scoped;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* TestAnnotation.
*
* @author <a href="adrian@jboss.com">Adrian Brock</a>
* @version $Revision$
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.CONSTRUCTOR })
public @interface TestAnnotation
{
String something() default "defaultValue";
}

+ 29
- 0
src/test/scoped/UnscopedAnnotationDefaultUsage.java View File

@@ -0,0 +1,29 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package scoped;

@TestAnnotation
public class UnscopedAnnotationDefaultUsage
{
@TestAnnotation
public int aField;
@TestAnnotation
public UnscopedAnnotationDefaultUsage(@TestAnnotation int param) {}

@TestAnnotation
public void doSomething(@TestAnnotation int param) {}
}

+ 29
- 0
src/test/scoped/UnscopedAnnotationUsage.java View File

@@ -0,0 +1,29 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package scoped;

@TestAnnotation(something="notDefault")
public class UnscopedAnnotationUsage
{
@TestAnnotation(something="notDefault")
public int aField;
@TestAnnotation(something="notDefault")
public UnscopedAnnotationUsage(@TestAnnotation(something="notDefault") int param) {}
@TestAnnotation(something="notDefault")
public void doSomething(@TestAnnotation(something="notDefault") int param) {}
}

+ 29
- 0
src/test/scoped/jar1/FullyScopedAnnotationDefaultUsage.java View File

@@ -0,0 +1,29 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package scoped.jar1;

@ScopedTestAnnotation
public class FullyScopedAnnotationDefaultUsage
{
@ScopedTestAnnotation
public int aField;

@ScopedTestAnnotation
public FullyScopedAnnotationDefaultUsage(@ScopedTestAnnotation int value) {}

@ScopedTestAnnotation
public void doSomething(@ScopedTestAnnotation int value) {}
}

+ 29
- 0
src/test/scoped/jar1/FullyScopedAnnotationUsage.java View File

@@ -0,0 +1,29 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package scoped.jar1;

@ScopedTestAnnotation(something="notDefault")
public class FullyScopedAnnotationUsage
{
@ScopedTestAnnotation(something="notDefault")
public int aField;

@ScopedTestAnnotation(something="notDefault")
public FullyScopedAnnotationUsage(@ScopedTestAnnotation(something="notDefault") int param) {}

@ScopedTestAnnotation(something="notDefault")
public void doSomething(@ScopedTestAnnotation(something="notDefault") int param) {}
}

+ 31
- 0
src/test/scoped/jar1/ScopedAnnotationDefaultUsage.java View File

@@ -0,0 +1,31 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package scoped.jar1;

import scoped.TestAnnotation;

@TestAnnotation
public class ScopedAnnotationDefaultUsage
{
@TestAnnotation
public int aField;

@TestAnnotation
public ScopedAnnotationDefaultUsage(@TestAnnotation int param) {}

@TestAnnotation
public void doSomething(@TestAnnotation int param) {}
}

+ 31
- 0
src/test/scoped/jar1/ScopedAnnotationUsage.java View File

@@ -0,0 +1,31 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package scoped.jar1;

import scoped.TestAnnotation;

@TestAnnotation(something="notDefault")
public class ScopedAnnotationUsage
{
@TestAnnotation(something="notDefault")
public int aField;

@TestAnnotation(something="notDefault")
public ScopedAnnotationUsage(@TestAnnotation(something="notDefault") int param) {}

@TestAnnotation(something="notDefault")
public void doSomething(@TestAnnotation(something="notDefault") int param) {}
}

+ 34
- 0
src/test/scoped/jar1/ScopedTestAnnotation.java View File

@@ -0,0 +1,34 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package scoped.jar1;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* TestAnnotation.
*
* @author <a href="adrian@jboss.com">Adrian Brock</a>
* @version $Revision$
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.CONSTRUCTOR })
public @interface ScopedTestAnnotation
{
String something() default "defaultValue";
}

+ 26
- 0
src/test/scoped/jar1/TestClass1.java View File

@@ -0,0 +1,26 @@
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package scoped.jar1;

/**
* TestClass1.
*
* @author <a href="adrian@jboss.com">Adrian Brock</a>
* @version $Revision$
*/
public class TestClass1
{
}

Loading…
Cancel
Save