From 53df45456fe86442077dded9f25fd54018c6fc8e Mon Sep 17 00:00:00 2001 From: Redkale <22250530@qq.com> Date: Wed, 7 Mar 2018 11:31:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E6=8E=89=E5=AF=B9sun.misc.Unsafe?= =?UTF-8?q?=E7=9A=84=E4=BE=9D=E8=B5=96=E5=92=8C=E6=9B=BF=E6=8D=A2=E8=BF=87?= =?UTF-8?q?=E6=9C=9F=E6=96=B9=E6=B3=95Class.newInstance()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/module-info.java | 2 - src/org/redkale/boot/Application.java | 4 +- src/org/redkale/boot/LogFileHandler.java | 4 +- src/org/redkale/boot/NodeHttpServer.java | 4 +- src/org/redkale/boot/NodeServer.java | 2 +- src/org/redkale/boot/NodeSncpServer.java | 2 +- .../redkale/net/http/HttpPrepareServlet.java | 4 +- .../redkale/net/http/HttpResourceServlet.java | 7 ++-- src/org/redkale/net/http/HttpServlet.java | 2 +- src/org/redkale/net/http/Rest.java | 4 +- src/org/redkale/net/sncp/Sncp.java | 6 +-- src/org/redkale/net/sncp/SncpClient.java | 2 +- src/org/redkale/net/sncp/SncpDynServlet.java | 4 +- src/org/redkale/source/CacheMemorySource.java | 2 +- src/org/redkale/source/EntityInfo.java | 4 +- src/org/redkale/source/PoolJdbcSource.java | 2 +- src/org/redkale/util/Attribute.java | 4 +- src/org/redkale/util/Creator.java | 4 +- src/org/redkale/util/RedkaleClassLoader.java | 38 +++++++++++++++++++ src/org/redkale/util/Reproduce.java | 4 +- src/org/redkale/util/Utility.java | 37 ++---------------- 21 files changed, 74 insertions(+), 68 deletions(-) diff --git a/src/module-info.java b/src/module-info.java index fc0a4f60f..ab0e22a13 100644 --- a/src/module-info.java +++ b/src/module-info.java @@ -12,8 +12,6 @@ module org.redkale { requires java.sql; requires java.sql.rowset; - requires jdk.unsupported; //sun.misc.Unsafe - exports javax.annotation; exports javax.persistence; diff --git a/src/org/redkale/boot/Application.java b/src/org/redkale/boot/Application.java index 309ac839c..e77116a9a 100644 --- a/src/org/redkale/boot/Application.java +++ b/src/org/redkale/boot/Application.java @@ -275,7 +275,7 @@ public final class Application { try { final String strategyClass = transportConf.getValue("strategy"); if (strategyClass != null && !strategyClass.isEmpty()) { - strategy = (TransportStrategy) classLoader.loadClass(strategyClass).newInstance(); + strategy = (TransportStrategy) classLoader.loadClass(strategyClass).getDeclaredConstructor().newInstance(); } final AtomicInteger counter = new AtomicInteger(); transportExec = Executors.newFixedThreadPool(threads, (Runnable r) -> { @@ -502,7 +502,7 @@ public final class Application { if (listenClass.isEmpty()) continue; Class clazz = classLoader.loadClass(listenClass); if (!ApplicationListener.class.isAssignableFrom(clazz)) continue; - ApplicationListener listener = (ApplicationListener) clazz.newInstance(); + ApplicationListener listener = (ApplicationListener) clazz.getDeclaredConstructor().newInstance(); listener.init(config); this.listeners.add(listener); } diff --git a/src/org/redkale/boot/LogFileHandler.java b/src/org/redkale/boot/LogFileHandler.java index a31abee76..87bb7f858 100644 --- a/src/org/redkale/boot/LogFileHandler.java +++ b/src/org/redkale/boot/LogFileHandler.java @@ -266,7 +266,7 @@ public class LogFileHandler extends Handler { try { if (filterstr != null) { Class clz = ClassLoader.getSystemClassLoader().loadClass(filterstr); - setFilter((Filter) clz.newInstance()); + setFilter((Filter) clz.getDeclaredConstructor().newInstance()); } } catch (Exception e) { } @@ -274,7 +274,7 @@ public class LogFileHandler extends Handler { try { if (formatterstr != null) { Class clz = ClassLoader.getSystemClassLoader().loadClass(formatterstr); - setFormatter((Formatter) clz.newInstance()); + setFormatter((Formatter) clz.getDeclaredConstructor().newInstance()); } } catch (Exception e) { } diff --git a/src/org/redkale/boot/NodeHttpServer.java b/src/org/redkale/boot/NodeHttpServer.java index 51b26b075..4ee0f004a 100644 --- a/src/org/redkale/boot/NodeHttpServer.java +++ b/src/org/redkale/boot/NodeHttpServer.java @@ -136,7 +136,7 @@ public class NodeHttpServer extends NodeServer { for (FilterEntry en : list) { Class clazz = (Class) en.getType(); if (Modifier.isAbstract(clazz.getModifiers())) continue; - final HttpFilter filter = clazz.newInstance(); + final HttpFilter filter = clazz.getDeclaredConstructor().newInstance(); resourceFactory.inject(filter, this); DefaultAnyValue filterConf = (DefaultAnyValue) en.getProperty(); this.httpServer.addHttpFilter(filter, filterConf); @@ -172,7 +172,7 @@ public class NodeHttpServer extends NodeServer { if (Modifier.isAbstract(clazz.getModifiers())) continue; WebServlet ws = clazz.getAnnotation(WebServlet.class); if (ws == null || ws.value().length == 0) continue; - final HttpServlet servlet = clazz.newInstance(); + final HttpServlet servlet = clazz.getDeclaredConstructor().newInstance(); resourceFactory.inject(servlet, this); final String[] mappings = ws.value(); String pref = ws.repair() ? prefix : ""; diff --git a/src/org/redkale/boot/NodeServer.java b/src/org/redkale/boot/NodeServer.java index f0e07a9ed..18cbd4c93 100644 --- a/src/org/redkale/boot/NodeServer.java +++ b/src/org/redkale/boot/NodeServer.java @@ -149,7 +149,7 @@ public abstract class NodeServer { String interceptorClass = this.serverConf.getValue("interceptor", ""); if (!interceptorClass.isEmpty()) { Class clazz = serverClassLoader.loadClass(interceptorClass); - this.interceptor = (NodeInterceptor) clazz.newInstance(); + this.interceptor = (NodeInterceptor) clazz.getDeclaredConstructor().newInstance(); } ClassFilter serviceFilter = createServiceClassFilter(); diff --git a/src/org/redkale/boot/NodeSncpServer.java b/src/org/redkale/boot/NodeSncpServer.java index ad972d99f..b11a9817c 100644 --- a/src/org/redkale/boot/NodeSncpServer.java +++ b/src/org/redkale/boot/NodeSncpServer.java @@ -93,7 +93,7 @@ public class NodeSncpServer extends NodeServer { for (FilterEntry en : list) { Class clazz = (Class) en.getType(); if (Modifier.isAbstract(clazz.getModifiers())) continue; - final SncpFilter filter = clazz.newInstance(); + final SncpFilter filter = clazz.getDeclaredConstructor().newInstance(); resourceFactory.inject(filter, this); DefaultAnyValue filterConf = (DefaultAnyValue) en.getProperty(); this.sncpServer.addSncpFilter(filter, filterConf); diff --git a/src/org/redkale/net/http/HttpPrepareServlet.java b/src/org/redkale/net/http/HttpPrepareServlet.java index e3a64b38b..a5909d1d0 100644 --- a/src/org/redkale/net/http/HttpPrepareServlet.java +++ b/src/org/redkale/net/http/HttpPrepareServlet.java @@ -225,7 +225,7 @@ public class HttpPrepareServlet extends PrepareServlet } }.loadClass(newDynName.replace('/', '.'), bytes); try { - HttpServlet instance = (HttpServlet) newClazz.newInstance(); + HttpServlet instance = (HttpServlet) newClazz.getDeclaredConstructor().newInstance(); instance.getClass().getField(factfield).set(instance, this); return instance; } catch (Exception ex) { diff --git a/src/org/redkale/net/http/Rest.java b/src/org/redkale/net/http/Rest.java index 2317ac38a..69903f008 100644 --- a/src/org/redkale/net/http/Rest.java +++ b/src/org/redkale/net/http/Rest.java @@ -637,7 +637,7 @@ public final class Rest { cw.visitEnd(); Class newClazz = newLoader.loadClass(newDynName.replace('/', '.'), cw.toByteArray()); try { - return (T) newClazz.newInstance(); + return (T) newClazz.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new RuntimeException(e); } @@ -1684,7 +1684,7 @@ public final class Rest { cw.visitEnd(); Class newClazz = new RestClassLoader(loader).loadClass(newDynName.replace('/', '.'), cw.toByteArray()); try { - T obj = ((Class) newClazz).newInstance(); + T obj = ((Class) newClazz).getDeclaredConstructor().newInstance(); for (Map.Entry en : restAttributes.entrySet()) { Field attrField = newClazz.getDeclaredField(en.getKey()); attrField.setAccessible(true); diff --git a/src/org/redkale/net/sncp/Sncp.java b/src/org/redkale/net/sncp/Sncp.java index 680651797..6c853a4bf 100644 --- a/src/org/redkale/net/sncp/Sncp.java +++ b/src/org/redkale/net/sncp/Sncp.java @@ -754,7 +754,7 @@ public abstract class Sncp { final AnyValue conf) { try { final Class newClazz = createLocalServiceClass(classLoader, name, serviceImplClass); - T rs = (T) newClazz.newInstance(); + T rs = (T) newClazz.getDeclaredConstructor().newInstance(); //-------------------------------------- Service remoteService = null; { @@ -888,7 +888,7 @@ public abstract class Sncp { String newDynName = supDynName.substring(0, supDynName.lastIndexOf('/') + 1) + REMOTEPREFIX + serviceTypeOrImplClass.getSimpleName(); try { Class newClazz = loader.loadClass(newDynName.replace('/', '.')); - T rs = (T) newClazz.newInstance(); + T rs = (T) newClazz.getDeclaredConstructor().newInstance(); SncpClient client = new SncpClient(name, serviceTypeOrImplClass, rs, transportFactory, true, realed ? createLocalServiceClass(loader, name, serviceTypeOrImplClass) : serviceTypeOrImplClass, clientAddress); client.setRemoteGroups(groups); client.setRemoteGroupTransport(transportFactory.loadRemoteTransport(clientAddress, groups)); @@ -1069,7 +1069,7 @@ public abstract class Sncp { } }.loadClass(newDynName.replace('/', '.'), bytes); try { - T rs = (T) newClazz.newInstance(); + T rs = (T) newClazz.getDeclaredConstructor().newInstance(); SncpClient client = new SncpClient(name, serviceTypeOrImplClass, rs, transportFactory, true, realed ? createLocalServiceClass(loader, name, serviceTypeOrImplClass) : serviceTypeOrImplClass, clientAddress); client.setRemoteGroups(groups); client.setRemoteGroupTransport(transportFactory.loadRemoteTransport(clientAddress, groups)); diff --git a/src/org/redkale/net/sncp/SncpClient.java b/src/org/redkale/net/sncp/SncpClient.java index 74f6614ca..05e8e48d6 100644 --- a/src/org/redkale/net/sncp/SncpClient.java +++ b/src/org/redkale/net/sncp/SncpClient.java @@ -595,7 +595,7 @@ public final class SncpClient { for (Annotation ann : anns[i]) { if (ann.annotationType() == RpcCall.class) { try { - atts[i + 1] = ((RpcCall) ann).value().newInstance(); + atts[i + 1] = ((RpcCall) ann).value().getDeclaredConstructor().newInstance(); hasattr = true; } catch (Exception e) { logger.log(Level.SEVERE, RpcCall.class.getSimpleName() + ".attribute cannot a newInstance for" + method, e); diff --git a/src/org/redkale/net/sncp/SncpDynServlet.java b/src/org/redkale/net/sncp/SncpDynServlet.java index b499795a6..41bcaf1ef 100644 --- a/src/org/redkale/net/sncp/SncpDynServlet.java +++ b/src/org/redkale/net/sncp/SncpDynServlet.java @@ -586,7 +586,7 @@ public final class SncpDynServlet extends SncpServlet { } }.loadClass(newDynName.replace('/', '.'), bytes); try { - SncpServletAction instance = (SncpServletAction) newClazz.newInstance(); + SncpServletAction instance = (SncpServletAction) newClazz.getDeclaredConstructor().newInstance(); instance.method = method; java.lang.reflect.Type[] ptypes = TypeToken.getGenericType(method.getGenericParameterTypes(), serviceClass); java.lang.reflect.Type[] types = new java.lang.reflect.Type[ptypes.length + 1]; @@ -606,7 +606,7 @@ public final class SncpDynServlet extends SncpServlet { for (Annotation ann : anns[i]) { if (ann.annotationType() == RpcCall.class) { try { - atts[i + 1] = ((RpcCall) ann).value().newInstance(); + atts[i + 1] = ((RpcCall) ann).value().getDeclaredConstructor().newInstance(); hasattr = true; } catch (Exception e) { logger.log(Level.SEVERE, RpcCall.class.getSimpleName() + ".attribute cannot a newInstance for" + method, e); diff --git a/src/org/redkale/source/CacheMemorySource.java b/src/org/redkale/source/CacheMemorySource.java index b72eee6d8..86d75fc04 100644 --- a/src/org/redkale/source/CacheMemorySource.java +++ b/src/org/redkale/source/CacheMemorySource.java @@ -104,7 +104,7 @@ public class CacheMemorySource extends AbstractService impleme String expireHandlerClass = prop == null ? null : prop.getValue("expirehandler"); if (expireHandlerClass != null) { try { - this.expireHandler = (Consumer) Thread.currentThread().getContextClassLoader().loadClass(expireHandlerClass).newInstance(); + this.expireHandler = (Consumer) Thread.currentThread().getContextClassLoader().loadClass(expireHandlerClass).getDeclaredConstructor().newInstance(); } catch (Throwable e) { logger.log(Level.SEVERE, self.getClass().getSimpleName() + " new expirehandler class (" + expireHandlerClass + ") instance error", e); } diff --git a/src/org/redkale/source/EntityInfo.java b/src/org/redkale/source/EntityInfo.java index 40025525b..33cdbfb36 100644 --- a/src/org/redkale/source/EntityInfo.java +++ b/src/org/redkale/source/EntityInfo.java @@ -191,7 +191,7 @@ public final class EntityInfo { this.table = null; BiFunction loader = null; try { - loader = type.getAnnotation(VirtualEntity.class).loader().newInstance(); + loader = type.getAnnotation(VirtualEntity.class).loader().getDeclaredConstructor().newInstance(); } catch (Exception e) { logger.log(Level.SEVERE, type + " init @VirtualEntity.loader error", e); } @@ -204,7 +204,7 @@ public final class EntityInfo { DistributeTable dt = type.getAnnotation(DistributeTable.class); DistributeTableStrategy dts = null; try { - dts = (dt == null) ? null : dt.strategy().newInstance(); + dts = (dt == null) ? null : dt.strategy().getDeclaredConstructor().newInstance(); } catch (Exception e) { logger.log(Level.SEVERE, type + " init DistributeTableStrategy error", e); } diff --git a/src/org/redkale/source/PoolJdbcSource.java b/src/org/redkale/source/PoolJdbcSource.java index 47764591e..ba01ad1a4 100644 --- a/src/org/redkale/source/PoolJdbcSource.java +++ b/src/org/redkale/source/PoolJdbcSource.java @@ -154,7 +154,7 @@ public class PoolJdbcSource { } } final Class clazz = Thread.currentThread().getContextClassLoader().loadClass(source); - Object pdsource = clazz.newInstance(); + Object pdsource = clazz.getDeclaredConstructor().newInstance(); if (source.contains(".postgresql.")) { Class driver = Thread.currentThread().getContextClassLoader().loadClass("org.postgresql.Driver"); Properties properties = (Properties) driver.getMethod("parseURL", String.class, Properties.class).invoke(null, url, new Properties()); diff --git a/src/org/redkale/util/Attribute.java b/src/org/redkale/util/Attribute.java index 004bc5ffc..869d6e198 100644 --- a/src/org/redkale/util/Attribute.java +++ b/src/org/redkale/util/Attribute.java @@ -441,7 +441,7 @@ public interface Attribute { + fieldname.substring(fieldname.indexOf('.') + 1) + "_" + pcolumn.getSimpleName().replace("[]", "Array"); } try { - return (Attribute) loader.loadClass(newDynName.replace('/', '.')).newInstance(); + return (Attribute) loader.loadClass(newDynName.replace('/', '.')).getDeclaredConstructor().newInstance(); } catch (Throwable ex) { } //--------------------------------------------------- @@ -593,7 +593,7 @@ public interface Attribute { } }.loadClass(newDynName.replace('/', '.'), bytes); try { - return creatorClazz.newInstance(); + return creatorClazz.getDeclaredConstructor().newInstance(); } catch (Exception ex) { throw new RuntimeException(ex); } diff --git a/src/org/redkale/util/Creator.java b/src/org/redkale/util/Creator.java index b0cedcf78..c1eefa3b6 100644 --- a/src/org/redkale/util/Creator.java +++ b/src/org/redkale/util/Creator.java @@ -246,7 +246,7 @@ public interface Creator { newDynName = interName + "_Dyn" + Creator.class.getSimpleName(); } try { - return (Creator) loader.loadClass(newDynName.replace('/', '.')).newInstance(); + return (Creator) loader.loadClass(newDynName.replace('/', '.')).getDeclaredConstructor().newInstance(); } catch (Throwable ex) { } @@ -494,7 +494,7 @@ public interface Creator { return defineClass(name, b, 0, b.length); } }.loadClass(newDynName.replace('/', '.'), bytes); - return (Creator) resultClazz.newInstance(); + return (Creator) resultClazz.getDeclaredConstructor().newInstance(); } catch (Exception ex) { throw new RuntimeException(ex); } diff --git a/src/org/redkale/util/RedkaleClassLoader.java b/src/org/redkale/util/RedkaleClassLoader.java index d492a399b..fac16801b 100644 --- a/src/org/redkale/util/RedkaleClassLoader.java +++ b/src/org/redkale/util/RedkaleClassLoader.java @@ -5,7 +5,9 @@ */ package org.redkale.util; +import java.lang.reflect.*; import java.net.*; +import java.nio.file.Paths; import java.util.HashSet; /** @@ -35,6 +37,15 @@ public class RedkaleClassLoader extends URLClassLoader { public URL[] getAllURLs() { ClassLoader loader = this; HashSet set = new HashSet<>(); + String appPath = System.getProperty("java.class.path"); + if (appPath != null && !appPath.isEmpty()) { + for (String path : appPath.replace(":/", "&&").replace(":\\", "##").replace(':', ';').split(";")) { + try { + set.add(Paths.get(path.replace("&&", ":/").replace("##", ":\\")).toRealPath().toFile().toURI().toURL()); + } catch (Exception e) { + } + } + } do { String loaderName = loader.getClass().getName(); if (loaderName.startsWith("sun.") && loaderName.contains("ExtClassLoader")) continue; @@ -42,6 +53,33 @@ public class RedkaleClassLoader extends URLClassLoader { for (URL url : ((URLClassLoader) loader).getURLs()) { set.add(url); } + } else { //可能JDK9及以上 + loader.getResource("org.redkale"); //必须要运行一次,确保URLClassPath的值被填充完毕 + Class loaderClazz = loader.getClass(); + Object ucp = null; + do { //读取 java.base/jdk.internal.loader.BuiltinClassLoader的URLClassPath ucp值 + try { + //需要在命令行里加入: --add-opens java.base/jdk.internal.loader=ALL-UNNAMED + Field field = loaderClazz.getDeclaredField("ucp"); + field.setAccessible(true); + ucp = field.get(loader); + break; + } catch (Throwable e) { + } + } while ((loaderClazz = loaderClazz.getSuperclass()) != Object.class); + if (ucp != null) { //URLClassPath + URL[] urls = null; + try { //读取 java.base/jdk.internal.loader.URLClassPath的urls值 + Method method = ucp.getClass().getMethod("getURLs"); + urls = (URL[]) method.invoke(ucp); + } catch (Exception e) { + } + if (urls != null) { + for (URL url : urls) { + set.add(url); + } + } + } } } while ((loader = loader.getParent()) != null); return set.toArray(new URL[set.size()]); diff --git a/src/org/redkale/util/Reproduce.java b/src/org/redkale/util/Reproduce.java index 4821a10c4..65ae508ae 100644 --- a/src/org/redkale/util/Reproduce.java +++ b/src/org/redkale/util/Reproduce.java @@ -41,7 +41,7 @@ public interface Reproduce extends BiFunction { newDynName = destName + "_Dyn" + Reproduce.class.getSimpleName() + "_" + srcClass.getSimpleName(); } try { - return (Reproduce) loader.loadClass(newDynName.replace('/', '.')).newInstance(); + return (Reproduce) loader.loadClass(newDynName.replace('/', '.')).getDeclaredConstructor().newInstance(); } catch (Throwable ex) { } // ------------------------------------------------------------------------------ @@ -136,7 +136,7 @@ public interface Reproduce extends BiFunction { } }.loadClass(newDynName.replace('/', '.'), bytes); try { - return (Reproduce) creatorClazz.newInstance(); + return (Reproduce) creatorClazz.getDeclaredConstructor().newInstance(); } catch (Exception ex) { throw new RuntimeException(ex); } diff --git a/src/org/redkale/util/Utility.java b/src/org/redkale/util/Utility.java index e7683f944..ccd4f7aef 100644 --- a/src/org/redkale/util/Utility.java +++ b/src/org/redkale/util/Utility.java @@ -35,36 +35,11 @@ public final class Utility { private static final char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - private static final sun.misc.Unsafe UNSAFE; - - private static final long strvaloffset; - - private static final long sbvaloffset; - private static final javax.net.ssl.SSLContext DEFAULTSSL_CONTEXT; private static final javax.net.ssl.HostnameVerifier defaultVerifier = (s, ss) -> true; static { - sun.misc.Unsafe usafe = null; - long fd1 = 0L; - long fd2 = 0L; - try { - Field f = String.class.getDeclaredField("value"); - if (f.getType() == char[].class) { //JDK9及以上不再是char[] - Field safeField = sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); - safeField.setAccessible(true); - usafe = (sun.misc.Unsafe) safeField.get(null); - fd1 = usafe.objectFieldOffset(f); - fd2 = usafe.objectFieldOffset(StringBuilder.class.getSuperclass().getDeclaredField("value")); - } - } catch (Exception e) { - throw new RuntimeException(e); //不可能会发生 - } - UNSAFE = usafe; - strvaloffset = fd1; - sbvaloffset = fd2; - try { DEFAULTSSL_CONTEXT = javax.net.ssl.SSLContext.getInstance("SSL"); DEFAULTSSL_CONTEXT.init(null, new javax.net.ssl.TrustManager[]{new javax.net.ssl.X509TrustManager() { @@ -1048,8 +1023,7 @@ public final class Utility { public static byte[] encodeUTF8(final String value) { if (value == null) return new byte[0]; - if (UNSAFE == null) return encodeUTF8(value.toCharArray()); - return encodeUTF8((char[]) UNSAFE.getObject(value, strvaloffset)); + return encodeUTF8(value.toCharArray()); } public static byte[] encodeUTF8(final char[] array) { @@ -1091,14 +1065,12 @@ public final class Utility { public static char[] charArray(String value) { if (value == null) return null; - if (UNSAFE == null) return value.toCharArray(); - return (char[]) UNSAFE.getObject(value, strvaloffset); + return value.toCharArray(); } public static char[] charArray(StringBuilder value) { if (value == null) return null; - if (UNSAFE == null) return value.toString().toCharArray(); - return (char[]) UNSAFE.getObject(value, sbvaloffset); + return value.toString().toCharArray(); } public static ByteBuffer encodeUTF8(final ByteBuffer buffer, final char[] array) { @@ -1111,8 +1083,7 @@ public final class Utility { public static int encodeUTF8Length(String value) { if (value == null) return -1; - if (UNSAFE == null) return encodeUTF8Length(value.toCharArray()); - return encodeUTF8Length((char[]) UNSAFE.getObject(value, strvaloffset)); + return encodeUTF8Length(value.toCharArray()); } public static int encodeUTF8Length(final char[] text) {