Commits

Jerry Lee committed f2c2c79

包名修改

  • Participants
  • Parent commits 98ec4ae

Comments (0)

Files changed (56)

src/main/java/com/alibaba/oldratlee/cooma/Adaptive.java

-package com.alibaba.oldratlee.cooma;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * 在{@link ExtensionLoader}生成Extension的Adaptive Instance时,为
- * {@link ExtensionLoader}提供信息。
- * 
- * @author oldratlee
- * @since 0.1.0
- * @see ExtensionLoader
- * @see URL
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ ElementType.TYPE, ElementType.METHOD })
-public @interface Adaptive {
-
-    /**
-     * 从{@link URL}的Key名,对应的Value作为要Adapt成的Extension名。
-     * <p>
-     * 如果{@link URL}这些Key都没有Value,使用 用 缺省的扩展(在接口的{@link Extension}中设定的值)。<br>
-     * 比如,<code>String[] {"key1", "key2"}</code>,表示
-     * <ol>
-     * <li>先在URL上找key1的Value作为要Adapt成的Extension名;
-     * <li>key1没有Value,则使用key2的Value作为要Adapt成的Extension名。
-     * <li>key2没有Value,使用缺省的扩展。
-     * <li>如果没有设定缺省扩展,则方法调用会抛出{@link IllegalStateException}。
-     * </ol>
-     * <p>
-     * 如果不设置则缺省使用Extension接口类名的点分隔小写字串。<br>
-     * 即对于Extension接口{@code com.alibaba.dubbo.xxx.YyyInvokerWrapper}的缺省值为
-     * <code>String[] {"yyy.invoker.wrapper"}</code>
-     * 
-     * @see Extension#value()
-     */
-    String[] value() default {};
-
-}

src/main/java/com/alibaba/oldratlee/cooma/Configs.java

-package com.alibaba.oldratlee.cooma;
-
-/**
- * @author oldratlee
- * @since 0.1.0
- */
-public interface Configs {
-    String get(String key);
-}

src/main/java/com/alibaba/oldratlee/cooma/Extension.java

-package com.alibaba.oldratlee.cooma;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * 扩展点接口的标识。
- * 
- * @author oldratlee
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ ElementType.TYPE })
-public @interface Extension {
-
-    /**
-     * 缺省扩展点名。
-     */
-    String value() default "";
-
-}

src/main/java/com/alibaba/oldratlee/cooma/ExtensionLoader.java

