JDK17 Support for Dubbo (#9062)

* Add JDK17 Support for Javaassist

* compact javaassist

* compact javaassist

* opt code

* fix compile

* fix classpath

* add ant

* tmp fix

* fix ut

* change name

* Refactor get class

* remove reflect get stackTrace

* Fix support jdk 17

* Add jdk 17 to ut

* Add jdk 17 to ut

* update mockito version

* update jacoco

* ignore java compile

* add open

* fix ut

* fix ut

* fix jupiter api

* fix pom

* disable zk 3.4

* disable script router in jdk 17

* remove curator5

* fix ut

* fix ut

* fix ut

* fix ut

* fix ut

* fix ut

* fix ut

* fix ut

* fix zk

* remove test scope

* fix ut

* add open

* fix ut

* add curator

* fix pom

* fix pom

* enable debug

* remove add open

* add open profile

* auto activate open

* disable test in zk

* refactor zk dependency

* remove curator test

* add zookeeper dependency

* fix compile

* change zk default wait time

* change zk default wait time

* fix ut

* set throwable message by constructor

* Add unit prepare jdk 17 support

* fix zk dependency

* remove jackson-databind
This commit is contained in:
Albumen Kevin 2021-12-27 13:18:15 +08:00 committed by GitHub
parent f06bbcc02c
commit f33398f857
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
71 changed files with 697 additions and 350 deletions

View File

@ -72,7 +72,7 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-18.04, windows-2019 ]
jdk: [ 8, 11 ]
jdk: [ 8, 11, 17 ]
env:
DISABLE_FILE_SYSTEM_TEST: true
ZOOKEEPER_VERSION: 3.6.3
@ -124,7 +124,7 @@ jobs:
fail-fast: false
matrix:
os: [ ubuntu-18.04, windows-2019 ]
jdk: [ 8, 11 ]
jdk: [ 8, 11, 17 ]
env:
DISABLE_FILE_SYSTEM_TEST: true
steps:

View File

