删掉对sun.misc.Unsafe的依赖和替换过期方法Class.newInstance()

This commit is contained in:
Redkale
2018-03-07 11:31:11 +08:00
parent 93698bacff
commit 53df45456f
21 changed files with 74 additions and 68 deletions

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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) {
}

View File

@@ -136,7 +136,7 @@ public class NodeHttpServer extends NodeServer {
for (FilterEntry<? extends Filter> en : list) {
Class<HttpFilter> clazz = (Class<HttpFilter>) 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 : "";

View File

@@ -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<Service> serviceFilter = createServiceClassFilter();

View File

@@ -93,7 +93,7 @@ public class NodeSncpServer extends NodeServer {
for (FilterEntry<? extends Filter> en : list) {
Class<SncpFilter> clazz = (Class<SncpFilter>) 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);

View File

@@ -225,7 +225,7 @@ public class HttpPrepareServlet extends PrepareServlet<String, HttpContext, Http
}
String resServlet = resConfig.getValue("servlet", HttpResourceServlet.class.getName());
try {
this.resourceHttpServlet = (HttpServlet) Thread.currentThread().getContextClassLoader().loadClass(resServlet).newInstance();
this.resourceHttpServlet = (HttpServlet) Thread.currentThread().getContextClassLoader().loadClass(resServlet).getDeclaredConstructor().newInstance();
} catch (Throwable e) {
this.resourceHttpServlet = new HttpResourceServlet();
logger.log(Level.WARNING, "init HttpResourceSerlvet(" + resServlet + ") error", e);
@@ -239,7 +239,7 @@ public class HttpPrepareServlet extends PrepareServlet<String, HttpContext, Http
for (AnyValue renderConfig : renderConfigs) {
String renderType = renderConfig.getValue("value");
try {
HttpRender render = (HttpRender) Thread.currentThread().getContextClassLoader().loadClass(renderType).newInstance();
HttpRender render = (HttpRender) Thread.currentThread().getContextClassLoader().loadClass(renderType).getDeclaredConstructor().newInstance();
for (HttpRender one : renders) {
if (one.getType().equals(render.getType())) throw new RuntimeException("HttpRender(" + renderType + ") repeat");
}

View File

@@ -59,7 +59,8 @@ public class HttpResourceServlet extends HttpServlet {
final String uri = path.toString().substring(rootstr.length()).replace('\\', '/');
//logger.log(Level.FINEST, "file(" + uri + ") happen " + event.kind() + " event");
if (event.kind() == ENTRY_DELETE) {
files.remove(uri);
FileEntry en = files.remove(uri);
if (en != null) en.remove();
} else if (event.kind() == ENTRY_MODIFY) {
FileEntry en = files.get(uri);
if (en != null && en.file != null) {
@@ -317,10 +318,8 @@ public class HttpResourceServlet extends HttpServlet {
}
}
@Override
protected void finalize() throws Throwable {
public void remove() {
if (this.content != null) this.servlet.cachedLength.add(0L - this.content.remaining());
super.finalize();
}
public long getCachedLength() {

View File

@@ -274,7 +274,7 @@ public class HttpServlet extends Servlet<HttpContext, HttpRequest, HttpResponse>
}
}.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) {

View File

@@ -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<T>) newClazz).newInstance();
T obj = ((Class<T>) newClazz).getDeclaredConstructor().newInstance();
for (Map.Entry<String, org.redkale.util.Attribute> en : restAttributes.entrySet()) {
Field attrField = newClazz.getDeclaredField(en.getKey());
attrField.setAccessible(true);

View File

@@ -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));

View File

@@ -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);

View File

@@ -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);

View File

@@ -104,7 +104,7 @@ public class CacheMemorySource<V extends Object> extends AbstractService impleme
String expireHandlerClass = prop == null ? null : prop.getValue("expirehandler");
if (expireHandlerClass != null) {
try {
this.expireHandler = (Consumer<CacheEntry>) Thread.currentThread().getContextClassLoader().loadClass(expireHandlerClass).newInstance();
this.expireHandler = (Consumer<CacheEntry>) Thread.currentThread().getContextClassLoader().loadClass(expireHandlerClass).getDeclaredConstructor().newInstance();
} catch (Throwable e) {
logger.log(Level.SEVERE, self.getClass().getSimpleName() + " new expirehandler class (" + expireHandlerClass + ") instance error", e);
}

View File

@@ -191,7 +191,7 @@ public final class EntityInfo<T> {
this.table = null;
BiFunction<DataSource, Class, List> 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<T> {
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);
}

View File

@@ -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());

View File

@@ -441,7 +441,7 @@ public interface Attribute<T, F> {
+ 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<T, F> {
}
}.loadClass(newDynName.replace('/', '.'), bytes);
try {
return creatorClazz.newInstance();
return creatorClazz.getDeclaredConstructor().newInstance();
} catch (Exception ex) {
throw new RuntimeException(ex);
}

View File

@@ -246,7 +246,7 @@ public interface Creator<T> {
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<T> {
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);
}

View File

@@ -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<URL> 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()]);

View File

@@ -41,7 +41,7 @@ public interface Reproduce<D, S> extends BiFunction<D, S, D> {
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<D, S> extends BiFunction<D, S, D> {
}
}.loadClass(newDynName.replace('/', '.'), bytes);
try {
return (Reproduce) creatorClazz.newInstance();
return (Reproduce) creatorClazz.getDeclaredConstructor().newInstance();
} catch (Exception ex) {
throw new RuntimeException(ex);
}

View File

@@ -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) {