-package com.alibaba.oldratlee.cooma;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.net.URL;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.regex.Pattern;
-
-import com.alibaba.oldratlee.cooma.internal.bytecode.ClassGenerator;
-import com.alibaba.oldratlee.cooma.internal.logging.InternalLogger;
-import com.alibaba.oldratlee.cooma.internal.logging.InternalLoggerFactory;
-import com.alibaba.oldratlee.cooma.internal.utils.ConcurrentHashSet;
-import com.alibaba.oldratlee.cooma.internal.utils.Reference;
-import com.alibaba.oldratlee.cooma.internal.utils.StringUtils;
-
-/**
- * Dubbo使用的扩展点获取。<p>
- * <ul>
- * <li>自动注入关联扩展点。</li>
- * <li>自动Wrap上扩展点的Wrap类。</li>
- * <li>缺省获得的的扩展点是一个Adaptive Instance。
- * </ul>
- * 
- * @see <a href="http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html#Service%20Provider">JDK5.0的自动发现机制实现</a>
- * 
- * @author oldratlee
- * @since 0.1.0
- * 
- * @see Adaptive
- */
-public class ExtensionLoader<T> {
-    
-    private static final InternalLogger logger = InternalLoggerFactory.getInstance(ExtensionLoader.class);
-    
-	private static final String SERVICES_DIRECTORY = "META-INF/services/";
-
-    private static final Pattern NAME_SEPARATOR = Pattern.compile("\\s*[,]+\\s*");
-    
-    private static final ConcurrentMap<Class<?>, ExtensionLoader<?>> EXTENSION_LOADERS = new ConcurrentHashMap<Class<?>, ExtensionLoader<?>>();
-
-    private final Class<?> type;
-
-    private final ConcurrentMap<Class<?>, String> cachedNames = new ConcurrentHashMap<Class<?>, String>();
-    
-    private final Reference<Map<String, Class<?>>> cachedClasses = new Reference<Map<String,Class<?>>>();
-    
-	private final ConcurrentMap<String, Reference<Object>> cachedInstances = new ConcurrentHashMap<String, Reference<Object>>();
-	
-    private volatile Class<?> cachedAdaptiveClass = null;
-    
-	private final Reference<Object> cachedAdaptiveInstance = new Reference<Object>();
-	private volatile Throwable createAdaptiveInstanceError;
-	
-    private Set<Class<?>> cachedWrapperClasses;
-    
-    private String cachedDefaultName;
-    
-    private Map<String, IllegalStateException> exceptions = new ConcurrentHashMap<String, IllegalStateException>();
-    
-    private static <T> boolean withExtensionAnnotation(Class<T> type) {
-        return type.isAnnotationPresent(Extension.class);
-    }
-    
-    @SuppressWarnings("unchecked")
-    public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
-        if (type == null)
-            throw new IllegalArgumentException("Extension type == null");
-        if(!withExtensionAnnotation(type)) {
-            throw new IllegalArgumentException("Extension type(" + type + 
-            		") is not extension, because WITHOUT @Extension Annotation!");
-        }
-        
-        ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
-        if (loader == null) {
-            EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
-            loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
-        }
-        return loader;
-    }
-
-    private ExtensionLoader(Class<?> type) {
-        this.type = type;
-    }
-    
-    public String getExtensionName(T extensionInstance) {
-        return getExtensionName(extensionInstance.getClass());
-    }
-
-    public String getExtensionName(Class<?> extensionClass) {
-        return cachedNames.get(extensionClass);
-    }
-    
-	@SuppressWarnings("unchecked")
-	public T getExtension(String name) {
-		if (name == null || name.length() == 0)
-		    throw new IllegalArgumentException("Extension name == null");
-		Reference<Object> reference = cachedInstances.get(name);
-		if (reference == null) {
-		    cachedInstances.putIfAbsent(name, new Reference<Object>());
-		    reference = cachedInstances.get(name);
-		}
-		Object instance = reference.get();
-		if (instance == null) {
-		    synchronized (reference) {
-	            instance = reference.get();
-	            if (instance == null) {
-	                instance = createExtension(name);
-	                reference.set(instance);
-	            }
-	        }
-		}
-		return (T) instance;
-	}
-	
-	/**
-	 * 返回缺省的扩展,如果没有设置则返回<code>null</code>。 
-	 */
-	public T getDefaultExtension() {
-        getExtensionClasses();
-	    if(null == cachedDefaultName || cachedDefaultName.length() == 0) {
-	        return null;
-	    }
-	    return getExtension(cachedDefaultName);
-	}
-
-	public boolean hasExtension(String name) {
-	    if (name == null || name.length() == 0)
-	        throw new IllegalArgumentException("Extension name == null");
-	    try {
-	        return getExtensionClass(name) != null;
-	    } catch (Throwable t) {
-	        return false;
-	    }
-	}
-    
-	public Set<String> getSupportedExtensions() {
-        Map<String, Class<?>> clazzes = getExtensionClasses();
-        return Collections.unmodifiableSet(new TreeSet<String>(clazzes.keySet()));
-    }
-	
-	/**
-	 * 返回缺省的扩展点名,如果没有设置缺省则返回<code>null</code>。 
-	 */
-	public String getDefaultExtensionName() {
-	    getExtensionClasses();
-	    return cachedDefaultName;
-	}
-	
-
-    @SuppressWarnings("unchecked")
-    public T getAdaptiveExtension() {
-        Object instance = cachedAdaptiveInstance.get();
-        if (instance == null) {
-            if(createAdaptiveInstanceError == null) {
-                synchronized (cachedAdaptiveInstance) {
-                    instance = cachedAdaptiveInstance.get();
-                    if (instance == null) {
-                        try {
-                            instance = createAdaptiveExtension();
-                            cachedAdaptiveInstance.set(instance);
-                        } catch (Throwable t) {
-                            createAdaptiveInstanceError = t;
-                            rethrowAsRuntime(t, "fail to create adaptive instance: ");
-                        }
-                    }
-                }
-            }
-            else {
-                rethrowAsRuntime(createAdaptiveInstanceError, "fail to create adaptive instance: ");
-            }
-        }
-        
-        return (T) instance;
-    }
-
-    private static void rethrowAsRuntime(Throwable t, String message) {
-        if(t instanceof RuntimeException)
-            throw (RuntimeException)t;
-        else
-            throw new IllegalStateException(message + t.toString(), t);
-    }
-    
-    private IllegalStateException findException(String name) {
-        for (Map.Entry<String, IllegalStateException> entry : exceptions.entrySet()) {
-            if (entry.getKey().toLowerCase().contains(name.toLowerCase())) {
-                return entry.getValue();
-            }
-        }
-        StringBuilder buf = new StringBuilder("No such extension " + type.getName() + " by name " + name + ", possible causes: ");
-        int i = 1;
-        for (Map.Entry<String, IllegalStateException> entry : exceptions.entrySet()) {
-            buf.append("\r\n(");
-            buf.append(i ++);
-            buf.append(") ");
-            buf.append(entry.getKey());
-            buf.append(":\r\n");
-            buf.append(StringUtils.toString(entry.getValue()));
-        }
-        return new IllegalStateException(buf.toString());
-    }
-
-    @SuppressWarnings("unchecked")
-    private T createExtension(String name) {
-        Class<?> clazz = getExtensionClasses().get(name);
-        if (clazz == null) {
-            throw findException(name);
-        }
-        try {
-            T instance = injectExtension((T) clazz.newInstance());
-            Set<Class<?>> wrapperClasses = cachedWrapperClasses;
-            if (wrapperClasses != null && wrapperClasses.size() > 0) {
-                for (Class<?> wrapperClass : wrapperClasses) {
-                    instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));
-                }
-            }
-            return instance;
-        } catch (Throwable t) {
-            throw new IllegalStateException("Extension instance(name: " + name + ", class: " +
-                    type + ")  could not be instantiated: " + t.getMessage(), t);
-        }
-    }
-    
-    private T injectExtension(T instance) {
-        try {
-            for (Method method : instance.getClass().getMethods()) {
-                if (method.getName().startsWith("set")
-                        && method.getParameterTypes().length == 1
-                        && Modifier.isPublic(method.getModifiers())) {
-                    Class<?> pt = method.getParameterTypes()[0];
-                    if (pt.isInterface() && withExtensionAnnotation(pt) && getExtensionLoader(pt).getSupportedExtensions().size() > 0) {
-                        try {
-                            Object adaptive = getExtensionLoader(pt).getAdaptiveExtension();
-                            method.invoke(instance, adaptive);
-                        } catch (Exception e) {
-                            logger.error("fail to inject via method " + method.getName()
-                            		+ " of interface " + type.getName() + ": " + e.getMessage(), e);
-                        }
-                    }
-                }
-            }
-        } catch (Exception e) {
-            logger.error(e.getMessage(), e);
-        }
-        return instance;
-    }
-    
-	private Class<?> getExtensionClass(String name) {
-	    if (type == null)
-	        throw new IllegalArgumentException("Extension type == null");
-	    if (name == null)
-	        throw new IllegalArgumentException("Extension name == null");
-	    Class<?> clazz = getExtensionClasses().get(name);
-	    if (clazz == null)
-	        throw new IllegalStateException("No such extension \"" + name + "\" for " + type.getName() + "!");
-	    return clazz;
-	}
-	
-	private Map<String, Class<?>> getExtensionClasses() {
-        Map<String, Class<?>> classes = cachedClasses.get();
-        if (classes == null) {
-            synchronized (cachedClasses) {
-                classes = cachedClasses.get();
-                if (classes == null) {
-                    classes = loadExtensionClasses();
-                    cachedClasses.set(classes);
-                }
-            }
-        }
-        return classes;
-	}
-	
-    private Map<String, Class<?>> loadExtensionClasses() {
-        final Extension defaultAnnotation = type.getAnnotation(Extension.class);
-        if(defaultAnnotation != null) {
-            String value = defaultAnnotation.value();
-            if(value != null && (value = value.trim()).length() > 0) {
-                String[] names = NAME_SEPARATOR.split(value);
-                if(names.length > 1) {
-                    throw new IllegalStateException("more than 1 default extension name on extension " + type.getName()
-                            + ": " + Arrays.toString(names));
-                }
-                if(names.length == 1) cachedDefaultName = names[0];
-            }
-        }
-        
-        ClassLoader classLoader = findClassLoader();
-        Map<String, Class<?>> extensionClasses = new HashMap<String, Class<?>>();
-        String fileName = null;
-        try {
-            fileName = SERVICES_DIRECTORY + type.getName();
-            Enumeration<java.net.URL> urls;
-            if (classLoader != null) {
-                urls = classLoader.getResources(fileName);
-            } else {
-                urls = ClassLoader.getSystemResources(fileName);
-            }
-            if (urls != null) {
-                while (urls.hasMoreElements()) {
-                    java.net.URL url = urls.nextElement();
-                    try {
-                        BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), "utf-8"));
-                        try {
-                            String line = null;
-                            while ((line = reader.readLine()) != null) {
-                                final int ci = line.indexOf('#');
-                                if (ci >= 0) line = line.substring(0, ci);
-                                line = line.trim();
-                                if (line.length() > 0) {
-                                    try {
-                                        String name = null;
-                                        int i = line.indexOf('=');
-                                        if (i > 0) {
-                                            name = line.substring(0, i).trim();
-                                            line = line.substring(i + 1).trim();
-                                        }
-                                        Class<?> clazz = Class.forName(line, true, classLoader);
-                                        if (! type.isAssignableFrom(clazz)) {
-                                            throw new IllegalStateException("Error when load extension class(interface: " +
-                                                    type + ", class line: " + clazz.getName() + "), class " 
-                                                    + clazz.getName() + "is not subtype of interface.");
-                                        }
-                                        if (clazz.isAnnotationPresent(Adaptive.class)) {
-                                            if(cachedAdaptiveClass == null) {
-                                                cachedAdaptiveClass = clazz;
-                                            } else if (! cachedAdaptiveClass.equals(clazz)) {
-                                                throw new IllegalStateException("More than 1 adaptive class found: "
-                                                        + cachedAdaptiveClass.getClass().getName()
-                                                        + ", " + clazz.getClass().getName());
-                                            }
-                                        } else {
-                                            try {
-                                                clazz.getConstructor(type);
-                                                Set<Class<?>> wrappers = cachedWrapperClasses;
-                                                if (wrappers == null) {
-                                                    cachedWrapperClasses = new ConcurrentHashSet<Class<?>>();
-                                                    wrappers = cachedWrapperClasses;
-                                                }
-                                                wrappers.add(clazz);
-                                            } catch (NoSuchMethodException e) {
-                                                clazz.getConstructor();
-                                                if (name == null || name.length() == 0) {
-                                                    name = findAnnotationName(clazz);
-                                                    if (name == null || name.length() == 0) {
-                                                        if (clazz.getSimpleName().length() > type.getSimpleName().length()
-                                                                && clazz.getSimpleName().endsWith(type.getSimpleName())) {
-                                                            name = clazz.getSimpleName().substring(0, clazz.getSimpleName().length() - type.getSimpleName().length()).toLowerCase();
-                                                        } else {
-                                                            throw new IllegalStateException("No such extension name for the class " + clazz.getName() + " in the config " + url);
-                                                        }
-                                                    }
-                                                }
-                                                String[] names = NAME_SEPARATOR.split(name);
-                                                for (String n : names) {
-                                                    if (! cachedNames.containsKey(clazz)) {
-                                                        cachedNames.put(clazz, n);
-                                                    }
-                                                    Class<?> c = extensionClasses.get(n);
-                                                    if (c == null) {
-                                                        extensionClasses.put(n, clazz);
-                                                    } else if (c != clazz) {
-                                                        throw new IllegalStateException("Duplicate extension " + type.getName() + " name " + n + " on " + c.getName() + " and " + clazz.getName());
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    } catch (Throwable t) {
-                                        IllegalStateException e = new IllegalStateException("Failed to load extension class(interface: " + type + ", class line: " + line + ") in " + url + ", cause: " + t.getMessage(), t);
-                                        exceptions.put(line, e);
-                                    }
-                                }
-                            } // end of while read lines
-                        } finally {
-                            reader.close();
-                        }
-                    } catch (Throwable t) {
-                        logger.error("Exception when load extension class(interface: " +
-                                            type + ", class file: " + url + ") in " + url, t);
-                    }
-                } // end of while urls
-            }
-        } catch (Throwable t) {
-            logger.error("Exception when load extension class(interface: " +
-                    type + ", description file: " + fileName + ").", t);
-        }
-        return extensionClasses;
-    }
-    
-    private String findAnnotationName(Class<?> clazz) {
-        Extension extension = clazz.getAnnotation(Extension.class);
-        return extension == null ? null : extension.value();
-    }
-    
-    @SuppressWarnings("unchecked")
-    private T createAdaptiveExtension() {
-        try {
-            return injectExtension((T) getAdaptiveExtensionClass().newInstance());
-        } catch (Exception e) {
-            throw new IllegalStateException("Can not create adaptive extenstion " + type + ", cause: " + e.getMessage(), e);
-        }
-    }
-    
-    private Class<?> getAdaptiveExtensionClass() {
-        getExtensionClasses();
-        if (cachedAdaptiveClass != null) {
-            return cachedAdaptiveClass;
-        }
-        return cachedAdaptiveClass = createAdaptiveExtensionClass();
-    }
-    
-    private Class<?> createAdaptiveExtensionClass() {
-        ClassLoader classLoader = findClassLoader();
-        
-        Method[] methods = type.getMethods();
-        boolean hasAdaptiveAnnotation = false;
-        for(Method m : methods) {
-            if(m.isAnnotationPresent(Adaptive.class)) {
-                hasAdaptiveAnnotation = true;
-                break;
-            }
-        }
-        // 完全没有Adaptive方法,则不需要生成Adaptive类
-        if(! hasAdaptiveAnnotation)
-            throw new IllegalStateException("No adaptive method on extension " + type.getName() + ", refuse to create the adaptive class!");
-        
-        ClassGenerator cg = ClassGenerator.newInstance(classLoader);
-        cg.setClassName(type.getName() + "$Adpative");
-        cg.addInterface(type);
-        cg.addDefaultConstructor();
-        
-        for (Method method : methods) {
-            Class<?> rt = method.getReturnType();
-            Class<?>[] pts = method.getParameterTypes();
-
-            Adaptive adaptiveAnnotation = method.getAnnotation(Adaptive.class);
-            StringBuilder code = new StringBuilder(512);
-            if (adaptiveAnnotation == null) {
-                code.append("throw new UnsupportedOperationException(\"method ")
-                        .append(method.toString()).append(" of interface ")
-                        .append(type.getName()).append(" is not adaptive method!\");");
-            } else {
-                int urlTypeIndex = -1;
-                for (int i = 0; i < pts.length; ++i) {
-                    if (pts[i].equals(URL.class)) {
-                        urlTypeIndex = i;
-                        break;
-                    }
-                }
-                // 有类型为URL的参数
-                if (urlTypeIndex != -1) {
-                    // Null Point check
-                    String s = String.format("if (arg%d == null)  { throw new IllegalArgumentException(\"url == null\"); }",
-                                    urlTypeIndex);
-                    code.append(s);
-                    
-                    s = String.format("%s url = arg%d;", URL.class.getName(), urlTypeIndex); 
-                    code.append(s);
-                }
-                // 参数没有URL类型
-                else {
-                    String attribMethod = null;
-                    
-                    // 找到参数的URL属性
-                    LBL_PTS:
-                    for (int i = 0; i < pts.length; ++i) {
-                        Method[] ms = pts[i].getMethods();
-                        for (Method m : ms) {
-                            String name = m.getName();
-                            if ((name.startsWith("get") || name.length() > 3)
-                                    && Modifier.isPublic(m.getModifiers())
-                                    && !Modifier.isStatic(m.getModifiers())
-                                    && m.getParameterTypes().length == 0
-                                    && m.getReturnType() == URL.class) {
-                                urlTypeIndex = i;
-                                attribMethod = name;
-                                break LBL_PTS;
-                            }
-                        }
-                    }
-                    if(attribMethod == null) {
-                        throw new IllegalStateException("fail to create adative class for interface " + type.getName()
-                        		+ ": not found url parameter or url attribute in parameters of method " + method.getName());
-                    }
-                    
-                    // Null point check
-                    String s = String.format("if (arg%d == null)  { throw new IllegalArgumentException(\"%s argument == null\"); }",
-                                    urlTypeIndex, pts[urlTypeIndex].getName());
-                    code.append(s);
-                    s = String.format("if (arg%d.%s() == null)  { throw new IllegalArgumentException(\"%s argument %s() == null\"); }",
-                                    urlTypeIndex, attribMethod, pts[urlTypeIndex].getName(), attribMethod);
-                    code.append(s);
-
-                    s = String.format("%s url = arg%d.%s();",URL.class.getName(), urlTypeIndex, attribMethod); 
-                    code.append(s);
-                }
-                
-                String[] value = adaptiveAnnotation.value();
-                // 没有设置Key,则使用“扩展点接口名的点分隔 作为Key
-                if(value.length == 0) {
-                    char[] charArray = type.getSimpleName().toCharArray();
-                    StringBuilder sb = new StringBuilder(128);
-                    for (int i = 0; i < charArray.length; i++) {
-                        if(Character.isUpperCase(charArray[i])) {
-                            if(i != 0) {
-                                sb.append(".");
-                            }
-                            sb.append(Character.toLowerCase(charArray[i]));
-                        }
-                        else {
-                            sb.append(charArray[i]);
-                        }
-                    }
-                    value = new String[] {sb.toString()};
-                }
-                
-                String defaultExtName = cachedDefaultName;
-                String getNameCode = null;
-                for (int i = value.length - 1; i >= 0; --i) {
-                    if(i == value.length - 1) {
-                        if(null != defaultExtName) {
-                            if(!"protocol".equals(value[i]))
-                                getNameCode = String.format("url.getParameter(\"%s\", \"%s\")", value[i], defaultExtName);
-                            else
-                                getNameCode = String.format("( url.getProtocol() == null ? \"%s\" : url.getProtocol() )", defaultExtName);
-                        }
-                        else {
-                            if(!"protocol".equals(value[i]))
-                                getNameCode = String.format("url.getParameter(\"%s\")", value[i]);
-                            else
-                                getNameCode = "url.getProtocol()";
-                        }
-                    }
-                    else {
-                        if(!"protocol".equals(value[i]))
-                            getNameCode = String.format("url.getParameter(\"%s\", %s)", value[i], getNameCode);
-                        else
-                            getNameCode = String.format("( url.getProtocol() == null ? (%s) : url.getProtocol() )", getNameCode);
-                    }
-                }
-                code.append("String extName = ").append(getNameCode).append(";");
-                // check extName == null?
-                String s = String.format("if(extName == null) {" +
-                		"throw new IllegalStateException(\"Fail to get extension(%s) name from url(\" + url.toString() + \") use keys(%s)\"); }",
-                        type.getName(), Arrays.toString(value));
-                code.append(s);
-                
-                s = String.format("%s extension = (%<s)%s.getExtensionLoader(%s.class).getExtension(extName);",
-                        type.getName(), ExtensionLoader.class.getName(), type.getName());
-                code.append(s);
-                
-                // return statement
-                if (!rt.equals(void.class)) {
-                    code.append("return ");
-                }
-
-                s = String.format("extension.%s(", method.getName());
-                code.append(s);
-                for (int i = 0; i < pts.length; i++) {
-                    if (i != 0)
-                        code.append(", ");
-                    code.append("arg").append(i);
-                }
-                code.append(");");
-            }
-            
-            cg.addMethod(method.getName(), method.getModifiers(), rt, pts,
-                    method.getExceptionTypes(), code.toString());
-        }
-        return cg.toClass();
-    }
-
-    private static ClassLoader findClassLoader() {
-        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-        if (classLoader != null) {
-            return classLoader;
-        }
-        classLoader = ExtensionLoader.class.getClassLoader();
-        return classLoader;
-    }
-    
-    @Override
-    public String toString() {
-        return this.getClass().getName() + "[" + type.getName() + "]";
-    }
-    
-}