@ -28,12 +28,15 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import java.util.ArrayList;
import java.util.List;
import static org.apache.dubbo.rpc.cluster.Constants.RULE_KEY;
@DisabledForJreRange(min = JRE.JAVA_16)
public class ScriptStateRouterTest {
private URL SCRIPT_URL = URL.valueOf("script://javascript?type=javascript");
@ -66,12 +69,12 @@ public class ScriptStateRouterTest {
@Test
public void testRoutePickInvokers() {
String rule = "var result = new java.util.ArrayList(invokers.size());" +
"for (i=0;i<invokers.size(); i++){ " +
"if (invokers.get(i).isAvailable()) {" +
"result.add(invokers.get(i)) ;" +
"}" +
"} ; " +
"return result;";
"for (i=0;i<invokers.size(); i++){ " +
"if (invokers.get(i).isAvailable()) {" +
"result.add(invokers.get(i)) ;" +
"}" +
"} ; " +
"return result;";
String script = "function route(invokers,invocation,context){" + rule + "} route(invokers,invocation,context)";
StateRouter router = new ScriptStateRouterFactory().getRouter(String.class, getRouteUrl(script));
@ -102,17 +105,17 @@ public class ScriptStateRouterTest {
BitList<Invoker<String>> invokers = new BitList<>(originInvokers);
String script = "function route(invokers, invocation, context){ " +
" var result = new java.util.ArrayList(invokers.size()); " +
" var targetHost = new java.util.ArrayList(); " +
" targetHost.add(\"10.134.108.2\"); " +
" for (var i = 0; i < invokers.length; i++) { " +
" if(targetHost.contains(invokers[i].getUrl().getHost())){ " +
" result.add(invokers[i]); " +
" } " +
" } " +
" return result; " +
"} " +
"route(invokers, invocation, context) ";
" var result = new java.util.ArrayList(invokers.size()); " +
" var targetHost = new java.util.ArrayList(); " +
" targetHost.add(\"10.134.108.2\"); " +
" for (var i = 0; i < invokers.length; i++) { " +
" if(targetHost.contains(invokers[i].getUrl().getHost())){ " +
" result.add(invokers[i]); " +
" } " +
" } " +
" return result; " +
"} " +
"route(invokers, invocation, context) ";
StateRouter router = new ScriptStateRouterFactory().getRouter(String.class, getRouteUrl(script));
List<Invoker<String>> routeResult = router.route(invokers, invokers.get(0).getUrl(), new RpcInvocation(), false).getResult();

View File

@ -94,7 +94,7 @@ public final class ClassGenerator {
if (pool == null) {
pool = new ClassPool(true);
pool.insertClassPath(new LoaderClassPath(loader));
pool.insertClassPath(new LoaderClassPath(ClassGenerator.class.getClassLoader()));
pool.insertClassPath(new DubboLoaderClassPath());
POOL_MAP.put(loader, pool);
}
return pool;
@ -284,12 +284,17 @@ public final class ClassGenerator {
return mPool;
}
public Class<?> toClass() {
return toClass(mClassLoader,
getClass().getProtectionDomain());
/**
* @param neighbor A class belonging to the same package that this
* class belongs to. It is used to load the class.
*/
public Class<?> toClass(Class<?> neighbor) {
return toClass(neighbor,
mClassLoader,
getClass().getProtectionDomain());
}
public Class<?> toClass(ClassLoader loader, ProtectionDomain pd) {
public Class<?> toClass(Class<?> neighborClass, ClassLoader loader, ProtectionDomain pd) {
if (mCtc != null) {
mCtc.detach();
}
@ -340,7 +345,15 @@ public final class ClassGenerator {
}
}
}
return mCtc.toClass(loader, pd);
try {
return mPool.toClass(mCtc, neighborClass, loader, pd);
} catch (Throwable t) {
if (!(t instanceof CannotCompileException)) {
return mPool.toClass(mCtc, loader, pd);
}
throw t;
}
} catch (RuntimeException e) {
throw e;
} catch (NotFoundException | CannotCompileException e) {

View File

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.bytecode;
import javassist.LoaderClassPath;
import javassist.NotFoundException;
import java.io.InputStream;
import java.net.URL;
/**
* Ensure javassist will load Dubbo's class from Dubbo's classLoader
*/
public class DubboLoaderClassPath extends LoaderClassPath {
public DubboLoaderClassPath() {
super(DubboLoaderClassPath.class.getClassLoader());
}
@Override
public InputStream openClassfile(String classname) throws NotFoundException {
if (!classname.startsWith("org.apache.dubbo")) {
return null;
}
return super.openClassfile(classname);
}
@Override
public URL find(String classname) {
if (!classname.startsWith("org.apache.dubbo")) {
return null;
}
return super.find(classname);
}
}

View File

@ -113,6 +113,7 @@ public abstract class Mixin {
}
ccp.addConstructor(Modifier.PUBLIC, new Class<?>[]{Object[].class}, code.toString());
Class<?> neighbor = null;
// impl methods.
Set<String> worked = new HashSet<String>();
for (int i = 0; i < ics.length; i++) {
@ -120,6 +121,7 @@ public abstract class Mixin {
String npkg = ics[i].getPackage().getName();
if (pkg == null) {
pkg = npkg;
neighbor = ics[i];
} else {
if (!pkg.equals(npkg)) {
throw new IllegalArgumentException("non-public delegate class from different packages");
@ -159,12 +161,13 @@ public abstract class Mixin {
if (pkg == null) {
pkg = PACKAGE_NAME;
neighbor = Mixin.class;
}
// create MixinInstance class.
String micn = pkg + ".mixin" + id;
ccp.setClassName(micn);
ccp.toClass();
ccp.toClass(neighbor);
// create Mixin class.
String fcn = Mixin.class.getName() + id;
@ -173,7 +176,7 @@ public abstract class Mixin {
ccm.addDefaultConstructor();
ccm.setSuperClass(Mixin.class.getName());
ccm.addMethod("public Object newInstance(Object[] delegates){ return new " + micn + "($1); }");
Class<?> mixin = ccm.toClass();
Class<?> mixin = ccm.toClass(Mixin.class);
return (Mixin) mixin.getDeclaredConstructor().newInstance();
} catch (RuntimeException e) {
throw e;

View File

@ -18,19 +18,18 @@ package org.apache.dubbo.common.bytecode;
import org.apache.dubbo.common.utils.ReflectUtils;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.security.ProtectionDomain;
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.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import static org.apache.dubbo.common.constants.CommonConstants.MAX_PROXY_COUNT;
@ -39,29 +38,26 @@ import static org.apache.dubbo.common.constants.CommonConstants.MAX_PROXY_COUNT;
* Proxy.
*/
public abstract class Proxy {
public static final InvocationHandler RETURN_NULL_INVOKER = (proxy, method, args) -> null;
public class Proxy {
public static final InvocationHandler THROW_UNSUPPORTED_INVOKER = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) {
throw new UnsupportedOperationException("Method [" + ReflectUtils.getName(method) + "] unimplemented.");
}
};
private static final AtomicLong PROXY_CLASS_COUNTER = new AtomicLong(0);
private static final String PACKAGE_NAME = Proxy.class.getPackage().getName();
private static final Map<ClassLoader, Map<String, Object>> PROXY_CACHE_MAP = new WeakHashMap<ClassLoader, Map<String, Object>>();
// cache class, avoid PermGen OOM.
private static final Map<ClassLoader, Map<String, Object>> PROXY_CLASS_MAP = new WeakHashMap<ClassLoader, Map<String, Object>>();
private static final Map<ClassLoader, Map<String, Proxy>> PROXY_CACHE_MAP = new WeakHashMap<>();
private static final Object PENDING_GENERATION_MARKER = new Object();
private final Class<?> classToCreate;
protected Proxy() {
protected Proxy(Class<?> classToCreate) {
this.classToCreate = classToCreate;
}
/**
* Get proxy.
*
* @param cl class loader.
* @param ics interface class array.
* @return Proxy instance.
*/
@ -72,112 +68,76 @@ public abstract class Proxy {
// ClassLoader from App Interface should support load some class from Dubbo
ClassLoader cl = ics[0].getClassLoader();
ClassLoader appClassLoader = ics[0].getClassLoader();
ProtectionDomain domain = ics[0].getProtectionDomain();
// use interface class name list as key.
String key = buildInterfacesKey(cl, ics);
// get cache by class loader.
final Map<String, Proxy> cache;
synchronized (PROXY_CACHE_MAP) {
cache = PROXY_CACHE_MAP.computeIfAbsent(cl, k -> new ConcurrentHashMap<>());
}
Proxy proxy = cache.get(key);
if (proxy == null) {
synchronized (ics[0]) {
proxy = cache.get(key);
if (proxy == null) {
// create Proxy class.
proxy = new Proxy(buildProxyClass(cl, ics, domain));
cache.put(key, proxy);
}
}
}
return proxy;
}
private static String buildInterfacesKey(ClassLoader cl, Class<?>[] ics) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ics.length; i++) {
String itf = ics[i].getName();
if (!ics[i].isInterface()) {
for (Class<?> ic : ics) {
String itf = ic.getName();
if (!ic.isInterface()) {
throw new RuntimeException(itf + " is not a interface.");
}
Class<?> tmp = null;
try {
tmp = Class.forName(itf, false, cl);
} catch (ClassNotFoundException e) {
} catch (ClassNotFoundException ignore) {
}
if (tmp != ics[i]) {
throw new IllegalArgumentException(ics[i] + " is not visible from class loader");
if (tmp != ic) {
throw new IllegalArgumentException(ic + " is not visible from class loader");
}
sb.append(itf).append(';');
}
return sb.toString();
}
// use interface class name list as key.
String key = sb.toString();
// get cache by class loader.
final Map<String, Object> cache;
// cache class
final Map<String, Object> classCache;
synchronized (PROXY_CACHE_MAP) {
cache = PROXY_CACHE_MAP.computeIfAbsent(cl, k -> new HashMap<>());
classCache = PROXY_CLASS_MAP.computeIfAbsent(cl, k -> new HashMap<>());
}
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;
}
}
// get Class by key.
Object clazzObj = classCache.get(key);
if (null == clazzObj || clazzObj instanceof Reference<?>) {
Class<?> clazz = null;
if (clazzObj instanceof Reference<?>) {
clazz = (Class<?>) ((Reference<?>) clazzObj).get();
}
if (null == clazz) {
if (value == PENDING_GENERATION_MARKER) {
try {
cache.wait();
} catch (InterruptedException e) {
}
} else {
cache.put(key, PENDING_GENERATION_MARKER);
break;
}
} else {
try {
proxy = (Proxy) clazz.newInstance();
return proxy;
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
} finally {
if (null == proxy) {
cache.remove(key);
} else {
cache.put(key, new SoftReference<>(proxy));
}
}
}
}
}
while (true);
}
long id = PROXY_CLASS_COUNTER.getAndIncrement();
String pkg = null;
ClassGenerator ccp = null, ccm = null;
private static Class<?> buildProxyClass(ClassLoader cl, Class<?>[] ics, ProtectionDomain domain) {
ClassGenerator ccp = null;
try {
ccp = ClassGenerator.newInstance(cl);
Set<String> worked = new HashSet<>();
List<Method> methods = new ArrayList<>();
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");
}
String pkg = ics[0].getPackage().getName();
Class<?> neighbor = ics[0];
for (Class<?> ic : ics) {
String npkg = ic.getPackage().getName();
if (!Modifier.isPublic(ic.getModifiers())) {
if (!pkg.equals(npkg)) {
throw new IllegalArgumentException("non-public interfaces from different packages");
}
}
ccp.addInterface(ics[i]);
for (Method method : ics[i].getMethods()) {
ccp.addInterface(ic);
for (Method method : ic.getMethods()) {
String desc = ReflectUtils.getDesc(method);
if (worked.contains(desc) || Modifier.isStatic(method.getModifiers())) {
continue;
@ -202,33 +162,16 @@ public abstract class Proxy {
}
}
if (pkg == null) {
pkg = PACKAGE_NAME;
}
// create ProxyInstance class.
String pcn = pkg + ".proxy" + id;
String pcn = neighbor.getName() + "DubboProxy" + PROXY_CLASS_COUNTER.getAndIncrement();
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;");
ccp.addConstructor(Modifier.PUBLIC, new Class<?>[]{InvocationHandler.class}, new Class<?>[0], "handler=$1;");
ccp.addDefaultConstructor();
Class<?> clazz = ccp.toClass(appClassLoader, domain);
Class<?> clazz = ccp.toClass(neighbor, cl, domain);
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(appClassLoader, domain);
proxy = (Proxy) pc.newInstance();
synchronized (classCache) {
classCache.put(key, new SoftReference<Class<?>>(pc));
}
return clazz;
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
@ -238,19 +181,7 @@ public abstract class Proxy {
if (ccp != null) {
ccp.release();
}
if (ccm != null) {
ccm.release();
}
synchronized (cache) {
if (proxy == null) {
cache.remove(key);
} else {
cache.put(key, new SoftReference<Proxy>(proxy));
}
cache.notifyAll();
}
}
return proxy;
}
private static String asArgument(Class<?> cl, String name) {
@ -298,5 +229,17 @@ public abstract class Proxy {
*
* @return instance.
*/
abstract public Object newInstance(InvocationHandler handler);
public Object newInstance(InvocationHandler handler) {
Constructor<?> constructor;
try {
constructor = classToCreate.getDeclaredConstructor(InvocationHandler.class);
return constructor.newInstance(handler);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
public Class<?> getClassToCreate() {
return classToCreate;
}
}

View File

@ -151,14 +151,14 @@ public abstract class Wrapper {
continue;
}
c1.append(" if( $2.equals(\"").append(fn).append("\") ){ ((" + f.getDeclaringClass().getName() + ")w).").append(fn).append('=').append(arg(ft, "$3")).append("; return; }");
c2.append(" if( $2.equals(\"").append(fn).append("\") ){ return ($w)((" + f.getDeclaringClass().getName() + ")w).").append(fn).append("; }");
c1.append(" if( $2.equals(\"").append(fn).append("\") ){ ((").append(f.getDeclaringClass().getName()).append(")w).").append(fn).append('=').append(arg(ft, "$3")).append("; return; }");
c2.append(" if( $2.equals(\"").append(fn).append("\") ){ return ($w)((").append(f.getDeclaringClass().getName()).append(")w).").append(fn).append("; }");
pts.put(fn, ft);
}
final ClassPool classPool = new ClassPool(ClassPool.getDefault());
classPool.insertClassPath(new LoaderClassPath(cl));
classPool.insertClassPath(new LoaderClassPath(ClassGenerator.class.getClassLoader()));
classPool.insertClassPath(new DubboLoaderClassPath());
List<String> allMethod = new ArrayList<>();
try {
@ -226,7 +226,7 @@ public abstract class Wrapper {
c3.append(" }");
}
c3.append(" throw new " + NoSuchMethodException.class.getName() + "(\"Not found method \\\"\"+$2+\"\\\" in class " + c.getName() + ".\"); }");
c3.append(" throw new ").append(NoSuchMethodException.class.getName()).append("(\"Not found method \\\"\"+$2+\"\\\" in class ").append(c.getName()).append(".\"); }");
// deal with get/set method.
Matcher matcher;
@ -248,13 +248,13 @@ public abstract class Wrapper {
pts.put(pn, pt);
}
}
c1.append(" throw new " + NoSuchPropertyException.class.getName() + "(\"Not found property \\\"\"+$2+\"\\\" field or setter method in class " + c.getName() + ".\"); }");
c2.append(" throw new " + NoSuchPropertyException.class.getName() + "(\"Not found property \\\"\"+$2+\"\\\" field or getter method in class " + c.getName() + ".\"); }");
c1.append(" throw new ").append(NoSuchPropertyException.class.getName()).append("(\"Not found property \\\"\"+$2+\"\\\" field or setter method in class ").append(c.getName()).append(".\"); }");
c2.append(" throw new ").append(NoSuchPropertyException.class.getName()).append("(\"Not found property \\\"\"+$2+\"\\\" field or getter method in class ").append(c.getName()).append(".\"); }");
// make class
long id = WRAPPER_CLASS_COUNTER.getAndIncrement();
ClassGenerator cc = ClassGenerator.newInstance(cl);
cc.setClassName((Modifier.isPublic(c.getModifiers()) ? Wrapper.class.getName() : c.getName() + "$sw") + id);
cc.setClassName(c.getName() + "DubboWrap" + id);
cc.setSuperClass(Wrapper.class);
cc.addDefaultConstructor();
@ -276,7 +276,7 @@ public abstract class Wrapper {
cc.addMethod(c3.toString());
try {
Class<?> wc = cc.toClass();
Class<?> wc = cc.toClass(c);
// setup static field.
wc.getField("pts").set(null, pts);
wc.getField("pns").set(null, pts.keySet().toArray(new String[0]));

View File

@ -31,7 +31,24 @@ public interface Compiler {
* @param code Java source code
* @param classLoader classloader
* @return Compiled class
* @deprecated use {@link Compiler#compile(Class, String, ClassLoader)} to support JDK 16
*/
Class<?> compile(String code, ClassLoader classLoader);
@Deprecated
default Class<?> compile(String code, ClassLoader classLoader) {
return compile(null, code, classLoader);
}
/**
* Compile java source code.
*
* @param neighbor A class belonging to the same package that this
* class belongs to. It is used to load the class. (For JDK 16 and above)
* @param code Java source code
* @param classLoader classloader
* @return Compiled class
*/
default Class<?> compile(Class<?> neighbor, String code, ClassLoader classLoader) {
return compile(code, classLoader);
}
}

View File

@ -37,7 +37,7 @@ public abstract class AbstractCompiler implements Compiler {
private static final Map<String, Lock> CLASS_IN_CREATION_MAP = new ConcurrentHashMap<>();
@Override
public Class<?> compile(String code, ClassLoader classLoader) {
public Class<?> compile(Class<?> neighbor, String code, ClassLoader classLoader) {
code = code.trim();
Matcher matcher = PACKAGE_PATTERN.matcher(code);
String pkg;
@ -67,7 +67,7 @@ public abstract class AbstractCompiler implements Compiler {
throw new IllegalStateException("The java code not endsWith \"}\", code: \n" + code + "\n");
}
try {
return doCompile(classLoader, className, code);
return doCompile(neighbor, classLoader, className, code);
} catch (RuntimeException t) {
throw t;
} catch (Throwable t) {
@ -78,6 +78,6 @@ public abstract class AbstractCompiler implements Compiler {
}
}
protected abstract Class<?> doCompile(ClassLoader classLoader, String name, String source) throws Throwable;
protected abstract Class<?> doCompile(Class<?> neighbor,ClassLoader classLoader, String name, String source) throws Throwable;
}

View File

@ -41,7 +41,7 @@ public class AdaptiveCompiler implements Compiler, ScopeModelAware {
}
@Override
public Class<?> compile(String code, ClassLoader classLoader) {
public Class<?> compile(Class<?> neighbor, String code, ClassLoader classLoader) {
Compiler compiler;
ExtensionLoader<Compiler> loader = frameworkModel.getExtensionLoader(Compiler.class);
String name = DEFAULT_COMPILER; // copy reference
@ -50,7 +50,7 @@ public class AdaptiveCompiler implements Compiler, ScopeModelAware {
} else {
compiler = loader.getDefaultExtension();
}
return compiler.compile(code, classLoader);
return compiler.compile(neighbor, code, classLoader);
}
}

View File

@ -16,6 +16,8 @@
*/
package org.apache.dubbo.common.compiler.support;
import org.apache.dubbo.common.bytecode.DubboLoaderClassPath;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
@ -141,6 +143,7 @@ public class CtClassBuilder {
public CtClass build(ClassLoader classLoader) throws NotFoundException, CannotCompileException {
ClassPool pool = new ClassPool(true);
pool.insertClassPath(new LoaderClassPath(classLoader));
pool.insertClassPath(new DubboLoaderClassPath());
// create class
CtClass ctClass = pool.makeClass(className, pool.get(superClassName));

View File

@ -16,8 +16,12 @@
*/
package org.apache.dubbo.common.compiler.support;
import org.apache.dubbo.common.bytecode.DubboLoaderClassPath;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.LoaderClassPath;
import java.util.Arrays;
import java.util.regex.Matcher;
@ -39,7 +43,7 @@ public class JavassistCompiler extends AbstractCompiler {
private static final Pattern FIELD_PATTERN = Pattern.compile("[^\n]+=[^\n]+;");
@Override
public Class<?> doCompile(ClassLoader classLoader, String name, String source) throws Throwable {
public Class<?> doCompile(Class<?> neighbor, ClassLoader classLoader, String name, String source) throws Throwable {
CtClassBuilder builder = new CtClassBuilder();
builder.setClassName(name);
@ -78,7 +82,22 @@ public class JavassistCompiler extends AbstractCompiler {
// compile
CtClass cls = builder.build(classLoader);
return cls.toClass(classLoader, JavassistCompiler.class.getProtectionDomain());
ClassPool cp = cls.getClassPool();
if (classLoader == null) {
classLoader = cp.getClassLoader();
}
cp.insertClassPath(new LoaderClassPath(classLoader));
cp.insertClassPath(new DubboLoaderClassPath());
try {
return cp.toClass(cls, neighbor, classLoader, JavassistCompiler.class.getProtectionDomain());
} catch (Throwable t) {
if (!(t instanceof CannotCompileException)) {
return cp.toClass(cls, classLoader, JavassistCompiler.class.getProtectionDomain());
}
throw t;
}
}
}

View File

@ -110,7 +110,7 @@ public class JdkCompiler extends AbstractCompiler {
}
@Override
public Class<?> doCompile(ClassLoader ignored, String name, String sourceCode) throws Throwable {
public Class<?> doCompile(Class<?> neighbor, ClassLoader ignored, String name, String sourceCode) throws Throwable {
int i = name.lastIndexOf('.');
String packageName = i < 0 ? "" : name.substring(0, i);
String className = i < 0 ? name : name.substring(i + 1);

View File

@ -1244,7 +1244,7 @@ public class ExtensionLoader<T> {
String code = new AdaptiveClassCodeGenerator(type, cachedDefaultName).generate();
org.apache.dubbo.common.compiler.Compiler compiler = extensionDirector.getExtensionLoader(
org.apache.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
return compiler.compile(code, classLoader);
return compiler.compile(type, code, classLoader);
}
private Environment getEnvironment() {

View File

@ -26,7 +26,6 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
@ -38,6 +37,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
@ -478,7 +478,18 @@ public class PojoUtils {
history.put(pojo, dest);
return dest;
} else {
Object dest = newInstance(type);
Object dest;
if (Throwable.class.isAssignableFrom(type)) {
Object message = map.get("message");
if (message instanceof String) {
dest = newThrowableInstance(type, (String) message);
} else {
dest = newInstance(type);
}
} else {
dest = newInstance(type);
}
history.put(pojo, dest);
for (Map.Entry<Object, Object> entry : map.entrySet()) {
Object key = entry.getKey();
@ -513,19 +524,6 @@ public class PojoUtils {
}
}
}
if (dest instanceof Throwable) {
Object message = map.get("message");
if (message instanceof String) {
try {
Field field = Throwable.class.getDeclaredField("detailMessage");
if (!field.isAccessible()) {
field.setAccessible(true);
}
field.set(dest, message);
} catch (Exception e) {
}
}
}
return dest;
}
}
@ -572,39 +570,42 @@ public class PojoUtils {
return clazz;
}
private static Object newThrowableInstance(Class<?> cls, String message) {
try {
Constructor<?> messagedConstructor = cls.getDeclaredConstructor(String.class);
return messagedConstructor.newInstance(message);
} catch (Throwable t) {
return newInstance(cls);
}
}
private static Object newInstance(Class<?> cls) {
try {
return cls.newInstance();
} catch (Throwable t) {
try {
Constructor<?>[] constructors = cls.getDeclaredConstructors();
/**
* From Javadoc java.lang.Class#getDeclaredConstructors
* This method returns an array of Constructor objects reflecting all the constructors
* declared by the class represented by this Class object.
* This method returns an array of length 0,
* if this Class object represents an interface, a primitive type, an array class, or void.
*/
if (constructors.length == 0) {
throw new RuntimeException("Illegal constructor: " + cls.getName());
}
Constructor<?> constructor = constructors[0];
if (constructor.getParameterTypes().length > 0) {
for (Constructor<?> c : constructors) {
if (c.getParameterTypes().length < constructor.getParameterTypes().length) {
constructor = c;
if (constructor.getParameterTypes().length == 0) {
break;
}
}
}
}
constructor.setAccessible(true);
Object[] parameters = Arrays.stream(constructor.getParameterTypes()).map(PojoUtils::getDefaultValue).toArray();
return constructor.newInstance(parameters);
} catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e.getMessage(), e);
Constructor<?>[] constructors = cls.getDeclaredConstructors();
/*
From Javadoc java.lang.Class#getDeclaredConstructors
This method returns an array of Constructor objects reflecting all the constructors
declared by the class represented by this Class object.
This method returns an array of length 0,
if this Class object represents an interface, a primitive type, an array class, or void.
*/
if (constructors.length == 0) {
throw new RuntimeException("Illegal constructor: " + cls.getName());
}
Throwable lastError = null;
Arrays.sort(constructors, Comparator.comparingInt(a -> a.getParameterTypes().length));
for (Constructor<?> constructor : constructors) {
try {
constructor.setAccessible(true);
Object[] parameters = Arrays.stream(constructor.getParameterTypes()).map(PojoUtils::getDefaultValue).toArray();
return constructor.newInstance(parameters);
} catch (Throwable e) {
lastError = e;
}
}
throw new RuntimeException(lastError.getMessage(), lastError);
}
}

View File

@ -70,7 +70,7 @@ public class ConfigCenterConfig extends AbstractConfig {
private String password;
/**
* The default value is 3000L;
* The default value is 30000L;
*/
private Long timeout;
@ -130,7 +130,7 @@ public class ConfigCenterConfig extends AbstractConfig {
group = CommonConstants.DUBBO;
}
if (timeout == null) {
timeout = 3000L;
timeout = 30000L;
}
// if (highestPriority == null) {
// highestPriority = true;

View File

@ -50,7 +50,7 @@ public class ClassGeneratorTest {
cg.addMethod("public void setName(" + Bean.class.getName() + " o, Object name){ FNAME.set($1, $2); }");
cg.addDefaultConstructor();
Class<?> cl = cg.toClass();
Class<?> cl = cg.toClass(Bean.class);
cl.getField("FNAME").set(null, fname);
System.out.println(cl.getName());
@ -80,7 +80,7 @@ public class ClassGeneratorTest {
cg.addMethod("public void setName(" + Bean.class.getName() + " o, Object name){ FNAME.set($1, $2); }");
cg.addDefaultConstructor();
Class<?> cl = cg.toClass();
Class<?> cl = cg.toClass(Bean.class);
cl.getField("FNAME").set(null, fname);
System.out.println(cl.getName());

View File

@ -34,19 +34,19 @@ public class MixinTest {
((I3) o).m3();
}
interface I1 {
public interface I1 {
void m1();
}
interface I2 {
public interface I2 {
void m2();
}
interface I3 {
public interface I3 {
void m3();
}
class C1 implements Mixin.MixinAware {
public class C1 implements Mixin.MixinAware {
public void m1() {
System.out.println("c1.m1();");
}
@ -60,7 +60,7 @@ public class MixinTest {
}
}
class C2 implements Mixin.MixinAware {
public class C2 implements Mixin.MixinAware {
public void m3() {
System.out.println("c2.m3();");
}

View File

@ -20,10 +20,13 @@ import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
@DisabledForJreRange(min = JRE.JAVA_16)
public class ProxyTest {
@Test

View File

@ -17,6 +17,7 @@
package org.apache.dubbo.common.compiler.support;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@ -27,7 +28,7 @@ public class AdaptiveCompilerTest extends JavaCodeTest {
AdaptiveCompiler.setDefaultCompiler("jdk");
AdaptiveCompiler compiler = new AdaptiveCompiler();
compiler.setFrameworkModel(FrameworkModel.defaultModel());
Class<?> clazz = compiler.compile(getSimpleCode(), AdaptiveCompiler.class.getClassLoader());
Class<?> clazz = compiler.compile(JavaCodeTest.class, getSimpleCode(), AdaptiveCompiler.class.getClassLoader());
HelloService helloService = (HelloService) clazz.newInstance();
Assertions.assertEquals("Hello world!", helloService.sayHello());
}

View File

@ -22,6 +22,15 @@ public class JavaCodeTest {
public final static AtomicInteger SUBFIX = new AtomicInteger(8);
boolean shouldIgnoreWithoutPackage() {
String jdkVersion = System.getProperty("java.specification.version");
try {
return Integer.parseInt(jdkVersion) > 15;
} catch (Throwable t) {
return false;
}
}
String getSimpleCode() {
StringBuilder code = new StringBuilder();
code.append("package org.apache.dubbo.common.compiler.support;");

View File

@ -18,6 +18,8 @@ package org.apache.dubbo.common.compiler.support;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import java.lang.reflect.Method;
@ -25,7 +27,7 @@ public class JavassistCompilerTest extends JavaCodeTest {
@Test
public void testCompileJavaClass() throws Exception {
JavassistCompiler compiler = new JavassistCompiler();
Class<?> clazz = compiler.compile(getSimpleCode(), JavassistCompiler.class.getClassLoader());
Class<?> clazz = compiler.compile(JavaCodeTest.class, getSimpleCode(), JavassistCompiler.class.getClassLoader());
// Because javassist compiles using the caller class loader, we should't use HelloService directly
Object instance = clazz.newInstance();
@ -37,19 +39,26 @@ public class JavassistCompilerTest extends JavaCodeTest {
* javassist compile will find HelloService in classpath
*/
@Test
@DisabledForJreRange(min = JRE.JAVA_16)
public void testCompileJavaClass0() throws Exception {
boolean ignoreWithoutPackage = shouldIgnoreWithoutPackage();
JavassistCompiler compiler = new JavassistCompiler();
Class<?> clazz = compiler.compile(getSimpleCodeWithoutPackage(), JavassistCompiler.class.getClassLoader());
Object instance = clazz.newInstance();
Method sayHello = instance.getClass().getMethod("sayHello");
Assertions.assertEquals("Hello world!", sayHello.invoke(instance));
if (ignoreWithoutPackage) {
Assertions.assertThrows(RuntimeException.class, () -> compiler.compile(null, getSimpleCodeWithoutPackage(), JavassistCompiler.class.getClassLoader()));
} else {
Class<?> clazz = compiler.compile(null, getSimpleCodeWithoutPackage(), JavassistCompiler.class.getClassLoader());
Object instance = clazz.newInstance();
Method sayHello = instance.getClass().getMethod("sayHello");
Assertions.assertEquals("Hello world!", sayHello.invoke(instance));
}
}
@Test
public void testCompileJavaClass1() throws Exception {
Assertions.assertThrows(IllegalStateException.class, () -> {
JavassistCompiler compiler = new JavassistCompiler();
Class<?> clazz = compiler.compile(getSimpleCodeWithSyntax0(), JavassistCompiler.class.getClassLoader());
Class<?> clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithSyntax0(), JavassistCompiler.class.getClassLoader());
Object instance = clazz.newInstance();
Method sayHello = instance.getClass().getMethod("sayHello");
Assertions.assertEquals("Hello world!", sayHello.invoke(instance));
@ -59,7 +68,7 @@ public class JavassistCompilerTest extends JavaCodeTest {
@Test
public void testCompileJavaClassWithImport() throws Exception {
JavassistCompiler compiler = new JavassistCompiler();
Class<?> clazz = compiler.compile(getSimpleCodeWithImports(), JavassistCompiler.class.getClassLoader());
Class<?> clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithImports(), JavassistCompiler.class.getClassLoader());
Object instance = clazz.newInstance();
Method sayHello = instance.getClass().getMethod("sayHello");
Assertions.assertEquals("Hello world!", sayHello.invoke(instance));
@ -68,7 +77,7 @@ public class JavassistCompilerTest extends JavaCodeTest {
@Test
public void testCompileJavaClassWithExtends() throws Exception {
JavassistCompiler compiler = new JavassistCompiler();
Class<?> clazz = compiler.compile(getSimpleCodeWithWithExtends(), JavassistCompiler.class.getClassLoader());
Class<?> clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithWithExtends(), JavassistCompiler.class.getClassLoader());
Object instance = clazz.newInstance();
Method sayHello = instance.getClass().getMethod("sayHello");
Assertions.assertEquals("Hello world3!", sayHello.invoke(instance));

View File

@ -26,7 +26,7 @@ public class JdkCompilerTest extends JavaCodeTest {
@Test
public void test_compileJavaClass() throws Exception {
JdkCompiler compiler = new JdkCompiler();
Class<?> clazz = compiler.compile(getSimpleCode(), JdkCompiler.class.getClassLoader());
Class<?> clazz = compiler.compile(JavaCodeTest.class, getSimpleCode(), JdkCompiler.class.getClassLoader());
Object instance = clazz.newInstance();
Method sayHello = instance.getClass().getMethod("sayHello");
Assertions.assertEquals("Hello world!", sayHello.invoke(instance));
@ -36,7 +36,7 @@ public class JdkCompilerTest extends JavaCodeTest {
public void test_compileJavaClass0() throws Exception {
Assertions.assertThrows(IllegalStateException.class, () -> {
JdkCompiler compiler = new JdkCompiler();
Class<?> clazz = compiler.compile(getSimpleCodeWithoutPackage(), JdkCompiler.class.getClassLoader());
Class<?> clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithoutPackage(), JdkCompiler.class.getClassLoader());
Object instance = clazz.newInstance();
Method sayHello = instance.getClass().getMethod("sayHello");
Assertions.assertEquals("Hello world!", sayHello.invoke(instance));
@ -47,7 +47,7 @@ public class JdkCompilerTest extends JavaCodeTest {
public void test_compileJavaClass1() throws Exception {
Assertions.assertThrows(IllegalStateException.class, () -> {
JdkCompiler compiler = new JdkCompiler();
Class<?> clazz = compiler.compile(getSimpleCodeWithSyntax(), JdkCompiler.class.getClassLoader());
Class<?> clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithSyntax(), JdkCompiler.class.getClassLoader());
Object instance = clazz.newInstance();
Method sayHello = instance.getClass().getMethod("sayHello");
Assertions.assertEquals("Hello world!", sayHello.invoke(instance));
@ -57,7 +57,7 @@ public class JdkCompilerTest extends JavaCodeTest {
@Test
public void test_compileJavaClass_java8() throws Exception {
JdkCompiler compiler = new JdkCompiler("1.8");
Class<?> clazz = compiler.compile(getSimpleCode(), JdkCompiler.class.getClassLoader());
Class<?> clazz = compiler.compile(JavaCodeTest.class, getSimpleCode(), JdkCompiler.class.getClassLoader());
Object instance = clazz.newInstance();
Method sayHello = instance.getClass().getMethod("sayHello");
Assertions.assertEquals("Hello world!", sayHello.invoke(instance));
@ -67,7 +67,7 @@ public class JdkCompilerTest extends JavaCodeTest {
public void test_compileJavaClass0_java8() throws Exception {
Assertions.assertThrows(IllegalStateException.class, () -> {
JdkCompiler compiler = new JdkCompiler("1.8");
Class<?> clazz = compiler.compile(getSimpleCodeWithoutPackage(), JdkCompiler.class.getClassLoader());
Class<?> clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithoutPackage(), JdkCompiler.class.getClassLoader());
Object instance = clazz.newInstance();
Method sayHello = instance.getClass().getMethod("sayHello");
Assertions.assertEquals("Hello world!", sayHello.invoke(instance));
@ -78,7 +78,7 @@ public class JdkCompilerTest extends JavaCodeTest {
public void test_compileJavaClass1_java8() throws Exception {
Assertions.assertThrows(IllegalStateException.class, () -> {
JdkCompiler compiler = new JdkCompiler("1.8");
Class<?> clazz = compiler.compile(getSimpleCodeWithSyntax(), JdkCompiler.class.getClassLoader());
Class<?> clazz = compiler.compile(JavaCodeTest.class, getSimpleCodeWithSyntax(), JdkCompiler.class.getClassLoader());
Object instance = clazz.newInstance();
Method sayHello = instance.getClass().getMethod("sayHello");
Assertions.assertEquals("Hello world!", sayHello.invoke(instance));

View File

@ -110,6 +110,22 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>

View File

@ -23,6 +23,7 @@ import org.apache.dubbo.config.support.Nested;
import org.apache.dubbo.config.support.Parameter;
import org.apache.dubbo.config.utils.ConfigValidationUtils;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;

View File

@ -22,6 +22,7 @@ import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.test.check.registrycenter.config.ZookeeperRegistryCenterConfig;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@ -67,7 +68,7 @@ public class ConfigCenterConfigTest {
Assertions.assertEquals(ZookeeperRegistryCenterConfig.getConnectionAddress()+"/ConfigCenterConfig?check=true&" +
"config-file=dubbo.properties&group=group&" +
"namespace=namespace&timeout=3000",
"namespace=namespace&timeout=30000",
config.toUrl().toFullString()
);
}

View File

@ -58,6 +58,8 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import org.mockito.Mockito;
import java.io.File;
@ -1017,6 +1019,7 @@ public class ReferenceConfigTest {
}
@Test
@DisabledForJreRange(min = JRE.JAVA_16)
public void testDifferentClassLoaderRequest() throws Exception {
String basePath = DemoService.class.getProtectionDomain().getCodeSource().getLocation().getFile();
basePath = java.net.URLDecoder.decode(basePath, "UTF-8");
@ -1083,6 +1086,7 @@ public class ReferenceConfigTest {
builder.setClassName(MultiClassLoaderServiceRequest.class.getName() + "A");
builder.setSuperClassName(MultiClassLoaderServiceRequest.class.getName());
CtClass cls = builder.build(classLoader);
// FIXME support JDK 17
return cls.toClass(classLoader, JavassistCompiler.class.getProtectionDomain());
}

View File

@ -30,8 +30,6 @@
<spring-boot.version>2.3.1.RELEASE</spring-boot.version>
<!-- Uncomment spring_version property to check Spring 4.x compatibility -->
<!-- <spring_version>4.3.30.RELEASE</spring_version> -->
<curator5_version>5.1.0</curator5_version>
<zookeeper_version>3.6.0</zookeeper_version>
</properties>
<dependencies>
@ -200,19 +198,16 @@
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${curator5_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-x-discovery</artifactId>
<version>${curator5_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper_version}</version>
<scope>test</scope>
</dependency>

View File

@ -23,12 +23,13 @@ import org.apache.dubbo.config.annotation.Method;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.apache.dubbo.config.spring.reference.ReferenceBeanManager;
import org.apache.dubbo.config.spring.api.DemoService;
import org.apache.dubbo.config.spring.api.HelloService;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.apache.dubbo.config.spring.reference.ReferenceBeanManager;
import org.apache.dubbo.config.spring.util.DubboBeanUtils;
import org.apache.dubbo.rpc.RpcContext;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
@ -50,6 +51,7 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@ -147,8 +149,8 @@ public class ReferenceAnnotationBeanPostProcessorTest {
Assertions.assertNotNull(context.getBean("demoService"));
Assertions.assertNotNull(context.getBean("demoServiceFromParent"));
String callSuffix = AOP_SUFFIX + " from "+ NetUtils.getLocalHost() +":12345";
String localCallSuffix = AOP_SUFFIX + " from 127.0.0.1:0";
String callSuffix = AOP_SUFFIX + " from "+ InetSocketAddress.createUnresolved(NetUtils.getLocalHost(), 12345);
String localCallSuffix = AOP_SUFFIX + " from " + InetSocketAddress.createUnresolved("127.0.0.1", 0);
String directInvokeSuffix = AOP_SUFFIX + " from null";
String defaultHelloServiceResult = "Greeting, Mercy";

View File

@ -19,6 +19,7 @@ package org.apache.dubbo.config.spring.propertyconfigurer.consumer;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.spring.api.HelloService;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
@ -30,6 +31,8 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.net.InetSocketAddress;
public class PropertyConfigurerTest {
@BeforeAll
@ -56,7 +59,7 @@ public class PropertyConfigurerTest {
HelloService service = (HelloService) context.getBean("demoService");
String result = service.sayHello("world");
System.out.println("result: " + result);
Assertions.assertEquals("Hello world, response from provider: 127.0.0.1:0", result);
Assertions.assertEquals("Hello world, response from provider: " + InetSocketAddress.createUnresolved("127.0.0.1", 0), result);
context.close();

View File

@ -20,6 +20,7 @@ import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.spring.api.HelloService;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.apache.dubbo.config.spring.propertyconfigurer.consumer.DemoBeanFactoryPostProcessor;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
@ -31,6 +32,8 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.net.InetSocketAddress;
public class PropertySourcesConfigurerTest {
@BeforeAll
@ -58,7 +61,7 @@ public class PropertySourcesConfigurerTest {
HelloService service = (HelloService) context.getBean("demoService");
String result = service.sayHello("world");
System.out.println("result: " + result);
Assertions.assertEquals("Hello world, response from provider: 127.0.0.1:0", result);
Assertions.assertEquals("Hello world, response from provider: " + InetSocketAddress.createUnresolved("127.0.0.1", 0), result);
} finally {
context.close();
}

View File

@ -20,6 +20,7 @@ import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.spring.api.HelloService;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.apache.dubbo.config.spring.propertyconfigurer.consumer.DemoBeanFactoryPostProcessor;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@ -35,6 +36,7 @@ import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;
import java.io.IOException;
import java.net.InetSocketAddress;
public class PropertySourcesInJavaConfigTest {
@ -75,7 +77,7 @@ public class PropertySourcesInJavaConfigTest {
HelloService service = (HelloService) context.getBean("demoService");
String result = service.sayHello("world");
System.out.println("result: " + result);
Assertions.assertEquals("Hello world, response from provider: 127.0.0.1:0", result);
Assertions.assertEquals("Hello world, response from provider: " + InetSocketAddress.createUnresolved("127.0.0.1", 0), result);
} finally {
context.close();
}
@ -103,7 +105,7 @@ public class PropertySourcesInJavaConfigTest {
HelloService service = (HelloService) context.getBean("demoService");
String result = service.sayHello("world");
System.out.println("result: " + result);
Assertions.assertEquals("Hello world, response from provider: 127.0.0.1:0", result);
Assertions.assertEquals("Hello world, response from provider: " + InetSocketAddress.createUnresolved("127.0.0.1", 0), result);
} finally {
context.close();
}

View File

@ -16,7 +16,6 @@
*/
package org.apache.dubbo.config.spring.reference.javaconfig;
import com.sun.management.HotSpotDiagnosticMXBean;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.config.annotation.Reference;
@ -29,10 +28,9 @@ import org.apache.dubbo.config.spring.impl.HelloServiceImpl;
import org.apache.dubbo.config.spring.reference.ReferenceBeanBuilder;
import org.apache.dubbo.rpc.service.GenericException;
import org.apache.dubbo.rpc.service.GenericService;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
@ -41,37 +39,14 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.management.MBeanServer;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.management.ManagementFactory;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class JavaConfigReferenceBeanTest {
public static void dumpHeap(String dirpath, boolean live) throws Exception {
java.lang.management.RuntimeMXBean runtime =
java.lang.management.ManagementFactory.getRuntimeMXBean();
java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
jvm.setAccessible(true);
sun.management.VMManagement mgmt =
(sun.management.VMManagement) jvm.get(runtime);
java.lang.reflect.Method pid_method =
mgmt.getClass().getDeclaredMethod("getProcessId");
pid_method.setAccessible(true);
int pid = (Integer) pid_method.invoke(mgmt);
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
HotSpotDiagnosticMXBean mxBean = ManagementFactory.newPlatformMXBeanProxy(
server, "com.sun.management:type=HotSpotDiagnostic", HotSpotDiagnosticMXBean.class);
String filepath = dirpath + pid + ".hprof";
mxBean.dumpHeap(filepath, live);
System.out.println("Dump heap to file: " + filepath);
}
@BeforeEach
public void setUp() {
DubboBootstrap.reset();

View File

@ -18,6 +18,7 @@ package org.apache.dubbo.config.spring.reference.localcall;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.spring.api.HelloService;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
@ -28,6 +29,8 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.net.InetSocketAddress;
import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD;
@ExtendWith(SpringExtension.class)
@ -58,7 +61,7 @@ public class LocalCallTest {
// see also: org.apache.dubbo.rpc.protocol.injvm.InjvmInvoker.doInvoke
// InjvmInvoker set remote address to 127.0.0.1:0
String result = helloService.sayHello("world");
Assertions.assertEquals("Hello world, response from provider: 127.0.0.1:0", result);
Assertions.assertEquals("Hello world, response from provider: " + InetSocketAddress.createUnresolved("127.0.0.1", 0), result);
// direct call local service, the remote address is null
String originResult = localHelloService.sayHello("world");

View File

@ -19,6 +19,7 @@ package org.apache.dubbo.config.spring.reference.localcall;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.spring.api.HelloService;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
@ -30,6 +31,8 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.net.InetSocketAddress;
import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD;
@ExtendWith(SpringExtension.class)
@ -58,7 +61,7 @@ public class LocalCallTest2 {
// see also: org.apache.dubbo.rpc.protocol.injvm.InjvmInvoker.doInvoke
// InjvmInvoker set remote address to 127.0.0.1:0
String result = helloService.sayHello("world");
Assertions.assertEquals("Hello world, response from provider: 127.0.0.1:0", result);
Assertions.assertEquals("Hello world, response from provider: " + InetSocketAddress.createUnresolved("127.0.0.1", 0), result);
}
}

View File

@ -22,6 +22,7 @@ import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.spring.api.HelloService;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.apache.dubbo.rpc.RpcContext;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
@ -35,6 +36,8 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.net.InetSocketAddress;
import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD;
@EnableDubbo
@ -65,7 +68,7 @@ public class LocalCallReferenceAnnotationTest {
// see also: org.apache.dubbo.rpc.protocol.injvm.InjvmInvoker.doInvoke
// InjvmInvoker set remote address to 127.0.0.1:0
String result = helloService.sayHello("world");
Assertions.assertEquals("Hello world, response from provider: 127.0.0.1:0", result);
Assertions.assertEquals("Hello world, response from provider: " + InetSocketAddress.createUnresolved("127.0.0.1", 0), result);
}
@Configuration

View File

@ -23,6 +23,7 @@ import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.api.HelloService;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.apache.dubbo.rpc.RpcContext;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@ -35,6 +36,7 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.net.InetSocketAddress;
import java.util.Map;
import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD;
@ -65,10 +67,10 @@ public class LocalCallMultipleReferenceAnnotationsTest {
// see also: org.apache.dubbo.rpc.protocol.injvm.InjvmInvoker.doInvoke
// InjvmInvoker set remote address to 127.0.0.1:0
String result = helloService.sayHello("world");
Assertions.assertEquals("Hello world, response from provider: 127.0.0.1:0", result);
Assertions.assertEquals("Hello world, response from provider: " + InetSocketAddress.createUnresolved("127.0.0.1", 0), result);
String demoResult = demoHelloService.sayHello("world");
Assertions.assertEquals("Hello world, response from provider: 127.0.0.1:0", demoResult);
Assertions.assertEquals("Hello world, response from provider: " + InetSocketAddress.createUnresolved("127.0.0.1", 0), demoResult);
Map<String, ReferenceBean> referenceBeanMap = applicationContext.getBeansOfType(ReferenceBean.class);
Assertions.assertEquals(2, referenceBeanMap.size());

View File

@ -22,6 +22,7 @@ import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.spring.api.HelloService;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.apache.dubbo.rpc.RpcContext;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
@ -36,6 +37,8 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.net.InetSocketAddress;
import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD;
@EnableDubbo
@ -67,7 +70,7 @@ public class LocalCallReferenceMixTest {
// see also: org.apache.dubbo.rpc.protocol.injvm.InjvmInvoker.doInvoke
// InjvmInvoker set remote address to 127.0.0.1:0
String result = helloService.sayHello("world");
Assertions.assertEquals("Hello world, response from provider: 127.0.0.1:0", result);
Assertions.assertEquals("Hello world, response from provider: " + InetSocketAddress.createUnresolved("127.0.0.1", 0), result);
}
@Configuration

View File

@ -43,5 +43,26 @@
<artifactId>dubbo-remoting-zookeeper-curator5</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-test-common</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -54,10 +54,10 @@ public class ZookeeperDynamicConfiguration extends TreePathDynamicConfiguration
final String threadName = this.getClass().getSimpleName();
this.executor = new ThreadPoolExecutor(DEFAULT_ZK_EXECUTOR_THREADS_NUM, DEFAULT_ZK_EXECUTOR_THREADS_NUM,
THREAD_KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(DEFAULT_QUEUE),
new NamedThreadFactory(threadName, true),
new AbortPolicyWithReport(threadName, url));
THREAD_KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(DEFAULT_QUEUE),
new NamedThreadFactory(threadName, true),
new AbortPolicyWithReport(threadName, url));
zkClient = zookeeperTransporter.connect(url);
boolean isConnected = zkClient.isConnected();

View File

@ -62,7 +62,7 @@ public class ZookeeperDynamicConfigurationTest {
zookeeperServerPort1 = Integer.parseInt(zookeeperConnectionAddress1.substring(zookeeperConnectionAddress1.lastIndexOf(":") + 1));
client = CuratorFrameworkFactory.newClient("127.0.0.1:" + zookeeperServerPort1, 60 * 1000, 60 * 1000,
new ExponentialBackoffRetry(1000, 3));
new ExponentialBackoffRetry(1000, 3));
client.start();
try {

View File

@ -91,7 +91,7 @@
<!-- Common libs -->
<!-- <spring_version>4.3.30.RELEASE</spring_version> -->
<spring_version>5.2.8.RELEASE</spring_version>
<javassist_version>3.23.1-GA</javassist_version>
<javassist_version>3.28.0-GA</javassist_version>
<netty_version>3.2.5.Final</netty_version>
<netty4_version>4.1.56.Final</netty4_version>
<mina_version>1.1.7</mina_version>
@ -99,8 +99,8 @@
<httpclient_version>4.5.13</httpclient_version>
<httpcore_version>4.4.6</httpcore_version>
<fastjson_version>1.2.70</fastjson_version>
<zookeeper_version>3.4.13</zookeeper_version>
<curator_version>4.2.0</curator_version>
<zookeeper_version>3.7.0</zookeeper_version>
<curator_version>5.1.0</curator_version>
<curator_test_version>2.12.0</curator_test_version>
<jedis_version>3.6.0</jedis_version>
<consul_version>1.4.2</consul_version>

View File

@ -34,6 +34,7 @@
<properties>
<revision>3.0.6-SNAPSHOT</revision>
<maven_flatten_version>1.1.0</maven_flatten_version>
<zookeeper_version>3.7.0</zookeeper_version>
</properties>
<dependencyManagement>
@ -45,6 +46,13 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>parent</artifactId>
<version>${zookeeper_version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
@ -56,6 +64,57 @@
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-annotations</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
</dependency>
<dependency>
<groupId>jline</groupId>
<artifactId>jline</artifactId>
</dependency>
<dependency>
<groupId>io.dropwizard.metrics</groupId>
<artifactId>metrics-core</artifactId>
</dependency>
<dependency>
<groupId>org.xerial.snappy</groupId>
<artifactId>snappy-java</artifactId>
</dependency>
</dependencies>

View File

@ -21,6 +21,7 @@ import org.apache.dubbo.metadata.definition.model.MethodDefinition;
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
import org.apache.dubbo.metadata.definition.service.ComplexObject;
import org.apache.dubbo.metadata.definition.service.DemoService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@ -40,8 +41,9 @@ public class ServiceDefinitionBuilderTest {
void checkComplexObjectAsParam(FullServiceDefinition fullServiceDefinition) {
Assertions.assertEquals(fullServiceDefinition.getAnnotations(),
Arrays.asList("@org.apache.dubbo.metadata.definition.service.annotation.MockTypeAnnotation(value=666)"));
Assertions.assertTrue(fullServiceDefinition.getAnnotations().contains("@org.apache.dubbo.metadata.definition.service.annotation.MockTypeAnnotation(value=666)")
// JDK 17 style
|| fullServiceDefinition.getAnnotations().contains("@org.apache.dubbo.metadata.definition.service.annotation.MockTypeAnnotation(666)"));
List<MethodDefinition> methodDefinitions = fullServiceDefinition.getMethods();
MethodDefinition complexCompute = null;
@ -63,9 +65,13 @@ public class ServiceDefinitionBuilderTest {
String[].class.getCanonicalName(), "java.util.List<java.lang.Integer>", ComplexObject.TestEnum.class.getCanonicalName()}));
Assertions.assertEquals(findComplexObject.getReturnType(), ComplexObject.class.getCanonicalName());
Assertions.assertEquals(testAnnotation.getAnnotations(), Arrays.asList(
Assertions.assertTrue(testAnnotation.getAnnotations().equals(Arrays.asList(
"@org.apache.dubbo.metadata.definition.service.annotation.MockMethodAnnotation(value=777)",
"@org.apache.dubbo.metadata.definition.service.annotation.MockMethodAnnotation2(value=888)"));
"@org.apache.dubbo.metadata.definition.service.annotation.MockMethodAnnotation2(value=888)"))
// JDK 17 style
|| testAnnotation.getAnnotations().equals(Arrays.asList(
"@org.apache.dubbo.metadata.definition.service.annotation.MockMethodAnnotation(777)",
"@org.apache.dubbo.metadata.definition.service.annotation.MockMethodAnnotation2(888)")));
Assertions.assertEquals(testAnnotation.getReturnType(), "void");

View File

@ -382,7 +382,12 @@ public interface TypeUtils {
if (element != null) {
List<? extends TypeParameterElement> typeParameterElements = element.getTypeParameters();
if (!typeParameterElements.isEmpty()) {
List<TypeMirror> typeMirrors = invokeMethod(type, "getTypeArguments");
List<? extends TypeMirror> typeMirrors;
if (type instanceof DeclaredType) {
typeMirrors = ((DeclaredType) type).getTypeArguments();
} else {
typeMirrors = invokeMethod(type, "getTypeArguments");
}
StringBuilder typeBuilder = new StringBuilder(element.toString());
typeBuilder.append('<');
for (int i = 0; i < typeMirrors.size(); i++) {

View File

@ -67,7 +67,8 @@ public class MethodUtilsTest extends AbstractAnnotationProcessingTest {
assertEquals(12, methods.size());
methods = getAllDeclaredMethods(type);
assertEquals(34, methods.size());
// registerNatives() no provided in JDK 17
assertTrue(methods.size() >= 33);
assertTrue(getAllDeclaredMethods((TypeElement) null).isEmpty());
assertTrue(getAllDeclaredMethods((TypeMirror) null).isEmpty());

View File

@ -37,5 +37,26 @@
<artifactId>dubbo-configcenter-zookeeper</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-test-common</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -137,7 +137,7 @@ public class ZookeeperMetadataReportTest {
String protocol = "xxx";
URL url = generateURL(interfaceName, version, group, application);
ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(interfaceName, version,
group, "provider", revision, protocol);
group, "provider", revision, protocol);
zookeeperMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(serviceMetadataIdentifier));
@ -156,7 +156,7 @@ public class ZookeeperMetadataReportTest {
String protocol = "xxx";
URL url = generateURL(interfaceName, version, group, application);
ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(interfaceName, version,
group, "provider", revision, protocol);
group, "provider", revision, protocol);
zookeeperMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(serviceMetadataIdentifier));
@ -179,7 +179,7 @@ public class ZookeeperMetadataReportTest {
String protocol = "xxx";
URL url = generateURL(interfaceName, version, group, application);
ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(interfaceName, version,
group, "provider", revision, protocol);
group, "provider", revision, protocol);
zookeeperMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
List<String> r = zookeeperMetadataReport.doGetExportedURLs(serviceMetadataIdentifier);
@ -236,7 +236,7 @@ public class ZookeeperMetadataReportTest {
private MetadataIdentifier storePrivider(MetadataReport zookeeperMetadataReport, String interfaceName, String version, String group, String application) throws ClassNotFoundException, InterruptedException {
URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName + "?paramTest=zkTest&version=" + version + "&application="
+ application + (group == null ? "" : "&group=" + group));
+ application + (group == null ? "" : "&group=" + group));
MetadataIdentifier providerMetadataIdentifier = new MetadataIdentifier(interfaceName, version, group, PROVIDER_SIDE, application);
Class interfaceClass = Class.forName(interfaceName);
@ -249,7 +249,7 @@ public class ZookeeperMetadataReportTest {
private MetadataIdentifier storeConsumer(MetadataReport zookeeperMetadataReport, String interfaceName, String version, String group, String application) throws ClassNotFoundException, InterruptedException {
URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName + "?version=" + version + "&application="
+ application + (group == null ? "" : "&group=" + group));
+ application + (group == null ? "" : "&group=" + group));
MetadataIdentifier consumerMetadataIdentifier = new MetadataIdentifier(interfaceName, version, group, CONSUMER_SIDE, application);
Class interfaceClass = Class.forName(interfaceName);
@ -272,8 +272,8 @@ public class ZookeeperMetadataReportTest {
private URL generateURL(String interfaceName, String version, String group, String application) {
URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":8989/" + interfaceName +
"?paramTest=etcdTest&version=" + version + "&application="
+ application + (group == null ? "" : "&group=" + group));
"?paramTest=etcdTest&version=" + version + "&application="
+ application + (group == null ? "" : "&group=" + group));
return url;
}

View File

@ -134,7 +134,7 @@ public abstract class CacheableFailbackRegistry extends FailbackRegistry {
Map<String, ServiceAddressURL> newURLs;
URL copyOfConsumer = removeParamsFromConsumer(consumer);
if (oldURLs == null) {
newURLs = new HashMap<>();
newURLs = new HashMap<>((int) (providers.size() / 0.75f + 1));
for (String rawProvider : providers) {
rawProvider = stripOffVariableKeys(rawProvider);
ServiceAddressURL cachedURL = createURL(rawProvider, copyOfConsumer, getExtraParameters());
@ -145,7 +145,7 @@ public abstract class CacheableFailbackRegistry extends FailbackRegistry {
newURLs.put(rawProvider, cachedURL);
}
} else {
newURLs = new HashMap<>((int) (oldURLs.size() / .75 + 1));
newURLs = new HashMap<>((int) (providers.size() / 0.75f + 1));
// maybe only default , or "env" + default
for (String rawProvider : providers) {
rawProvider = stripOffVariableKeys(rawProvider);

View File

@ -55,19 +55,19 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.4.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>3.4.6</version>
<version>${mockito_version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
</project>

View File

@ -46,5 +46,26 @@
<artifactId>commons-lang3</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-test-common</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -95,10 +95,10 @@ public class MultipleRegistry2S2RTest {
Assertions.assertNotNull(MultipleRegistryTestUtil.getZookeeperRegistry(multipleRegistry.getReferenceRegistries().values()));
Assertions.assertEquals(MultipleRegistryTestUtil.getZookeeperRegistry(multipleRegistry.getServiceRegistries().values()),
MultipleRegistryTestUtil.getZookeeperRegistry(multipleRegistry.getReferenceRegistries().values()));
MultipleRegistryTestUtil.getZookeeperRegistry(multipleRegistry.getReferenceRegistries().values()));
Assertions.assertEquals(MultipleRegistryTestUtil.getZookeeperRegistry(multipleRegistry.getServiceRegistries().values()),
MultipleRegistryTestUtil.getZookeeperRegistry(multipleRegistry.getReferenceRegistries().values()));
MultipleRegistryTestUtil.getZookeeperRegistry(multipleRegistry.getReferenceRegistries().values()));
Assertions.assertEquals(multipleRegistry.getApplicationName(), "vic");

View File

@ -18,9 +18,13 @@ package org.apache.dubbo.registry.zookeeper;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.registry.client.ServiceDiscovery;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
@DisabledForJreRange(min = JRE.JAVA_16)
public class ZookeeperServiceDiscoveryFactoryTest {
@Test

View File

@ -30,6 +30,8 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import org.mockito.internal.util.collections.Sets;
import java.util.HashMap;
@ -49,6 +51,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
*
* @since 2.7.5
*/
@DisabledForJreRange(min = JRE.JAVA_16)
public class ZookeeperServiceDiscoveryTest {
private static final String SERVICE_NAME = "A";

View File

@ -33,7 +33,8 @@ public abstract class AbstractZookeeperClient<TargetDataListener, TargetChildLis
protected static final Logger logger = LoggerFactory.getLogger(AbstractZookeeperClient.class);
protected int DEFAULT_CONNECTION_TIMEOUT_MS = 5 * 1000;
// may hang up to wait name resolution up to 10s
protected int DEFAULT_CONNECTION_TIMEOUT_MS = 30 * 1000;
protected int DEFAULT_SESSION_TIMEOUT_MS = 60 * 1000;
private final URL url;

View File

@ -29,8 +29,6 @@
<description>The zookeeper curator5 remoting module of dubbo project</description>
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
<curator5_version>5.1.0</curator5_version>
<zookeeper_version>3.6.0</zookeeper_version>
</properties>
<dependencies>
@ -47,17 +45,14 @@
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator5_version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${curator5_version}</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper_version}</version>
</dependency>
</dependencies>
</project>

View File

@ -28,6 +28,8 @@
<description>The zookeeper remoting module of dubbo project</description>
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
<zookeeper_version>3.4.13</zookeeper_version>
<curator_version>4.2.0</curator_version>
</properties>
<dependencies>
<dependency>
@ -43,10 +45,22 @@
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>${curator_version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>${curator_version}</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-x-discovery</artifactId>
<version>${curator_version}</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>${zookeeper_version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>

View File

@ -25,20 +25,25 @@ import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.WatchedEvent;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.Mockito.mock;
@DisabledForJreRange(min = JRE.JAVA_16)
public class CuratorZookeeperClientTest {
private CuratorZookeeperClient curatorClient;
CuratorFramework client = null;

View File

@ -21,11 +21,14 @@ import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.core.IsNull.nullValue;
@DisabledForJreRange(min = JRE.JAVA_16)
public class CuratorZookeeperTransporterTest {
private ZookeeperClient zookeeperClient;
private CuratorZookeeperTransporter curatorZookeeperTransporter;

View File

@ -20,11 +20,16 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.remoting.zookeeper.AbstractZookeeperTransporter;
import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
import org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import java.util.List;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.core.IsNull.nullValue;
@ -32,6 +37,7 @@ import static org.hamcrest.core.IsNull.nullValue;
/**
* AbstractZookeeperTransporterTest
*/
@DisabledForJreRange(min = JRE.JAVA_16)
public class AbstractZookeeperTransporterTest {
private ZookeeperClient zookeeperClient;
private AbstractZookeeperTransporter abstractZookeeperTransporter;

View File

@ -16,8 +16,6 @@
*/
package org.apache.dubbo.rpc;
import org.apache.dubbo.rpc.proxy.InvokerInvocationHandler;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@ -80,7 +78,7 @@ public class AppResponse implements Result {
if (exception != null) {
// fix issue#619
try {
Object stackTrace = InvokerInvocationHandler.stackTraceField.get(exception);
Object stackTrace = exception.getStackTrace();
if (stackTrace == null) {
exception.setStackTrace(new StackTraceElement[0]);
}

View File

@ -26,7 +26,6 @@ import org.apache.dubbo.rpc.RpcServiceContext;
import org.apache.dubbo.rpc.model.ConsumerModel;
import org.apache.dubbo.rpc.model.ServiceModel;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
@ -40,17 +39,6 @@ public class InvokerInvocationHandler implements InvocationHandler {
private URL url;
private String protocolServiceKey;
public static Field stackTraceField;
static {
try {
stackTraceField = Throwable.class.getDeclaredField("stackTrace");
stackTraceField.setAccessible(true);
} catch (NoSuchFieldException e) {
// ignore
}
}
public InvokerInvocationHandler(Invoker<?> handler) {
this.invoker = handler;
this.url = invoker.getUrl();

View File

@ -26,6 +26,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ConsumerModel;
import org.apache.dubbo.rpc.model.ModuleServiceRepository;
import org.apache.dubbo.rpc.protocol.dubbo.support.ProtocolUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;

View File

@ -21,6 +21,7 @@ import org.apache.dubbo.remoting.RemotingServer;
import org.apache.dubbo.rpc.ProtocolServer;
import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol;
import org.apache.dubbo.rpc.protocol.dubbo.decode.MockChannel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
@ -56,12 +57,16 @@ public class ServerStatusCheckerTest {
mockDubboProtocol.when(() -> DubboProtocol.getDubboProtocol()).thenReturn(dubboProtocol);
status = serverStatusChecker.check();
Assertions.assertEquals(status.getLevel(), Status.Level.OK);
Assertions.assertEquals(status.getMessage(), "127.0.0.1:9999(clients:1)");
// In JDK 17 : 127.0.0.1/<unresolved>:9999(clients:1)
Assertions.assertTrue(status.getMessage().contains("127.0.0.1"));
Assertions.assertTrue(status.getMessage().contains("9999(clients:1)"));
Mockito.when(remotingServer.isBound()).thenReturn(false);
status = serverStatusChecker.check();
Assertions.assertEquals(status.getLevel(), Status.Level.ERROR);
Assertions.assertEquals(status.getMessage(), "127.0.0.1:9999");
// In JDK 17 : 127.0.0.1/<unresolved>:9999
Assertions.assertTrue(status.getMessage().contains("127.0.0.1"));
Assertions.assertTrue(status.getMessage().contains("9999"));
}
}
}

View File

@ -89,7 +89,7 @@ public class InjvmDeepCopyTest {
applicationModel.destroy();
}
private interface DemoInterface {
interface DemoInterface {
Data call(Data obj);
}

View File

@ -21,6 +21,7 @@ import org.junit.platform.engine.support.descriptor.ClassSource;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan;
import java.util.HashSet;
import java.util.Set;

View File

@ -147,6 +147,12 @@
<version>${hamcrest_version}</version>
<!--<scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit_jupiter_version}</version>
<!-- <scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
@ -165,6 +171,22 @@
<version>${cglib_version}</version>
<!--<scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<!-- <scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<!-- <scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<!-- <scope>test</scope>-->
</dependency>
</dependencies>
</project>

View File

@ -52,6 +52,22 @@
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<!-- <scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<!-- <scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<!-- <scope>test</scope>-->
</dependency>
</dependencies>
<build>

View File

@ -51,7 +51,22 @@
<artifactId>dubbo-test-spring</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<!-- <scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<!-- <scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<!-- <scope>test</scope>-->
</dependency>
</dependencies>
<build>

View File

@ -51,7 +51,22 @@
<artifactId>dubbo-test-spring</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<!-- <scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<!-- <scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<!-- <scope>test</scope>-->
</dependency>
</dependencies>
<build>

39
pom.xml
View File

@ -88,14 +88,14 @@
<properties>
<!-- Test libs -->
<junit_jupiter_version>5.6.0</junit_jupiter_version>
<junit_jupiter_version>5.8.1</junit_jupiter_version>
<hazelcast_version>3.11.1</hazelcast_version>
<hamcrest_version>2.2</hamcrest_version>
<hibernate_validator_version>5.2.4.Final</hibernate_validator_version>
<el_api_version>2.2.4</el_api_version>
<jaxb_api_version>2.2.7</jaxb_api_version>
<cglib_version>2.2</cglib_version>
<mockito_version>3.8.0</mockito_version>
<mockito_version>3.12.4</mockito_version>
<!-- Build args -->
<argline>-server -Xms256m -Xmx512m -Dfile.encoding=UTF-8
-Djava.net.preferIPv4Stack=true -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m
@ -120,7 +120,7 @@
<maven_javadoc_version>3.2.0</maven_javadoc_version>
<maven_jetty_version>9.4.38.v20210224</maven_jetty_version>
<maven_checkstyle_version>3.1.2</maven_checkstyle_version>
<maven_jacoco_version>0.8.6</maven_jacoco_version>
<maven_jacoco_version>0.8.7</maven_jacoco_version>
<maven_flatten_version>1.2.5</maven_flatten_version>
<maven_enforce_version>3.0.0-M3</maven_enforce_version>
<apache-rat-plugin.version>0.13</apache-rat-plugin.version>
@ -179,6 +179,12 @@
<version>${junit_jupiter_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit_jupiter_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
@ -488,6 +494,33 @@
</plugins>
</build>
</profile>
<profile>
<id>jdk15ge</id>
<activation>
<jdk>[15,</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>true</useSystemClassLoader>
<forkMode>once</forkMode>
<argLine>${argline} ${jacocoArgLine}
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
</argLine>
<systemProperties>
<!-- common shared -->
</systemProperties>
<!-- Activate the use of TCP to transmit events to the plugin to fix Corrupted STDOUT issue -->
<forkNode implementation="org.apache.maven.plugin.surefire.extensions.SurefireForkNodeFactory"/>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>