/*
 * 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.config;

import demo.MultiClassLoaderService;
import demo.MultiClassLoaderServiceImpl;
import demo.MultiClassLoaderServiceRequest;
import demo.MultiClassLoaderServiceResult;
import javassist.CannotCompileException;
import javassist.CtClass;
import javassist.NotFoundException;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.compiler.support.CtClassBuilder;
import org.apache.dubbo.common.compiler.support.JavassistCompiler;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.ConfigUtils;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.annotation.Argument;
import org.apache.dubbo.config.annotation.Method;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.api.DemoService;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.config.context.ModuleConfigManager;
import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
import org.apache.dubbo.registry.client.migration.MigrationInvoker;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.ProxyFactory;
import org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareClusterInvoker;
import org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker;
import org.apache.dubbo.rpc.listener.ListenerInvokerWrapper;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ServiceMetadata;
import org.apache.dubbo.rpc.protocol.injvm.InjvmInvoker;
import org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol;
import org.apache.dubbo.rpc.service.GenericService;
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;
import org.junit.jupiter.api.condition.DisabledForJreRange;
import org.junit.jupiter.api.condition.JRE;
import org.mockito.Mockito;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_VERSION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.BROADCAST_CLUSTER;
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.DUMP_DIRECTORY;
import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.LIVENESS_PROBE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METADATA_SERVICE_PORT_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METADATA_SERVICE_PROTOCOL_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.READINESS_PROBE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REFER_ASYNC_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REFER_BACKGROUND_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REFER_THREAD_NUM_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REGISTRY_LOCAL_FILE_CACHE_ENABLED;
import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REVISION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.STARTUP_PROBE;
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.URL_MERGE_PROCESSOR_KEY;
import static org.apache.dubbo.common.constants.QosConstants.ACCEPT_FOREIGN_IP;
import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE;
import static org.apache.dubbo.common.constants.QosConstants.QOS_HOST;
import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT;
import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
import static org.apache.dubbo.rpc.Constants.DEFAULT_STUB_EVENT;
import static org.apache.dubbo.rpc.Constants.LOCAL_KEY;
import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;

public class ReferenceConfigTest {
    private static String zkUrl1;
    private static String zkUrl2;
    private static String registryUrl1;

    @BeforeAll
    public static void beforeAll() {
        int zkServerPort1 = 2181;
        int zkServerPort2 = 2182;
        zkUrl1 = "zookeeper://localhost:" + zkServerPort1;
        zkUrl2 = "zookeeper://localhost:" + zkServerPort2;
        registryUrl1 = "registry://localhost:" + zkServerPort1 + "?registry=zookeeper";
    }

    @BeforeEach
    public void setUp() throws Exception {
        DubboBootstrap.reset();
        ApplicationModel.defaultModel().getApplicationConfigManager();
        DubboBootstrap.getInstance();
    }

    @AfterEach
    public void tearDown() throws IOException {
        DubboBootstrap.reset();
        Mockito.framework().clearInlineMocks();
    }

    /**
     * Test whether the configuration required for the aggregation service reference meets expectations
     */
    @Test
    public void testAppendConfig() {

        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("application1");
        applicationConfig.setVersion("v1");
        applicationConfig.setOwner("owner1");
        applicationConfig.setOrganization("bu1");
        applicationConfig.setArchitecture("architecture1");
        applicationConfig.setEnvironment("test");
        applicationConfig.setCompiler("javassist");
        applicationConfig.setLogger("log4j");
        applicationConfig.setDumpDirectory("/");
        applicationConfig.setQosEnable(false);
        applicationConfig.setQosHost("127.0.0.1");
        applicationConfig.setQosPort(77777);
        applicationConfig.setQosAcceptForeignIp(false);
        Map<String, String> parameters = new HashMap<>();
        parameters.put("key1", "value1");
        parameters.put("key2", "value2");
        applicationConfig.setParameters(parameters);
        applicationConfig.setShutwait("5");
        applicationConfig.setMetadataType("local");
        applicationConfig.setRegisterConsumer(false);
        applicationConfig.setRepository("repository1");
        applicationConfig.setEnableFileCache(false);
        applicationConfig.setProtocol("dubbo");
        applicationConfig.setMetadataServicePort(88888);
        applicationConfig.setMetadataServiceProtocol("tri");
        applicationConfig.setLivenessProbe("livenessProbe");
        applicationConfig.setReadinessProbe("readinessProb");
        applicationConfig.setStartupProbe("startupProbe");

        ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
        referenceConfig.setClient("netty");
        referenceConfig.setGeneric(Boolean.FALSE.toString());
        referenceConfig.setProtocol("dubbo");
        referenceConfig.setInit(true);
        referenceConfig.setLazy(false);
        referenceConfig.setInjvm(false);
        referenceConfig.setReconnect("reconnect");
        referenceConfig.setSticky(false);
        referenceConfig.setStub(DEFAULT_STUB_EVENT);
        referenceConfig.setRouter("default");
        referenceConfig.setReferAsync(true);

        MonitorConfig monitorConfig = new MonitorConfig();
        applicationConfig.setMonitor(monitorConfig);

        ModuleConfig moduleConfig = new ModuleConfig();
        moduleConfig.setMonitor("default");
        moduleConfig.setName("module1");
        moduleConfig.setOrganization("application1");
        moduleConfig.setVersion("v1");
        moduleConfig.setOwner("owner1");

        ConsumerConfig consumerConfig = new ConsumerConfig();
        consumerConfig.setClient("netty");
        consumerConfig.setThreadpool("fixed");
        consumerConfig.setCorethreads(200);
        consumerConfig.setQueues(500);
        consumerConfig.setThreads(300);
        consumerConfig.setShareconnections(10);
        consumerConfig.setUrlMergeProcessor("default");
        consumerConfig.setReferThreadNum(20);
        consumerConfig.setReferBackground(false);
        referenceConfig.setConsumer(consumerConfig);

        MethodConfig methodConfig = new MethodConfig();
        methodConfig.setName("sayName");
        methodConfig.setStat(1);
        methodConfig.setRetries(0);
        methodConfig.setExecutes(10);
        methodConfig.setDeprecated(false);
        methodConfig.setSticky(false);
        methodConfig.setReturn(false);
        methodConfig.setService("service");
        methodConfig.setServiceId(DemoService.class.getName());
        methodConfig.setParentPrefix("demo");

        referenceConfig.setMethods(Collections.singletonList(methodConfig));

        referenceConfig.setInterface(DemoService.class);
        referenceConfig.getInterfaceClass();
        referenceConfig.setCheck(false);
        RegistryConfig registry = new RegistryConfig();
        registry.setAddress(zkUrl1);
        applicationConfig.setRegistries(Collections.singletonList(registry));
        applicationConfig.setRegistryIds(registry.getId());
        moduleConfig.setRegistries(Collections.singletonList(registry));

        referenceConfig.setRegistry(registry);

        DubboBootstrap dubboBootstrap = DubboBootstrap.newInstance(FrameworkModel.defaultModel());
        dubboBootstrap.application(applicationConfig)
            .reference(referenceConfig)
            .registry(registry)
            .module(moduleConfig)
            .initialize();

        referenceConfig.init();

        ServiceMetadata serviceMetadata = referenceConfig.getServiceMetadata();

        // verify additional side parameter
        Assertions.assertEquals(CONSUMER_SIDE, serviceMetadata.getAttachments().get(SIDE_KEY));

        // verify additional interface parameter
        Assertions.assertEquals(DemoService.class.getName(), serviceMetadata.getAttachments().get(INTERFACE_KEY));

        // verify additional metadata-type parameter
        Assertions.assertEquals(DEFAULT_METADATA_STORAGE_TYPE, serviceMetadata.getAttachments().get(METADATA_KEY));

        // verify additional register.ip parameter
        Assertions.assertEquals(NetUtils.getLocalHost(), serviceMetadata.getAttachments().get(REGISTER_IP_KEY));

        // verify additional runtime parameters
        Assertions.assertEquals(Version.getProtocolVersion(), serviceMetadata.getAttachments().get(DUBBO_VERSION_KEY));
        Assertions.assertEquals(Version.getVersion(), serviceMetadata.getAttachments().get(RELEASE_KEY));
        Assertions.assertTrue(serviceMetadata.getAttachments().containsKey(TIMESTAMP_KEY));
        Assertions.assertEquals(String.valueOf(ConfigUtils.getPid()), serviceMetadata.getAttachments().get(PID_KEY));

        // verify additional application config
        Assertions.assertEquals(applicationConfig.getName(), serviceMetadata.getAttachments().get(APPLICATION_KEY));
        Assertions.assertEquals(applicationConfig.getOwner(), serviceMetadata.getAttachments().get("owner"));
        Assertions.assertEquals(applicationConfig.getVersion(),
            serviceMetadata.getAttachments().get(APPLICATION_VERSION_KEY));
        Assertions.assertEquals(applicationConfig.getOrganization(),
            serviceMetadata.getAttachments().get("organization"));
        Assertions.assertEquals(applicationConfig.getArchitecture(),
            serviceMetadata.getAttachments().get("architecture"));
        Assertions.assertEquals(applicationConfig.getEnvironment(),
            serviceMetadata.getAttachments().get("environment"));
        Assertions.assertEquals(applicationConfig.getCompiler(), serviceMetadata.getAttachments().get("compiler"));
        Assertions.assertEquals(applicationConfig.getLogger(), serviceMetadata.getAttachments().get("logger"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("registries"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("registry.ids"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("monitor"));
        Assertions.assertEquals(applicationConfig.getDumpDirectory(),
            serviceMetadata.getAttachments().get(DUMP_DIRECTORY));
        Assertions.assertEquals(applicationConfig.getQosEnable().toString(),
            serviceMetadata.getAttachments().get(QOS_ENABLE));
        Assertions.assertEquals(applicationConfig.getQosHost(),
            serviceMetadata.getAttachments().get(QOS_HOST));
        Assertions.assertEquals(applicationConfig.getQosPort().toString(),
            serviceMetadata.getAttachments().get(QOS_PORT));
        Assertions.assertEquals(applicationConfig.getQosAcceptForeignIp().toString(),
            serviceMetadata.getAttachments().get(ACCEPT_FOREIGN_IP));
        Assertions.assertEquals(applicationConfig.getParameters().get("key1"),
            serviceMetadata.getAttachments().get("key1"));
        Assertions.assertEquals(applicationConfig.getParameters().get("key2"),
            serviceMetadata.getAttachments().get("key2"));
        Assertions.assertEquals(applicationConfig.getShutwait(),
            serviceMetadata.getAttachments().get("shutwait"));
        Assertions.assertEquals(applicationConfig.getMetadataType(),
            serviceMetadata.getAttachments().get(METADATA_KEY));
        Assertions.assertEquals(applicationConfig.getRegisterConsumer().toString(),
            serviceMetadata.getAttachments().get("register.consumer"));
        Assertions.assertEquals(applicationConfig.getRepository(),
            serviceMetadata.getAttachments().get("repository"));
        Assertions.assertEquals(applicationConfig.getEnableFileCache().toString(),
            serviceMetadata.getAttachments().get(REGISTRY_LOCAL_FILE_CACHE_ENABLED));
        Assertions.assertEquals(applicationConfig.getMetadataServicePort().toString(),
            serviceMetadata.getAttachments().get(METADATA_SERVICE_PORT_KEY));
        Assertions.assertEquals(applicationConfig.getMetadataServiceProtocol().toString(),
            serviceMetadata.getAttachments().get(METADATA_SERVICE_PROTOCOL_KEY));
        Assertions.assertEquals(applicationConfig.getLivenessProbe(),
            serviceMetadata.getAttachments().get(LIVENESS_PROBE_KEY));
        Assertions.assertEquals(applicationConfig.getReadinessProbe(),
            serviceMetadata.getAttachments().get(READINESS_PROBE_KEY));
        Assertions.assertEquals(applicationConfig.getStartupProbe(),
            serviceMetadata.getAttachments().get(STARTUP_PROBE));

        // verify additional module config
        Assertions.assertEquals(moduleConfig.getName(), serviceMetadata.getAttachments().get("module"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("monitor"));
        Assertions.assertEquals(moduleConfig.getOrganization(),
            serviceMetadata.getAttachments().get("module.organization"));
        Assertions.assertEquals(moduleConfig.getOwner(), serviceMetadata.getAttachments().get("module.owner"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("registries"));
        Assertions.assertEquals(moduleConfig.getVersion(), serviceMetadata.getAttachments().get("module.version"));

        // verify additional consumer config
        Assertions.assertEquals(consumerConfig.getClient(), serviceMetadata.getAttachments().get("client"));
        Assertions.assertEquals(consumerConfig.getThreadpool(), serviceMetadata.getAttachments().get("threadpool"));
        Assertions.assertEquals(consumerConfig.getCorethreads().toString(),
            serviceMetadata.getAttachments().get("corethreads"));
        Assertions.assertEquals(consumerConfig.getQueues().toString(),
            serviceMetadata.getAttachments().get("queues"));
        Assertions.assertEquals(consumerConfig.getThreads().toString(),
            serviceMetadata.getAttachments().get("threads"));
        Assertions.assertEquals(consumerConfig.getShareconnections().toString(),
            serviceMetadata.getAttachments().get("shareconnections"));
        Assertions.assertEquals(consumerConfig.getUrlMergeProcessor(),
            serviceMetadata.getAttachments().get(URL_MERGE_PROCESSOR_KEY));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey(REFER_THREAD_NUM_KEY));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey(REFER_BACKGROUND_KEY));

        // verify additional reference config
        Assertions.assertEquals(referenceConfig.getClient(), serviceMetadata.getAttachments().get("client"));
        Assertions.assertEquals(referenceConfig.getGeneric(), serviceMetadata.getAttachments().get("generic"));
        Assertions.assertEquals(referenceConfig.getProtocol(), serviceMetadata.getAttachments().get("protocol"));
        Assertions.assertEquals(referenceConfig.isInit().toString(), serviceMetadata.getAttachments().get("init"));
        Assertions.assertEquals(referenceConfig.getLazy().toString(), serviceMetadata.getAttachments().get("lazy"));
        Assertions.assertEquals(referenceConfig.isInjvm().toString(), serviceMetadata.getAttachments().get("injvm"));
        Assertions.assertEquals(referenceConfig.getReconnect(), serviceMetadata.getAttachments().get("reconnect"));
        Assertions.assertEquals(referenceConfig.getSticky().toString(), serviceMetadata.getAttachments().get("sticky"));
        Assertions.assertEquals(referenceConfig.getStub(), serviceMetadata.getAttachments().get("stub"));
        Assertions.assertEquals(referenceConfig.getProvidedBy(), serviceMetadata.getAttachments().get("provided-by"));
        Assertions.assertEquals(referenceConfig.getRouter(), serviceMetadata.getAttachments().get("router"));
        Assertions.assertEquals(referenceConfig.getReferAsync().toString(),
            serviceMetadata.getAttachments().get(REFER_ASYNC_KEY));

        // verify additional method config
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("name"));
        Assertions.assertEquals(methodConfig.getStat().toString(),
            serviceMetadata.getAttachments().get("sayName.stat"));
        Assertions.assertEquals(methodConfig.getRetries().toString(),
            serviceMetadata.getAttachments().get("sayName.retries"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.reliable"));
        Assertions.assertEquals(methodConfig.getExecutes().toString(),
            serviceMetadata.getAttachments().get("sayName.executes"));
        Assertions.assertEquals(methodConfig.getDeprecated().toString(),
            serviceMetadata.getAttachments().get("sayName.deprecated"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.stick"));
        Assertions.assertEquals(methodConfig.isReturn().toString(),
            serviceMetadata.getAttachments().get("sayName.return"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.service"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.service.id"));
        Assertions.assertFalse(serviceMetadata.getAttachments().containsKey("sayName.parent.prefix"));

        // verify additional revision and methods parameter
        Assertions.assertEquals(Version.getVersion(referenceConfig.getInterfaceClass(), referenceConfig.getVersion()),
            serviceMetadata.getAttachments().get(REVISION_KEY));
        Assertions.assertTrue(serviceMetadata.getAttachments().containsKey(METHODS_KEY));
        Assertions.assertEquals(DemoService.class.getMethods().length,
            StringUtils.split((String) serviceMetadata.getAttachments().get(METHODS_KEY), ',').length);

        dubboBootstrap.stop();
    }

    @Test
    public void testShouldJvmRefer() {

        Map<String, String> parameters = new HashMap<>();

        ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();

        // verify that if injvm is configured as true, local references should be made
        referenceConfig.setInjvm(true);
        Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters));

        // verify that if injvm is configured as false, local references should not be made
        referenceConfig.setInjvm(false);
        Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters));

        // verify that if url is configured, local reference should not be made
        referenceConfig.setInjvm(null);
        referenceConfig.setUrl("dubbo://127.0.0.1:20880/DemoService");
        parameters.put(INTERFACE_KEY, DemoService.class.getName());
        Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters));
        parameters.clear();

        // verify that if scope is configured as local, local references should be made
        referenceConfig.setInjvm(null);
        referenceConfig.setUrl(null);
        parameters.put(SCOPE_KEY, SCOPE_LOCAL);
        Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters));
        parameters.clear();

        // verify that if url protocol is configured as injvm, local references should be made
        referenceConfig.setInjvm(null);
        referenceConfig.setUrl(null);
        parameters.put(LOCAL_PROTOCOL, "true");
        Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters));
        parameters.clear();

        // verify that if generic is configured as true, local references should not be made
        referenceConfig.setInjvm(null);
        referenceConfig.setUrl(null);
        parameters.put(GENERIC_KEY, "true");
        Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters));
        parameters.clear();

        // verify that if the service has been exposed, and the cluster is not configured with broadcast, local reference should be made
        referenceConfig.setInjvm(null);
        referenceConfig.setUrl(null);
        ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
        DemoService service = new DemoServiceImpl();
        URL url = URL.valueOf("dubbo://127.0.0.1/DemoService")
            .addParameter(INTERFACE_KEY, DemoService.class.getName());
        parameters.put(INTERFACE_KEY, DemoService.class.getName());
        Exporter<?> exporter = InjvmProtocol.getInjvmProtocol(FrameworkModel.defaultModel()).export(proxy.getInvoker(service, DemoService.class, url));
        InjvmProtocol.getInjvmProtocol(FrameworkModel.defaultModel()).getExporterMap().put(DemoService.class.getName(), exporter);
        Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters));

        // verify that if the service has been exposed, and the cluster is configured with broadcast, local reference should not be made
        parameters.put(CLUSTER_KEY, BROADCAST_CLUSTER);
        Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters));
        parameters.clear();
        InjvmProtocol.getInjvmProtocol(FrameworkModel.defaultModel()).destroy();
    }

    @Test
    public void testCreateInvokerForLocalRefer() {

        ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
        referenceConfig.setScope(LOCAL_KEY);

        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("application1");
        Map<String, String> parameters = new HashMap<>();
        parameters.put("key1", "value1");
        parameters.put("key2", "value2");
        applicationConfig.setParameters(parameters);

        referenceConfig.setInterface(DemoService.class);
        referenceConfig.getInterfaceClass();
        referenceConfig.setCheck(false);

        DubboBootstrap dubboBootstrap = DubboBootstrap.newInstance(FrameworkModel.defaultModel());
        dubboBootstrap.application(applicationConfig)
            .reference(referenceConfig)
            .initialize();

        referenceConfig.init();
        Assertions.assertTrue(referenceConfig.getInvoker() instanceof MockClusterInvoker);
        Invoker<?> withFilter = ((MockClusterInvoker<?>) referenceConfig.getInvoker()).getDirectory().getAllInvokers().get(0);
        Assertions.assertTrue(withFilter instanceof ListenerInvokerWrapper);
        Assertions.assertTrue(((ListenerInvokerWrapper<?>) withFilter).getInvoker() instanceof InjvmInvoker);
        URL url = withFilter.getUrl();
        Assertions.assertEquals("application1", url.getParameter("application"));
        Assertions.assertEquals("value1", url.getParameter("key1"));
        Assertions.assertEquals("value2", url.getParameter("key2"));

        dubboBootstrap.stop();
    }

    /**
     * Verify the configuration of the registry protocol for remote reference
     */
    @Test
    public void testCreateInvokerForRemoteRefer() {

        ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
        referenceConfig.setGeneric(Boolean.FALSE.toString());
        referenceConfig.setProtocol("dubbo");
        referenceConfig.setInit(true);
        referenceConfig.setLazy(false);
        referenceConfig.setInjvm(false);

        DubboBootstrap dubboBootstrap = DubboBootstrap.newInstance(FrameworkModel.defaultModel());

        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("application1");
        Map<String, String> parameters = new HashMap<>();
        parameters.put("key1", "value1");
        parameters.put("key2", "value2");
        applicationConfig.setParameters(parameters);

        referenceConfig.refreshed.set(true);
        referenceConfig.setInterface(DemoService.class);
        referenceConfig.getInterfaceClass();
        referenceConfig.setCheck(false);
        RegistryConfig registry = new RegistryConfig();
        registry.setAddress(zkUrl1);
        applicationConfig.setRegistries(Collections.singletonList(registry));
        applicationConfig.setRegistryIds(registry.getId());

        referenceConfig.setRegistry(registry);

        dubboBootstrap
            .application(applicationConfig)
            .reference(referenceConfig)
            .initialize();

        referenceConfig.init();
        Assertions.assertTrue(referenceConfig.getInvoker() instanceof MigrationInvoker);

        dubboBootstrap.destroy();
    }


    /**
     * Verify that the remote url is directly configured for remote reference
     */
    @Test
    public void testCreateInvokerWithRemoteUrlForRemoteRefer() {

        ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
        referenceConfig.setGeneric(Boolean.FALSE.toString());
        referenceConfig.setProtocol("dubbo");
        referenceConfig.setInit(true);
        referenceConfig.setLazy(false);
        referenceConfig.setInjvm(false);

        DubboBootstrap dubboBootstrap = DubboBootstrap.newInstance(FrameworkModel.defaultModel());

        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("application1");
        Map<String, String> parameters = new HashMap<>();
        parameters.put("key1", "value1");
        parameters.put("key2", "value2");
        applicationConfig.setParameters(parameters);

        referenceConfig.refreshed.set(true);
        referenceConfig.setInterface(DemoService.class);
        referenceConfig.getInterfaceClass();
        referenceConfig.setCheck(false);

        referenceConfig.setUrl("dubbo://127.0.0.1:20880");

        dubboBootstrap
            .application(applicationConfig)
            .reference(referenceConfig)
            .initialize();

        referenceConfig.init();
        Assertions.assertTrue(referenceConfig.getInvoker() instanceof MockClusterInvoker);
        Assertions.assertEquals(Boolean.TRUE, referenceConfig.getInvoker().getUrl().getAttribute(PEER_KEY));
        dubboBootstrap.destroy();

    }

    /**
     * Verify that the registry url is directly configured for remote reference
     */
    @Test
    public void testCreateInvokerWithRegistryUrlForRemoteRefer() {

        ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
        referenceConfig.setGeneric(Boolean.FALSE.toString());
        referenceConfig.setProtocol("dubbo");
        referenceConfig.setInit(true);
        referenceConfig.setLazy(false);
        referenceConfig.setInjvm(false);

        DubboBootstrap dubboBootstrap = DubboBootstrap.newInstance(FrameworkModel.defaultModel());

        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("application1");
        Map<String, String> parameters = new HashMap<>();
        parameters.put("key1", "value1");
        parameters.put("key2", "value2");
        applicationConfig.setParameters(parameters);

        referenceConfig.refreshed.set(true);
        referenceConfig.setInterface(DemoService.class);
        referenceConfig.getInterfaceClass();
        referenceConfig.setCheck(false);

        referenceConfig.setUrl(registryUrl1);

        dubboBootstrap
            .application(applicationConfig)
            .reference(referenceConfig)
            .initialize();

        referenceConfig.init();
        Assertions.assertTrue(referenceConfig.getInvoker() instanceof MigrationInvoker);
        dubboBootstrap.destroy();

    }

    /**
     * Verify the service reference of multiple registries
     */
    @Test
    public void testMultipleRegistryForRemoteRefer() {
        ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
        referenceConfig.setGeneric(Boolean.FALSE.toString());
        referenceConfig.setProtocol("dubbo");
        referenceConfig.setInit(true);
        referenceConfig.setLazy(false);
        referenceConfig.setInjvm(false);

        DubboBootstrap dubboBootstrap = DubboBootstrap.newInstance(FrameworkModel.defaultModel());

        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("application1");
        Map<String, String> parameters = new HashMap<>();
        parameters.put("key1", "value1");
        parameters.put("key2", "value2");
        applicationConfig.setParameters(parameters);

        referenceConfig.refreshed.set(true);
        referenceConfig.setInterface(DemoService.class);
        referenceConfig.getInterfaceClass();
        referenceConfig.setCheck(false);
        RegistryConfig registry1 = new RegistryConfig();
        registry1.setAddress(zkUrl1);
        registry1.setId("zk1");

        RegistryConfig registry2 = new RegistryConfig();
        registry2.setAddress(zkUrl2);
        registry2.setId("zk2");

        List<RegistryConfig> registryConfigs = new ArrayList<>();
        registryConfigs.add(registry1);
        registryConfigs.add(registry2);
        applicationConfig.setRegistries(registryConfigs);
        applicationConfig.setRegistryIds("zk1,zk2");

        referenceConfig.setRegistries(registryConfigs);

        dubboBootstrap
            .application(applicationConfig)
            .reference(referenceConfig)
            .initialize();

        referenceConfig.init();
        Assertions.assertTrue(referenceConfig.getInvoker() instanceof ZoneAwareClusterInvoker);

        dubboBootstrap.destroy();
    }

    @Test
    @Disabled("Disabled due to Github Actions environment")
    public void testInjvm() throws Exception {
        ApplicationConfig application = new ApplicationConfig();
        application.setName("test-protocol-random-port");
        application.setEnableFileCache(false);
        ApplicationModel.defaultModel().getApplicationConfigManager().setApplication(application);

        RegistryConfig registry = new RegistryConfig();
        registry.setAddress(zkUrl1);

        ProtocolConfig protocol = new ProtocolConfig();
        protocol.setName("dubbo");

        ServiceConfig<DemoService> demoService;
        demoService = new ServiceConfig<>();
        demoService.setInterface(DemoService.class);
        demoService.setRef(new DemoServiceImpl());
        demoService.setRegistry(registry);
        demoService.setProtocol(protocol);

        ReferenceConfig<DemoService> rc = new ReferenceConfig<>();
        rc.setRegistry(registry);
        rc.setInterface(DemoService.class.getName());
        rc.setScope(SCOPE_REMOTE);

        try {
            System.setProperty("java.net.preferIPv4Stack", "true");
            demoService.export();
            rc.get();
            Assertions.assertFalse(LOCAL_PROTOCOL.equalsIgnoreCase(
                rc.getInvoker().getUrl().getProtocol()));
        } finally {
            System.clearProperty("java.net.preferIPv4Stack");
            rc.destroy();
            demoService.unexport();
        }

        // Manually trigger dubbo resource recycling.
        DubboBootstrap.getInstance().destroy();
    }

    /**
     * unit test for dubbo-1765
     */
    @Test
    public void test1ReferenceRetry() {
        ApplicationConfig application = new ApplicationConfig();
        application.setName("test-reference-retry");
        application.setEnableFileCache(false);
        ApplicationModel.defaultModel().getApplicationConfigManager().setApplication(application);

        RegistryConfig registry = new RegistryConfig();
        registry.setAddress(zkUrl1);

        ReferenceConfig<DemoService> rc = new ReferenceConfig<>();
        rc.setRegistry(registry);
        rc.setInterface(DemoService.class.getName());

        boolean success = false;
        DemoService demoService = null;
        try {
            demoService = rc.get();
            success = true;
        } catch (Exception e) {
            // ignore
        }
        Assertions.assertFalse(success);
        Assertions.assertNull(demoService);

        try {
            System.setProperty("java.net.preferIPv4Stack", "true");
            ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
            DemoService service = new DemoServiceImpl();
            URL url = URL.valueOf("dubbo://127.0.0.1/DemoService")
                .addParameter(INTERFACE_KEY, DemoService.class.getName());
            InjvmProtocol.getInjvmProtocol(FrameworkModel.defaultModel()).export(proxy.getInvoker(service, DemoService.class, url));
            demoService = rc.get();
            success = true;
        } catch (Exception e) {
            // ignore
        } finally {
            rc.destroy();
            InjvmProtocol.getInjvmProtocol(FrameworkModel.defaultModel()).destroy();
            System.clearProperty("java.net.preferIPv4Stack");

        }
        Assertions.assertTrue(success);
        Assertions.assertNotNull(demoService);

    }

    @Test
    public void test2ReferenceRetry() {
        ApplicationConfig application = new ApplicationConfig();
        application.setName("test-reference-retry2");
        application.setEnableFileCache(false);
        ApplicationModel.defaultModel().getApplicationConfigManager().setApplication(application);

        RegistryConfig registry = new RegistryConfig();
        registry.setAddress(zkUrl1);
        ProtocolConfig protocol = new ProtocolConfig();
        protocol.setName("mockprotocol");

        ReferenceConfig<DemoService> rc = new ReferenceConfig<>();
        rc.setRegistry(registry);
        rc.setInterface(DemoService.class.getName());

        boolean success = false;
        DemoService demoService = null;
        try {
            demoService = rc.get();
            success = true;
        } catch (Exception e) {
            // ignore
        }
        Assertions.assertFalse(success);
        Assertions.assertNull(demoService);

        ServiceConfig<DemoService> sc = new ServiceConfig<>();
        sc.setInterface(DemoService.class.getName());
        sc.setRef(new DemoServiceImpl());
        sc.setRegistry(registry);
        sc.setProtocol(protocol);

        try {
            System.setProperty("java.net.preferIPv4Stack", "true");
            sc.export();
            demoService = rc.get();
            success = true;
        } catch (Exception e) {
            // ignore
        } finally {
            rc.destroy();
            sc.unexport();
            System.clearProperty("java.net.preferIPv4Stack");

        }
        Assertions.assertTrue(success);
        Assertions.assertNotNull(demoService);

    }

    @Test
    public void testMetaData() {
        ReferenceConfig config = new ReferenceConfig();
        Map<String, String> metaData = config.getMetaData();
        Assertions.assertEquals(0, metaData.size(), "Expect empty metadata but found: " + metaData);

        // test merged and override consumer attributes
        ConsumerConfig consumerConfig = new ConsumerConfig();
        consumerConfig.setAsync(true);
        consumerConfig.setActives(10);
        config.setConsumer(consumerConfig);
        config.setAsync(false);// override

        metaData = config.getMetaData();
        Assertions.assertEquals(2, metaData.size());
        Assertions.assertEquals(String.valueOf(consumerConfig.getActives()), metaData.get("actives"));
        Assertions.assertEquals(String.valueOf(config.isAsync()), metaData.get("async"));

    }

    @Test
    public void testGetPrefixes() {

        ReferenceConfig referenceConfig = new ReferenceConfig();
        referenceConfig.setInterface(DemoService.class);

        List<String> prefixes = referenceConfig.getPrefixes();
        Assertions.assertTrue(prefixes.contains("dubbo.reference." + referenceConfig.getInterface()));

        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            referenceConfig.getPrefixes();
        }
        long end = System.currentTimeMillis();
        System.out.println("ReferenceConfig get prefixes cost: " + (end - start));

    }

    @Test
    public void testGenericAndInterfaceConflicts() {

        ReferenceConfig referenceConfig = new ReferenceConfig();
        referenceConfig.setInterface(DemoService.class);
        referenceConfig.setGeneric("true");

        DubboBootstrap.getInstance()
            .application("demo app")
            .reference(referenceConfig)
            .initialize();

        Assertions.assertEquals(GenericService.class, referenceConfig.getInterfaceClass());
    }


    @Test
    public void testLargeReferences() throws InterruptedException {
        int amount = 10000;
        ModuleConfigManager configManager = DubboBootstrap.getInstance().getApplicationModel().getDefaultModule().getConfigManager();

        ApplicationConfig applicationConfig = new ApplicationConfig();
        applicationConfig.setName("test-app");
        MetadataReportConfig metadataReportConfig = new MetadataReportConfig();
        metadataReportConfig.setAddress("metadata://");
        ConfigCenterConfig configCenterConfig = new ConfigCenterConfig();
        configCenterConfig.setAddress("diamond://");

        testInitReferences(0, amount, applicationConfig, metadataReportConfig, configCenterConfig);
        configManager.clear();
        testInitReferences(0, 1, applicationConfig, metadataReportConfig, configCenterConfig);
        configManager.clear();

        long t1 = System.currentTimeMillis();
        int nThreads = 8;
        ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
        for (int i = 0; i < nThreads; i++) {
            int perCount = (int) (1.0 * amount / nThreads);
            int start = perCount * i;
            int end = start + perCount;
            if (i == nThreads - 1) {
                end = amount;
            }
            int finalEnd = end;
            System.out.println(String.format("start thread %s: range: %s - %s, count: %s", i, start, end, (end - start)));
            executorService.submit(() -> {
                testInitReferences(start, finalEnd, applicationConfig, metadataReportConfig, configCenterConfig);
            });
        }
        executorService.shutdown();
        executorService.awaitTermination(100, TimeUnit.SECONDS);

        long t2 = System.currentTimeMillis();
        long cost = t2 - t1;
        System.out.println("Init large references cost: " + cost + "ms");
        Assertions.assertEquals(amount, configManager.getReferences().size());
        Assertions.assertTrue(cost < 1000, "Init large references too slowly: " + cost);

        //test equals
        testSearchReferences();

    }

    private void testSearchReferences() {
        long t1 = System.currentTimeMillis();
        Collection<ReferenceConfigBase<?>> references = DubboBootstrap.getInstance().getApplicationModel().getDefaultModule().getConfigManager().getReferences();
        List<ReferenceConfigBase<?>> results = references.stream().filter(rc -> rc.equals(references.iterator().next()))
            .collect(Collectors.toList());
        long t2 = System.currentTimeMillis();
        long cost = t2 - t1;
        System.out.println("Search large references cost: " + cost + "ms");
        Assertions.assertEquals(1, results.size());
        Assertions.assertTrue(cost < 1000, "Search large references too slowly: " + cost);
    }

    private long testInitReferences(int start, int end, ApplicationConfig applicationConfig, MetadataReportConfig metadataReportConfig, ConfigCenterConfig configCenterConfig) {
        // test add large number of references
        long t1 = System.currentTimeMillis();
        try {
            for (int i = start; i < end; i++) {
                ReferenceConfig referenceConfig = new ReferenceConfig();
                referenceConfig.setInterface("com.test.TestService" + i);
                referenceConfig.setApplication(applicationConfig);
                referenceConfig.setMetadataReportConfig(metadataReportConfig);
                referenceConfig.setConfigCenter(configCenterConfig);
                DubboBootstrap.getInstance().reference(referenceConfig);

                //ApplicationModel.defaultModel().getConfigManager().getConfigCenters();
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        long t2 = System.currentTimeMillis();
        return t2 - t1;
    }

    @Test
    public void testConstructWithReferenceAnnotation() throws NoSuchFieldException {
        Reference reference = getClass().getDeclaredField("innerTest").getAnnotation(Reference.class);
        ReferenceConfig referenceConfig = new ReferenceConfig(reference);
        Assertions.assertEquals(1, referenceConfig.getMethods().size());
        Assertions.assertEquals((referenceConfig.getMethods().get(0)).getName(), "sayHello");
        Assertions.assertEquals(1300, (int) (referenceConfig.getMethods().get(0)).getTimeout());
        Assertions.assertEquals(4, (int) (referenceConfig.getMethods().get(0)).getRetries());
        Assertions.assertEquals((referenceConfig.getMethods().get(0)).getLoadbalance(), "random");
        Assertions.assertEquals(3, (int) (referenceConfig.getMethods().get(0)).getActives());
        Assertions.assertEquals(5, (int) (referenceConfig.getMethods().get(0)).getExecutes());
        Assertions.assertTrue((referenceConfig.getMethods().get(0)).isAsync());
        Assertions.assertEquals((referenceConfig.getMethods().get(0)).getOninvokeMethod(), "i");
        Assertions.assertEquals((referenceConfig.getMethods().get(0)).getOnreturnMethod(), "r");
        Assertions.assertEquals((referenceConfig.getMethods().get(0)).getOnthrowMethod(), "t");
        Assertions.assertEquals((referenceConfig.getMethods().get(0)).getCache(), "c");
    }

    @Test
    public void testDifferentClassLoader() throws Exception {
        ApplicationConfig applicationConfig = new ApplicationConfig("TestApp");
        ApplicationModel applicationModel = new ApplicationModel(FrameworkModel.defaultModel());
        applicationModel.getApplicationConfigManager().setApplication(applicationConfig);
        ModuleModel moduleModel = new ModuleModel(applicationModel);

        DemoService demoService = new DemoServiceImpl();
        ServiceConfig<DemoService> serviceConfig = new ServiceConfig<>();
        serviceConfig.setInterface(DemoService.class);
        serviceConfig.setRegistry(new RegistryConfig(zkUrl1));
        serviceConfig.setScopeModel(moduleModel);
        serviceConfig.setRef(demoService);
        serviceConfig.export();

        String basePath = DemoService.class.getProtectionDomain().getCodeSource().getLocation().getFile();
        basePath = URLDecoder.decode(basePath, "UTF-8");
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        TestClassLoader classLoader1 = new TestClassLoader(classLoader, basePath);
        TestClassLoader classLoader2 = new TestClassLoader(classLoader, basePath);

        Class<?> class1 = classLoader1.loadClass(DemoService.class.getName(), false);
        Class<?> class2 = classLoader2.loadClass(DemoService.class.getName(), false);

        Assertions.assertNotEquals(class1, class2);

        ReferenceConfig<DemoService> referenceConfig1 = new ReferenceConfig<>();
        referenceConfig1.setInterface(class1);
        referenceConfig1.setRegistry(new RegistryConfig(zkUrl1));
        referenceConfig1.setScopeModel(moduleModel);
        referenceConfig1.setScope("remote");
        Object demoService1 = referenceConfig1.get();

        for (Class<?> anInterface : demoService1.getClass().getInterfaces()) {
            Assertions.assertNotEquals(DemoService.class, anInterface);
        }
        Assertions.assertTrue(Arrays.stream(demoService1.getClass().getInterfaces()).anyMatch((clazz) -> clazz.getClassLoader().equals(classLoader1)));

        java.lang.reflect.Method callBean1 = demoService1.getClass().getDeclaredMethod("callInnerClass");
        callBean1.setAccessible(true);
        Object result1 = callBean1.invoke(demoService1);

        Assertions.assertNotEquals(result1.getClass(), DemoService.InnerClass.class);
        Assertions.assertEquals(classLoader1, result1.getClass().getClassLoader());

        ReferenceConfig<DemoService> referenceConfig2 = new ReferenceConfig<>();
        referenceConfig2.setInterface(class2);
        referenceConfig2.setRegistry(new RegistryConfig(zkUrl1));
        referenceConfig2.setScopeModel(moduleModel);
        referenceConfig2.setScope("remote");
        Object demoService2 = referenceConfig2.get();

        for (Class<?> anInterface : demoService2.getClass().getInterfaces()) {
            Assertions.assertNotEquals(DemoService.class, anInterface);
        }
        Assertions.assertTrue(Arrays.stream(demoService2.getClass().getInterfaces()).anyMatch((clazz) -> clazz.getClassLoader().equals(classLoader2)));

        java.lang.reflect.Method callBean2 = demoService2.getClass().getDeclaredMethod("callInnerClass");
        callBean2.setAccessible(true);
        Object result2 = callBean2.invoke(demoService2);

        Assertions.assertNotEquals(callBean1, callBean2);
        Assertions.assertNotEquals(result2.getClass(), DemoService.InnerClass.class);
        Assertions.assertEquals(classLoader2, result2.getClass().getClassLoader());
        Assertions.assertNotEquals(result1.getClass(), result2.getClass());

        applicationModel.destroy();
        DubboBootstrap.getInstance().destroy();
        Thread.currentThread().setContextClassLoader(classLoader);
        Thread.currentThread().getContextClassLoader().loadClass(DemoService.class.getName());
    }

    @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");
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        TestClassLoader1 classLoader1 = new TestClassLoader1(basePath);
        TestClassLoader1 classLoader2 = new TestClassLoader1(basePath);
        TestClassLoader2 classLoader3 = new TestClassLoader2(classLoader2, basePath);

        ApplicationConfig applicationConfig = new ApplicationConfig("TestApp");
        ApplicationModel applicationModel = new ApplicationModel(FrameworkModel.defaultModel());
        applicationModel.getApplicationConfigManager().setApplication(applicationConfig);
        ModuleModel moduleModel = new ModuleModel(applicationModel);

        Class<?> clazz1 = classLoader1.loadClass(MultiClassLoaderService.class.getName(), false);
        Class<?> clazz1impl = classLoader1.loadClass(MultiClassLoaderServiceImpl.class.getName(), false);
        Class<?> requestClazzCustom1 = compileCustomRequest(classLoader1);
        Class<?> resultClazzCustom1 = compileCustomResult(classLoader1);
        classLoader1.loadedClass.put(requestClazzCustom1.getName(), requestClazzCustom1);
        classLoader1.loadedClass.put(resultClazzCustom1.getName(), resultClazzCustom1);
        AtomicReference innerRequestReference = new AtomicReference();
        AtomicReference innerResultReference = new AtomicReference();
        innerResultReference.set(resultClazzCustom1.newInstance());
        Constructor<?> declaredConstructor = clazz1impl.getDeclaredConstructor(AtomicReference.class, AtomicReference.class);

        ServiceConfig serviceConfig = new ServiceConfig<>();
        serviceConfig.setInterfaceClassLoader(classLoader1);
        serviceConfig.setInterface(clazz1);
        serviceConfig.setRegistry(new RegistryConfig(zkUrl1));
        serviceConfig.setScopeModel(moduleModel);
        serviceConfig.setRef(declaredConstructor.newInstance(innerRequestReference, innerResultReference));
        serviceConfig.export();

        Class<?> clazz2 = classLoader2.loadClass(MultiClassLoaderService.class.getName(), false);
        Class<?> requestClazzOrigin = classLoader2.loadClass(MultiClassLoaderServiceRequest.class.getName(), false);
        Class<?> requestClazzCustom2 = compileCustomRequest(classLoader2);
        Class<?> resultClazzCustom3 = compileCustomResult(classLoader3);
        classLoader2.loadedClass.put(requestClazzCustom2.getName(), requestClazzCustom2);
        classLoader3.loadedClass.put(resultClazzCustom3.getName(), resultClazzCustom3);

        ReferenceConfig<DemoService> referenceConfig1 = new ReferenceConfig<>();
        referenceConfig1.setInterface(clazz2);
        referenceConfig1.setInterfaceClassLoader(classLoader3);
        referenceConfig1.setRegistry(new RegistryConfig(zkUrl1));
        referenceConfig1.setScopeModel(moduleModel);
        referenceConfig1.setScope("remote");
        Object object1 = referenceConfig1.get();

        java.lang.reflect.Method callBean1 = object1.getClass().getDeclaredMethod("call", requestClazzOrigin);
        callBean1.setAccessible(true);
        Object result1 = callBean1.invoke(object1, requestClazzCustom2.newInstance());

        Assertions.assertEquals(resultClazzCustom3, result1.getClass());
        Assertions.assertNotEquals(classLoader2, result1.getClass().getClassLoader());
        Assertions.assertEquals(classLoader1, innerRequestReference.get().getClass().getClassLoader());

        applicationModel.destroy();
        DubboBootstrap.getInstance().destroy();
        Thread.currentThread().setContextClassLoader(classLoader);
        Thread.currentThread().getContextClassLoader().loadClass(DemoService.class.getName());
    }

    private Class<?> compileCustomRequest(ClassLoader classLoader) throws NotFoundException, CannotCompileException {
        CtClassBuilder builder = new CtClassBuilder();
        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());
    }

    private Class<?> compileCustomResult(ClassLoader classLoader) throws NotFoundException, CannotCompileException {
        CtClassBuilder builder = new CtClassBuilder();
        builder.setClassName(MultiClassLoaderServiceResult.class.getName() + "A");
        builder.setSuperClassName(MultiClassLoaderServiceResult.class.getName());
        CtClass cls = builder.build(classLoader);
        return cls.toClass(classLoader, JavassistCompiler.class.getProtectionDomain());
    }

    @Reference(methods = {@Method(name = "sayHello", timeout = 1300, retries = 4, loadbalance = "random", async = true,
        actives = 3, executes = 5, deprecated = true, sticky = true, oninvoke = "instance.i", onthrow = "instance.t", onreturn = "instance.r", cache = "c", validation = "v",
        arguments = {@Argument(index = 24, callback = true, type = "sss")})})
    private InnerTest innerTest;

    private class InnerTest {

    }

    private static class TestClassLoader extends ClassLoader {
        private String basePath;

        public TestClassLoader(ClassLoader parent, String basePath) {
            super(parent);
            this.basePath = basePath;
        }

        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            try {
                byte[] bytes = loadClassData(name);
                return defineClass(name, bytes, 0, bytes.length);
            } catch (Exception e) {
                throw new ClassNotFoundException();
            }
        }

        @Override
        public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
            Class<?> loadedClass = this.findLoadedClass(name);
            if (loadedClass != null) {
                return loadedClass;
            } else {
                try {
                    if (name.equals("org.apache.dubbo.config.api.DemoService") || name.equals("org.apache.dubbo.config.api.DemoService$InnerClass")) {
                        Class<?> aClass = this.findClass(name);
                        if (resolve) {
                            this.resolveClass(aClass);
                        }
                        return aClass;
                    } else {
                        return super.loadClass(name, resolve);
                    }
                } catch (Exception e) {
                    return super.loadClass(name, resolve);
                }
            }
        }


        public byte[] loadClassData(String className) throws IOException {
            className = className.replaceAll("\\.", "/");
            String path = basePath + File.separator + className + ".class";
            FileInputStream fileInputStream;
            byte[] classBytes;
            fileInputStream = new FileInputStream(path);
            int length = fileInputStream.available();
            classBytes = new byte[length];
            fileInputStream.read(classBytes);
            fileInputStream.close();
            return classBytes;
        }
    }

    private static class TestClassLoader1 extends ClassLoader {
        private String basePath;

        public TestClassLoader1(String basePath) {
            this.basePath = basePath;
        }

        Map<String, Class<?>> loadedClass = new ConcurrentHashMap<>();

        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            try {
                byte[] bytes = loadClassData(name);
                return defineClass(name, bytes, 0, bytes.length);
            } catch (Exception e) {
                throw new ClassNotFoundException();
            }
        }

        @Override
        public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
            if (loadedClass.containsKey(name)) {
                return loadedClass.get(name);
            }
            if (name.startsWith("demo")) {
                Class<?> aClass = this.findClass(name);
                this.loadedClass.put(name, aClass);
                if (resolve) {
                    this.resolveClass(aClass);
                }
                return aClass;
            } else {
                Class<?> loadedClass = this.findLoadedClass(name);
                if (loadedClass != null) {
                    return loadedClass;
                } else {
                    return super.loadClass(name, resolve);
                }
            }
        }


        public byte[] loadClassData(String className) throws IOException {
            className = className.replaceAll("\\.", "/");
            String path = basePath + File.separator + className + ".class";
            FileInputStream fileInputStream;
            byte[] classBytes;
            fileInputStream = new FileInputStream(path);
            int length = fileInputStream.available();
            classBytes = new byte[length];
            fileInputStream.read(classBytes);
            fileInputStream.close();
            return classBytes;
        }
    }

    private static class TestClassLoader2 extends ClassLoader {
        private String basePath;
        private TestClassLoader1 testClassLoader;

        Map<String, Class<?>> loadedClass = new ConcurrentHashMap<>();

        public TestClassLoader2(TestClassLoader1 testClassLoader, String basePath) {
            this.testClassLoader = testClassLoader;
            this.basePath = basePath;
        }

        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            try {
                byte[] bytes = loadClassData(name);
                return defineClass(name, bytes, 0, bytes.length);
            } catch (Exception e) {
                throw new ClassNotFoundException();
            }
        }

        @Override
        public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
            if (loadedClass.containsKey(name)) {
                return loadedClass.get(name);
            }
            if (name.startsWith("demo.MultiClassLoaderServiceRe")) {
                Class<?> aClass = this.findClass(name);
                this.loadedClass.put(name, aClass);
                if (resolve) {
                    this.resolveClass(aClass);
                }
                return aClass;
            } else {
                return testClassLoader.loadClass(name, resolve);
            }
        }


        public byte[] loadClassData(String className) throws IOException {
            className = className.replaceAll("\\.", "/");
            String path = basePath + File.separator + className + ".class";
            FileInputStream fileInputStream;
            byte[] classBytes;
            fileInputStream = new FileInputStream(path);
            int length = fileInputStream.available();
            classBytes = new byte[length];
            fileInputStream.read(classBytes);
            fileInputStream.close();
            return classBytes;
        }
    }

}