src/main/java/com/alibaba/oldratlee/cooma/internal/bytecode/ClassGenerator.java

-package com.alibaba.oldratlee.cooma.internal.bytecode;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javassist.CannotCompileException;
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtConstructor;
-import javassist.CtField;
-import javassist.CtMethod;
-import javassist.CtNewConstructor;
-import javassist.CtNewMethod;
-import javassist.LoaderClassPath;
-import javassist.NotFoundException;
-
-import com.alibaba.oldratlee.cooma.internal.clazz.ReflectUtils;
-
-/**
- * ClassGenerator
- * 
- * @author qian.lei
- */
-
-public final class ClassGenerator
-{
-	public static interface DC{} // dynamic class tag interface.
-
-	private static final AtomicLong CLASS_NAME_COUNTER = new AtomicLong(0);
-
-	private static final String SIMPLE_NAME_TAG = "<init>";
-
-	private static final Map<ClassLoader, ClassPool> POOL_MAP = new ConcurrentHashMap<ClassLoader, ClassPool>(); //ClassLoader - ClassPool
-
-	public static ClassGenerator newInstance()
-	{
-		return new ClassGenerator(getClassPool(Thread.currentThread().getContextClassLoader()));
-	}
-
-	public static ClassGenerator newInstance(ClassLoader loader)
-	{
-		return new ClassGenerator(getClassPool(loader));
-	}
-
-	public static boolean isDynamicClass(Class<?> cl)
-	{
-		return ClassGenerator.DC.class.isAssignableFrom(cl);
-	}
-
-	public static ClassPool getClassPool(ClassLoader loader)
-	{
-		if( loader == null )
-			return ClassPool.getDefault();
-
-		ClassPool pool = POOL_MAP.get(loader);
-		if( pool == null )
-		{
-			pool = new ClassPool(true);
-			pool.appendClassPath(new LoaderClassPath(loader));
-			POOL_MAP.put(loader, pool);
-		}
-		return pool;
-	}
-
-	private ClassPool mPool;
-
-	private CtClass mCtc;
-
-	private String mClassName, mSuperClass;
-
-	private Set<String> mInterfaces;
-
-	private List<String> mFields, mConstructors, mMethods;
-
-	private Map<String, Method> mCopyMethods; // <method desc,method instance>
-
-	private Map<String, Constructor<?>> mCopyConstructors; // <constructor desc,constructor instance>
-
-	private boolean mDefaultConstructor = false;
-
-	private ClassGenerator(){}
-
-	private ClassGenerator(ClassPool pool)
-	{
-		mPool = pool;
-	}
-
-	public String getClassName()
-	{
-		return mClassName;
-	}
-
-	public ClassGenerator setClassName(String name)
-	{
-		mClassName = name;
-		return this;
-	}
-
-	public ClassGenerator addInterface(String cn)
-	{
-		if( mInterfaces == null )
-			mInterfaces = new HashSet<String>();
-		mInterfaces.add(cn);
-		return this;
-	}
-
-	public ClassGenerator addInterface(Class<?> cl)
-	{
-		return addInterface(cl.getName());
-	}
-
-	public ClassGenerator setSuperClass(String cn)
-	{
-		mSuperClass = cn;
-		return this;
-	}
-
-	public ClassGenerator setSuperClass(Class<?> cl)
-	{
-		mSuperClass = cl.getName();
-		return this;
-	}
-
-	public ClassGenerator addField(String code)
-	{
-		if( mFields == null )
-			mFields = new ArrayList<String>();
-		mFields.add(code);
-		return this;
-	}
-
-	public ClassGenerator addField(String name, int mod, Class<?> type)
-	{
-		return addField(name, mod, type, null);
-	}
-
-	public ClassGenerator addField(String name, int mod, Class<?> type, String def)
-	{
-		StringBuilder sb = new StringBuilder();
-		sb.append(modifier(mod)).append(' ').append(ReflectUtils.getName(type)).append(' ');
-		sb.append(name);
-		if( def != null && def.length() > 0 )
-		{
-			sb.append('=');
-			sb.append(def);
-		}
-		sb.append(';');
-		return addField(sb.toString());
-	}
-
-	public ClassGenerator addMethod(String code)
-	{
-		if( mMethods == null )
-			mMethods = new ArrayList<String>();
-		mMethods.add(code);
-		return this;
-	}
-
-	public ClassGenerator addMethod(String name, int mod, Class<?> rt, Class<?>[] pts, String body)
-	{
-		return addMethod(name, mod, rt, pts, null, body);
-	}
-
-	public ClassGenerator addMethod(String name, int mod, Class<?> rt, Class<?>[] pts, Class<?>[] ets, String body)
-	{
-		StringBuilder sb = new StringBuilder();
-		sb.append(modifier(mod)).append(' ').append(ReflectUtils.getName(rt)).append(' ').append(name);
-		sb.append('(');
-		for(int i=0;i<pts.length;i++)
-		{
-			if( i > 0 )
-				sb.append(',');
-			sb.append(ReflectUtils.getName(pts[i]));
-			sb.append(" arg").append(i);
-		}
-		sb.append(')');
-		if( ets != null && ets.length > 0 )
-		{
-			sb.append(" throws ");
-			for(int i=0;i<ets.length;i++)
-			{
-				if( i > 0 )
-					sb.append(',');
-				sb.append(ReflectUtils.getName(ets[i]));
-			}
-		}
-		sb.append('{').append(body).append('}');
-		return addMethod(sb.toString());
-	}
-
-	public ClassGenerator addMethod(Method m)
-	{
-		addMethod(m.getName(), m);
-		return this;
-	}
-
-	public ClassGenerator addMethod(String name, Method m)
-	{
-		String desc = name + ReflectUtils.getDescWithoutMethodName(m);
-		addMethod(':' + desc);
-		if( mCopyMethods == null )
-			mCopyMethods = new ConcurrentHashMap<String, Method>(8);
-		mCopyMethods.put(desc, m);
-		return this;
-	}
-
-	public ClassGenerator addConstructor(String code)
-	{
-		if( mConstructors == null )
-			mConstructors = new LinkedList<String>();
-		mConstructors.add(code);
-		return this;
-	}
-
-	public ClassGenerator addConstructor(int mod, Class<?>[] pts, String body)
-	{
-		return addConstructor(mod, pts, null, body);
-	}
-
-	public ClassGenerator addConstructor(int mod, Class<?>[] pts, Class<?>[] ets, String body)
-	{
-		StringBuilder sb = new StringBuilder();
-		sb.append(modifier(mod)).append(' ').append(SIMPLE_NAME_TAG);
-		sb.append('(');
-		for(int i=0;i<pts.length;i++)
-		{
-			if( i > 0 )
-				sb.append(',');
-			sb.append(ReflectUtils.getName(pts[i]));
-			sb.append(" arg").append(i);
-		}
-		sb.append(')');
-		if( ets != null && ets.length > 0 )
-		{
-			sb.append(" throws ");
-			for(int i=0;i<ets.length;i++)
-			{
-				if( i > 0 )
-					sb.append(',');
-				sb.append(ReflectUtils.getName(ets[i]));
-			}
-		}
-		sb.append('{').append(body).append('}');
-		return addConstructor(sb.toString());
-	}
-
-	public ClassGenerator addConstructor(Constructor<?> c)
-	{
-		String desc = ReflectUtils.getDesc(c);
-		addConstructor(":"+desc);
-		if( mCopyConstructors == null )
-			mCopyConstructors = new ConcurrentHashMap<String, Constructor<?>>(4);
-		mCopyConstructors.put(desc, c);
-		return this;
-	}
-
-	public ClassGenerator addDefaultConstructor()
-	{
-		mDefaultConstructor = true;
-		return this;
-	}
-
-	public Class<?> toClass()
-	{
-		if( mCtc != null )
-			mCtc.detach();
-		long id = CLASS_NAME_COUNTER.getAndIncrement();
-		try
-		{
-			CtClass ctcs = mSuperClass == null ? null : mPool.get(mSuperClass);
-			if( mClassName == null )
-				mClassName = ( mSuperClass == null || javassist.Modifier.isPublic(ctcs.getModifiers())
-						? ClassGenerator.class.getName() : mSuperClass + "$sc" ) + id;
-			mCtc = mPool.makeClass(mClassName);
-			if( mSuperClass != null )
-				mCtc.setSuperclass(ctcs);
-			mCtc.addInterface(mPool.get(DC.class.getName())); // add dynamic class tag.
-			if( mInterfaces != null )
-				for( String cl : mInterfaces ) mCtc.addInterface(mPool.get(cl));
-			if( mFields != null )
-				for( String code : mFields ) mCtc.addField(CtField.make(code, mCtc));
-			if( mMethods != null )
-			{
-				for( String code : mMethods )
-				{
-					if( code.charAt(0) == ':' )
-						mCtc.addMethod(CtNewMethod.copy(getCtMethod(mCopyMethods.get(code.substring(1))), code.substring(1, code.indexOf('(')), mCtc, null));
-					else
-						mCtc.addMethod(CtNewMethod.make(code, mCtc));
-				}
-			}
-			if( mDefaultConstructor )
-				mCtc.addConstructor(CtNewConstructor.defaultConstructor(mCtc));
-			if( mConstructors != null )
-			{
-				for( String code : mConstructors )
-				{
-					if( code.charAt(0) == ':' )
-					{
-						mCtc.addConstructor(CtNewConstructor.copy(getCtConstructor(mCopyConstructors.get(code.substring(1))), mCtc, null));
-					}
-					else
-					{
-						String[] sn = mCtc.getSimpleName().split("\\$+"); // inner class name include $.
-						mCtc.addConstructor(CtNewConstructor.make(code.replaceFirst(SIMPLE_NAME_TAG, sn[sn.length-1]), mCtc));
-					}
-				}
-			}
-			return mCtc.toClass();
-		}
-		catch(RuntimeException e)
-		{
-			throw e;
-		}
-		catch(NotFoundException e)
-		{
-			throw new RuntimeException(e.getMessage(), e);
-		}
-		catch(CannotCompileException e)
-		{
-			throw new RuntimeException(e.getMessage(), e);
-		}
-	}
-
-	public void release()
-	{
-		if( mCtc != null ) mCtc.detach();
-		if( mInterfaces != null ) mInterfaces.clear();
-		if( mFields != null ) mFields.clear();
-		if( mMethods != null ) mMethods.clear();
-		if( mConstructors != null ) mConstructors.clear();
-		if( mCopyMethods != null ) mCopyMethods.clear();
-		if( mCopyConstructors != null ) mCopyConstructors.clear();
-	}
-
-	private CtClass getCtClass(Class<?> c) throws NotFoundException
-	{
-		return mPool.get(c.getName());
-	}
-
-	private CtMethod getCtMethod(Method m) throws NotFoundException
-	{
-		return getCtClass(m.getDeclaringClass()).getMethod(m.getName(),ReflectUtils.getDescWithoutMethodName(m));
-	}
-
-	private CtConstructor getCtConstructor(Constructor<?> c) throws NotFoundException
-	{
-		return getCtClass(c.getDeclaringClass()).getConstructor(ReflectUtils.getDesc(c));
-	}
-
-	private static String modifier(int mod)
-	{
-		if( Modifier.isPublic(mod) ) return "public";
-		if( Modifier.isProtected(mod) ) return "protected";
-		if( Modifier.isPrivate(mod) ) return "private";
-		return "";
-	}
-}

