From b1e2b118ebe8158858026bd3eb022b2426856a84 Mon Sep 17 00:00:00 2001 From: wentch <22250530@qq.com> Date: Fri, 22 Jan 2016 10:30:36 +0800 Subject: [PATCH] --- src/org/redkale/util/Creator.java | 53 ++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/src/org/redkale/util/Creator.java b/src/org/redkale/util/Creator.java index e76a150b5..9648fc283 100644 --- a/src/org/redkale/util/Creator.java +++ b/src/org/redkale/util/Creator.java @@ -5,10 +5,12 @@ package org.redkale.util; import java.beans.*; +import java.io.*; import java.lang.annotation.*; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.reflect.*; +import java.net.*; import java.util.*; import jdk.internal.org.objectweb.asm.*; import jdk.internal.org.objectweb.asm.Type; @@ -132,13 +134,13 @@ public interface Creator { } catch (Exception ex) { } Constructor constructor0 = null; - for (Constructor c : clazz.getConstructors()) { + for (Constructor c : clazz.getConstructors()) { //优先找public 的构造函数 if (c.getParameterTypes().length == 0) { //为了兼容android 而不使用 getParameterCount() constructor0 = c; break; } } - if (constructor0 == null) { + if (constructor0 == null) {//其次找非private带ConstructorProperties的构造函数 for (Constructor c : clazz.getDeclaredConstructors()) { if (Modifier.isPrivate(c.getModifiers())) continue; if (c.getAnnotation(ConstructorProperties.class) != null) { @@ -147,6 +149,13 @@ public interface Creator { } } } + if (constructor0 == null) {//最后找非private的构造函数 + for (Constructor c : clazz.getDeclaredConstructors()) { + if (Modifier.isPrivate(c.getModifiers())) continue; + constructor0 = c; + break; + } + } final Constructor constructor = constructor0; if (constructor == null) throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation constructor."); //------------------------------------------------------------- @@ -270,13 +279,41 @@ public interface Creator { } cw.visitEnd(); final byte[] bytes = cw.toByteArray(); + final boolean ispub = Modifier.isPublic(constructor.getModifiers()); + Class resultClazz = null; + if (loader instanceof URLClassLoader && !ispub) { + try { + final URLClassLoader urlLoader = (URLClassLoader) loader; + final URL url = new URL("memclass", "localhost", -1, "/" + newDynName.replace('/', '.') + "/", new URLStreamHandler() { + @Override + protected URLConnection openConnection(URL u) throws IOException { + return new URLConnection(u) { + @Override + public void connect() throws IOException { + } + + @Override + public InputStream getInputStream() throws IOException { + return new ByteArrayInputStream(bytes); + } + }; + } + }); + Method addURLMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); + addURLMethod.setAccessible(true); + addURLMethod.invoke(urlLoader, url); + resultClazz = urlLoader.loadClass(newDynName.replace('/', '.')); + } catch (Throwable t) { //异常无需理会, 使用下一种loader方式 + t.printStackTrace(); + } + } try { - if (!Modifier.isPublic(constructor.getModifiers())) throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation constructor."); - Class resultClazz = new ClassLoader(loader) { - public final Class loadClass(String name, byte[] b) { - return defineClass(name, b, 0, b.length); - } - }.loadClass(newDynName.replace('/', '.'), bytes); + if (!ispub) throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation constructor."); + if (resultClazz == null) resultClazz = new ClassLoader(loader) { + public final Class loadClass(String name, byte[] b) { + return defineClass(name, b, 0, b.length); + } + }.loadClass(newDynName.replace('/', '.'), bytes); return (Creator) resultClazz.newInstance(); } catch (Exception ex) { throw new RuntimeException(ex);