src/main/java/com/alibaba/oldratlee/cooma/internal/bytecode/Mixin.java

-package com.alibaba.oldratlee.cooma.internal.bytecode;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicLong;
-
-import com.alibaba.oldratlee.cooma.internal.clazz.ClassHelper;
-import com.alibaba.oldratlee.cooma.internal.clazz.ReflectUtils;
-
-/**
- * Mixin
- * 
- * @author qian.lei
- */
-
-public abstract class Mixin
-{
-	private static AtomicLong MIXIN_CLASS_COUNTER = new AtomicLong(0);
-
-	private static final String PACKAGE_NAME = Mixin.class.getPackage().getName();
-
-	public static interface MixinAware{ void setMixinInstance(Object instance); }
-
-	/**
-	 * mixin interface and delegates.
-	 * all class must be public.
-	 * 
-	 * @param ics interface class array.
-	 * @param dc delegate class.
-	 * @return Mixin instance.
-	 */
-	public static Mixin mixin(Class<?>[] ics, Class<?> dc)
-	{
-		return mixin(ics, new Class[]{dc});
-	}
-
-	/**
-	 * mixin interface and delegates.
-	 * all class must be public.
-	 * 
-	 * @param ics interface class array.
-	 * @param dc delegate class.
-	 * @param cl class loader.
-	 * @return Mixin instance.
-	 */
-	public static Mixin mixin(Class<?>[] ics, Class<?> dc, ClassLoader cl)
-	{
-		return mixin(ics, new Class[]{dc}, cl);
-	}
-
-	/**
-	 * mixin interface and delegates.
-	 * all class must be public.
-	 * 
-	 * @param ics interface class array.
-	 * @param dcs delegate class array.
-	 * @return Mixin instance.
-	 */
-	public static Mixin mixin(Class<?>[] ics, Class<?>[] dcs)
-	{
-		return mixin(ics, dcs, ClassHelper.getClassLoader(ics[0]));
-	}
-
-	/**
-	 * mixin interface and delegates.
-	 * all class must be public.
-	 * 
-	 * @param ics interface class array.
-	 * @param dcs delegate class array.
-	 * @param cl class loader.
-	 * @return Mixin instance.
-	 */
-	public static Mixin mixin(Class<?>[] ics, Class<?>[] dcs, ClassLoader cl)
-	{
-		assertInterfaceArray(ics);
-
-		long id = MIXIN_CLASS_COUNTER.getAndIncrement();
-		String pkg = null;
-		ClassGenerator ccp = null, ccm = null;
-		try
-		{
-			ccp = ClassGenerator.newInstance(cl);
-
-			// impl constructor
-			StringBuilder code = new StringBuilder();
-			for(int i=0;i<dcs.length;i++)
-			{
-				if( !Modifier.isPublic(dcs[i].getModifiers()) )
-				{
-					String npkg = dcs[i].getPackage().getName();
-					if( pkg == null )
-					{
-						pkg = npkg;
-					}
-					else
-					{
-						if( !pkg.equals(npkg)  )
-							throw new IllegalArgumentException("non-public interfaces class from different packages");
-					}
-				}
-
-				ccp.addField("private " + dcs[i].getName() + " d" + i + ";");
-
-				code.append("d").append(i).append(" = (").append(dcs[i].getName()).append(")$1[").append(i).append("];\n");
-				if( MixinAware.class.isAssignableFrom(dcs[i]) )
-					code.append("d").append(i).append(".setMixinInstance(this);\n");
-			}
-			ccp.addConstructor(Modifier.PUBLIC, new Class<?>[]{ Object[].class }, code.toString());
-
-			// impl methods.
-			Set<String> worked = new HashSet<String>();
-			for(int i=0;i<ics.length;i++)
-			{
-				if( !Modifier.isPublic(ics[i].getModifiers()) )
-				{
-					String npkg = ics[i].getPackage().getName();
-					if( pkg == null )
-					{
-						pkg = npkg;
-					}
-					else
-					{
-						if( !pkg.equals(npkg)  )
-							throw new IllegalArgumentException("non-public delegate class from different packages");
-					}
-				}
-
-				ccp.addInterface(ics[i]);
-
-				for( Method method : ics[i].getMethods() )
-				{
-					if( "java.lang.Object".equals(method.getDeclaringClass().getName()) )
-						continue;
-
-					String desc = ReflectUtils.getDesc(method);
-					if( worked.contains(desc) )
-						continue;
-					worked.add(desc);
-
-					int ix = findMethod(dcs, desc);
-					if( ix < 0 )
-						throw new RuntimeException("Missing method [" + desc + "] implement.");
-
-					Class<?> rt = method.getReturnType();
-					String mn = method.getName();
-					if( Void.TYPE.equals(rt) )
-						ccp.addMethod(mn, method.getModifiers(), rt, method.getParameterTypes(), method.getExceptionTypes(),
-								"d" + ix + "." + mn + "($$);");
-					else
-						ccp.addMethod(mn, method.getModifiers(), rt, method.getParameterTypes(), method.getExceptionTypes(),
-								"return ($r)d" + ix + "." + mn + "($$);");
-				}
-			}
-
-			if( pkg == null )
-				pkg = PACKAGE_NAME;
-
-			// create MixinInstance class.
-			String micn = pkg + ".mixin" + id;
-			ccp.setClassName(micn);
-			ccp.toClass();
-
-			// create Mixin class.
-			String fcn = Mixin.class.getName() + id;
-			ccm = ClassGenerator.newInstance(cl);
-			ccm.setClassName(fcn);
-			ccm.addDefaultConstructor();
-			ccm.setSuperClass(Mixin.class.getName());
-			ccm.addMethod("public Object newInstance(Object[] delegates){ return new " + micn + "($1); }");
-			Class<?> mixin = ccm.toClass();
-			return (Mixin)mixin.newInstance();
-		}
-		catch(RuntimeException e)
-		{
-			throw e;
-		}
-		catch(Exception e)
-		{
-			throw new RuntimeException(e.getMessage(), e);
-		}
-		finally
-		{
-			// release ClassGenerator
-			if( ccp != null )
-				ccp.release();
-			if( ccm != null )
-				ccm.release();
-		}
-	}
-
-	/**
-	 * new Mixin instance.
-	 * 
-	 * @param ds delegates instance.
-	 * @return instance.
-	 */
-	abstract public Object newInstance(Object[] ds);
-
-	protected Mixin(){}
-
-	private static int findMethod(Class<?>[] dcs, String desc)
-	{
-		Class<?> cl;
-		Method[] methods;
-		for(int i=0;i<dcs.length;i++)
-		{
-			cl = dcs[i];
-			methods = cl.getMethods();
-			for( Method method : methods )
-			{
-				if( desc.equals(ReflectUtils.getDesc(method)) )
-					return i;
-			}
-		}
-		return -1;
-	}
-
-	private static void assertInterfaceArray(Class<?>[] ics)
-	{
-		for(int i=0;i<ics.length;i++)
-			if( !ics[i].isInterface() )
-				throw new RuntimeException("Class " + ics[i].getName() + " is not a interface.");
-	}
-}

src/main/java/com/alibaba/oldratlee/cooma/internal/bytecode/NoSuchMethodException.java

-package com.alibaba.oldratlee.cooma.internal.bytecode;
-
-/**
- * NoSuchMethodException.
- * 
- * @author qian.lei
- */
-
-public class NoSuchMethodException extends RuntimeException
-{
-	private static final long serialVersionUID = -2725364246023268766L;
-
-	public NoSuchMethodException()
-	{
-		super();
-	}
-
-	public NoSuchMethodException(String msg)
-	{
-		super(msg);
-	}
-}

src/main/java/com/alibaba/oldratlee/cooma/internal/bytecode/NoSuchPropertyException.java

-package com.alibaba.oldratlee.cooma.internal.bytecode;
-
-/**
- * NoSuchPropertyException.
- * 
- * @author qian.lei
- */
-
-public class NoSuchPropertyException extends RuntimeException
-{
-	private static final long serialVersionUID = -2725364246023268766L;
-
-	public NoSuchPropertyException()
-	{
-		super();
-	}
-
-	public NoSuchPropertyException(String msg)
-	{
-		super(msg);
-	}
-}

src/main/java/com/alibaba/oldratlee/cooma/internal/bytecode/Proxy.java

-package com.alibaba.oldratlee.cooma.internal.bytecode;
-
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.WeakHashMap;
-import java.util.concurrent.atomic.AtomicLong;
-
-import com.alibaba.oldratlee.cooma.internal.clazz.ClassHelper;
-import com.alibaba.oldratlee.cooma.internal.clazz.ReflectUtils;
-
-/**
- * Proxy.
- * 
- * @author qian.lei
- */
-
-public abstract class Proxy
-{
-	private static final AtomicLong PROXY_CLASS_COUNTER = new AtomicLong(0);
-
-	private static final String PACKAGE_NAME = Proxy.class.getPackage().getName();
-
-	public static final InvocationHandler RETURN_NULL_INVOKER = new InvocationHandler(){
-		public Object invoke(Object proxy, Method method, Object[] args){ return null; }
-	};
-
-	public static final InvocationHandler THROW_UNSUPPORTED_INVOKER = new InvocationHandler(){
-		public Object invoke(Object proxy, Method method, Object[] args){ throw new UnsupportedOperationException("Method [" + ReflectUtils.getName(method) + "] unimplemented."); }
-	};
-
-	private static final Map<ClassLoader, Map<String, Object>> ProxyCacheMap = new WeakHashMap<ClassLoader, Map<String, Object>>();
-
-	private static final Object PendingGenerationMarker = new Object();
-
-	/**
-	 * Get proxy.
-	 * 
-	 * @param ics interface class array.
-	 * @return Proxy instance.
-	 */
-	public static Proxy getProxy(Class<?>... ics)
-	{
-		return getProxy(ClassHelper.getClassLoader(ics[0]), ics);
-	}
-
-	/**
-	 * Get proxy.
-	 * @param cl class loader.
-	 * @param ics interface class array.
-	 * 
-	 * @return Proxy instance.
-	 */
-	public static Proxy getProxy(ClassLoader cl, Class<?>... ics)
-	{
-		if( ics.length > 65535 )
-			throw new IllegalArgumentException("interface limit exceeded");
-		
-		StringBuilder sb = new StringBuilder();
-		for(int i=0;i<ics.length;i++)
-		{
-			String itf = ics[i].getName();
-			if( !ics[i].isInterface() )
-				throw new RuntimeException(itf + " is not a interface.");
-
-			Class<?> tmp = null;
-			try
-			{
-				tmp = Class.forName(itf, false, cl);
-			}
-			catch(ClassNotFoundException e)
-			{}
-
-			if( tmp != ics[i] )
-				throw new IllegalArgumentException(ics[i] + " is not visible from class loader");
-
-		    sb.append(itf).append(';');
-		}
-
-		// use interface class name list as key.
-		String key = sb.toString();
-
-		// get cache by class loader.
-		Map<String, Object> cache;
-		synchronized( ProxyCacheMap )
-		{
-			cache = ProxyCacheMap.get(cl);
-			if( cache == null )
-		    {
-				cache = new HashMap<String, Object>();
-				ProxyCacheMap.put(cl, cache);
-		    }
-		}
-
-		Proxy proxy = null;
-		synchronized( cache )
-		{
-			do
-			{
-				Object value = cache.get(key);
-				if( value instanceof Reference<?> )
-				{
-					proxy = (Proxy)((Reference<?>)value).get();
-					if( proxy != null )
-						return proxy;
-				}
-
-				if( value == PendingGenerationMarker )
-				{
-					try{ cache.wait(); }catch(InterruptedException e){}
-				}
-				else
-				{
-					cache.put(key, PendingGenerationMarker);
-					break;
-				}
-			}
-			while( true );
-		}
-
-		long id = PROXY_CLASS_COUNTER.getAndIncrement();
-		String pkg = null;
-		ClassGenerator ccp = null, ccm = null;
-		try
-		{
-			ccp = ClassGenerator.newInstance(cl);
-
-			Set<String> worked = new HashSet<String>();
-			List<Method> methods = new ArrayList<Method>();
-
-			for(int i=0;i<ics.length;i++)
-			{
-				if( !Modifier.isPublic(ics[i].getModifiers()) )
-				{
-					String npkg = ics[i].getPackage().getName();
-					if( pkg == null )
-					{
-						pkg = npkg;
-					}
-					else
-					{
-						if( !pkg.equals(npkg)  )
-							throw new IllegalArgumentException("non-public interfaces from different packages");
-					}
-				}
-				ccp.addInterface(ics[i]);
-
-				for( Method method : ics[i].getMethods() )
-				{
-					String desc = ReflectUtils.getDesc(method);
-					if( worked.contains(desc) )
-						continue;
-					worked.add(desc);
-
-					int ix = methods.size();
-					Class<?> rt = method.getReturnType();
-					Class<?>[] pts = method.getParameterTypes();
-
-					StringBuilder code = new StringBuilder("Object[] args = new Object[").append(pts.length).append("];");
-					for(int j=0;j<pts.length;j++)
-						code.append(" args[").append(j).append("] = ($w)$").append(j+1).append(";");
-					code.append(" Object ret = handler.invoke(this, methods[" + ix + "], args);");
-					if( !Void.TYPE.equals(rt) )
-						code.append(" return ").append(asArgument(rt, "ret")).append(";");
-
-					methods.add(method);
-					ccp.addMethod(method.getName(), method.getModifiers(), rt, pts, method.getExceptionTypes(), code.toString());
-				}
-			}
-
-			if( pkg == null )
-				pkg = PACKAGE_NAME;
-
-			// create ProxyInstance class.
-			String pcn = pkg + ".proxy" + id;
-			ccp.setClassName(pcn);
-			ccp.addField("public static java.lang.reflect.Method[] methods;");
-			ccp.addField("private " + InvocationHandler.class.getName() + " handler;");
-			ccp.addConstructor(Modifier.PUBLIC, new Class<?>[]{ InvocationHandler.class }, new Class<?>[0], "handler=$1;");
-			Class<?> clazz = ccp.toClass();
-			clazz.getField("methods").set(null, methods.toArray(new Method[0]));
-
-			// create Proxy class.
-			String fcn = Proxy.class.getName() + id;
-			ccm = ClassGenerator.newInstance(cl);
-			ccm.setClassName(fcn);
-			ccm.addDefaultConstructor();
-			ccm.setSuperClass(Proxy.class);
-			ccm.addMethod("public Object newInstance(" + InvocationHandler.class.getName() + " h){ return new " + pcn + "($1); }");
-			Class<?> pc = ccm.toClass();
-			proxy = (Proxy)pc.newInstance();
-		}
-		catch(RuntimeException e)
-		{
-			throw e;
-		}
-		catch(Exception e)
-		{
-			throw new RuntimeException(e.getMessage(), e);
-		}
-		finally
-		{
-			// release ClassGenerator
-			if( ccp != null )
-				ccp.release();
-			if( ccm != null )
-				ccm.release();
-			synchronized( cache )
-			{
-				if( proxy == null )
-					cache.remove(key);
-				else
-					cache.put(key, new WeakReference<Proxy>(proxy));
-				cache.notifyAll();
-			}
-		}
-		return proxy;
-	}
-
-	/**
-	 * get instance with default handler.
-	 * 
-	 * @return instance.
-	 */
-	public Object newInstance()
-	{
-		return newInstance(THROW_UNSUPPORTED_INVOKER);
-	}
-
-	/**
-	 * get instance with special handler.
-	 * 
-	 * @return instance.
-	 */
-	abstract public Object newInstance(InvocationHandler handler);
-
-	protected Proxy(){}
-
-	private static String asArgument(Class<?> cl, String name)
-	{
-		if( cl.isPrimitive() )
-		{
-			if( Boolean.TYPE == cl )
-				return name + "==null?false:((Boolean)" + name + ").booleanValue()";
-			if( Byte.TYPE == cl )
-				return name + "==null?(byte)0:((Byte)" + name + ").byteValue()";
-			if( Character.TYPE == cl )
-				return name + "==null?(char)0:((Character)" + name + ").charValue()";
-			if( Double.TYPE == cl )
-				return name + "==null?(double)0:((Double)" + name + ").doubleValue()";
-			if( Float.TYPE == cl )
-				return name + "==null?(float)0:((Float)" + name + ").floatValue()";
-			if( Integer.TYPE == cl )
-				return name + "==null?(int)0:((Integer)" + name + ").intValue()";
-			if( Long.TYPE == cl )
-				return name + "==null?(long)0:((Long)" + name + ").longValue()";
-			if( Short.TYPE == cl )
-				return name + "==null?(short)0:((Short)" + name + ").shortValue()";
-			throw new RuntimeException(name+" is unknown primitive type."); 
-		}
-		return "(" + ReflectUtils.getName(cl) + ")"+name;
-	}
-}

src/main/java/com/alibaba/oldratlee/cooma/internal/bytecode/Wrapper.java

-package com.alibaba.oldratlee.cooma.internal.bytecode;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.regex.Matcher;
-
-import com.alibaba.oldratlee.cooma.internal.clazz.ClassHelper;
-import com.alibaba.oldratlee.cooma.internal.clazz.ReflectUtils;
-
-/**
- * Wrapper.
- * 
- * @author qian.lei
- */
-
-public abstract class Wrapper
-{
-	private static AtomicLong WRAPPER_CLASS_COUNTER = new AtomicLong(0);
-
-	private static final Map<Class<?>, Wrapper> WRAPPER_MAP = new ConcurrentHashMap<Class<?>, Wrapper>(); //class wrapper map
-
-	private static final String[] EMPTY_STRING_ARRAY = new String[0];
-
-	private static final String[] OBJECT_METHODS = new String[]{"getClass", "hashCode", "toString", "equals"};
-
-	private static final Wrapper OBJECT_WRAPPER = new Wrapper(){
-		public String[] getMethodNames(){ return OBJECT_METHODS; }
-		public String[] getDeclaredMethodNames(){ return OBJECT_METHODS; }
-		public String[] getPropertyNames(){ return EMPTY_STRING_ARRAY; }
-		public Class<?> getPropertyType(String pn){ return null; }
-		public Object getPropertyValue(Object instance, String pn) throws NoSuchPropertyException{ throw new NoSuchPropertyException("Property [" + pn + "] not found."); }
-		public void setPropertyValue(Object instance, String pn, Object pv) throws NoSuchPropertyException{ throw new NoSuchPropertyException("Property [" + pn + "] not found."); }
-		public boolean hasProperty(String name){ return false; }
-		public Object invokeMethod(Object instance, String mn, Class<?>[] types, Object[] args) throws NoSuchMethodException
-		{
-			if( "getClass".equals(mn) ) return instance.getClass();
-			if( "hashCode".equals(mn) ) return instance.hashCode();
-			if( "toString".equals(mn) ) return instance.toString();
-			if( "equals".equals(mn) )
-			{
-				if( args.length == 1 ) return instance.equals(args[0]);
-				throw new IllegalArgumentException("Invoke method [" + mn + "] argument number error.");
-			}
-			throw new NoSuchMethodException("Method [" + mn + "] not found.");
-		}
-	};
-
-	/**
-	 * get wrapper.
-	 * 
-	 * @param c Class instance.
-	 * @return Wrapper instance(not null).
-	 */
-	public static Wrapper getWrapper(Class<?> c)
-    {
-        while( ClassGenerator.isDynamicClass(c) ) // can not wrapper on dynamic class.
-            c = c.getSuperclass();
-
-        if( c == Object.class )
-            return OBJECT_WRAPPER;
-
-        Wrapper ret = WRAPPER_MAP.get(c);
-        if( ret == null )
-        {
-            ret = makeWrapper(c);
-            WRAPPER_MAP.put(c,ret);
-        }
-        return ret;
-    }
-	/**
-	 * get property name array.
-	 * 
-	 * @return property name array.
-	 */
-	abstract public String[] getPropertyNames();
-
-	/**
-	 * get property type.
-	 * 
-	 * @param pn property name.
-	 * @return Property type or nul.
-	 */
-	abstract public Class<?> getPropertyType(String pn);
-
-	/**
-	 * has property.
-	 * 
-	 * @param name property name.
-	 * @return has or has not.
-	 */
-	abstract public boolean hasProperty(String name);
-
-	/**
-	 * get property value.
-	 * 
-	 * @param instance instance.
-	 * @param pn property name.
-	 * @return value.
-	 */
-	abstract public Object getPropertyValue(Object instance, String pn) throws NoSuchPropertyException, IllegalArgumentException;
-
-	/**
-	 * set property value.