mirror of
https://github.com/ReaJason/MemShellParty.git
synced 2026-09-21 22:50:42 +08:00
test: add dubbo integration-test
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
plugins {
|
||||
id("java")
|
||||
id("idea")
|
||||
}
|
||||
|
||||
group = "io.github.reajason"
|
||||
version = rootProject.version
|
||||
|
||||
val dubboProviderCommon: SourceSet by sourceSets.creating
|
||||
val dubboProviderAlibaba: SourceSet by sourceSets.creating
|
||||
val dubboProviderApache276: SourceSet by sourceSets.creating
|
||||
val dubboProviderApache277: SourceSet by sourceSets.creating
|
||||
val dubboProviderApache278: SourceSet by sourceSets.creating
|
||||
val dubboProviderApache2723: SourceSet by sourceSets.creating
|
||||
val dubboProviderApache336: SourceSet by sourceSets.creating
|
||||
|
||||
val dubboProviderCommonImplementation: Configuration by configurations.getting
|
||||
val dubboProviderAlibabaImplementation: Configuration by configurations.getting
|
||||
val dubboProviderApache276Implementation: Configuration by configurations.getting
|
||||
val dubboProviderApache277Implementation: Configuration by configurations.getting
|
||||
val dubboProviderApache278Implementation: Configuration by configurations.getting
|
||||
val dubboProviderApache2723Implementation: Configuration by configurations.getting
|
||||
val dubboProviderApache336Implementation: Configuration by configurations.getting
|
||||
|
||||
val dubboProviderCommonOutput = dubboProviderCommon.output
|
||||
|
||||
dubboProviderAlibaba.compileClasspath += dubboProviderCommonOutput
|
||||
dubboProviderAlibaba.runtimeClasspath += dubboProviderCommonOutput
|
||||
dubboProviderApache276.compileClasspath += dubboProviderCommonOutput
|
||||
dubboProviderApache276.runtimeClasspath += dubboProviderCommonOutput
|
||||
dubboProviderApache277.compileClasspath += dubboProviderCommonOutput
|
||||
dubboProviderApache277.runtimeClasspath += dubboProviderCommonOutput
|
||||
dubboProviderApache278.compileClasspath += dubboProviderCommonOutput
|
||||
dubboProviderApache278.runtimeClasspath += dubboProviderCommonOutput
|
||||
dubboProviderApache2723.compileClasspath += dubboProviderCommonOutput
|
||||
dubboProviderApache2723.runtimeClasspath += dubboProviderCommonOutput
|
||||
dubboProviderApache336.compileClasspath += dubboProviderCommonOutput
|
||||
dubboProviderApache336.runtimeClasspath += dubboProviderCommonOutput
|
||||
|
||||
listOf(
|
||||
"dubboProviderApache336CompileClasspath",
|
||||
"dubboProviderApache336RuntimeClasspath"
|
||||
).forEach { configurationName ->
|
||||
configurations.named(configurationName) {
|
||||
exclude(group = "io.netty", module = "netty-transport-native-kqueue")
|
||||
exclude(group = "io.netty", module = "netty-resolver-dns-native-macos")
|
||||
}
|
||||
}
|
||||
|
||||
idea {
|
||||
module {
|
||||
excludeDirs.add(file("src/main"))
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
dubboProviderCommonImplementation("org.slf4j:slf4j-api:1.7.36")
|
||||
dubboProviderCommonImplementation("org.apache.dubbo:dubbo:2.7.23") {
|
||||
exclude(group = "log4j", module = "log4j")
|
||||
}
|
||||
|
||||
dubboProviderAlibabaImplementation(dubboProviderCommonOutput)
|
||||
dubboProviderAlibabaImplementation("com.alibaba:dubbo:2.6.12")
|
||||
dubboProviderAlibabaImplementation("org.apache.dubbo:dubbo:2.7.6")
|
||||
dubboProviderAlibabaImplementation("com.alibaba:hessian-lite:3.2.4")
|
||||
dubboProviderAlibabaImplementation("com.caucho:hessian:4.0.51")
|
||||
dubboProviderAlibabaImplementation("org.apache.httpcomponents:httpclient:4.5.3")
|
||||
dubboProviderAlibabaImplementation("org.springframework:spring-web:5.3.39")
|
||||
dubboProviderAlibabaImplementation("io.netty:netty-all:4.1.25.Final")
|
||||
dubboProviderAlibabaImplementation("org.mortbay.jetty:jetty:6.1.26")
|
||||
dubboProviderAlibabaImplementation("org.mortbay.jetty:jetty-util:6.1.26")
|
||||
dubboProviderAlibabaImplementation("org.slf4j:slf4j-api:1.7.36")
|
||||
dubboProviderAlibabaImplementation("ch.qos.logback:logback-classic:1.2.13")
|
||||
|
||||
fun apacheDubbo27Provider(configuration: Configuration, version: String, tomcatVersion: String) {
|
||||
add(configuration.name, dubboProviderCommonOutput)
|
||||
add(configuration.name, "org.apache.dubbo:dubbo:$version") {
|
||||
exclude(group = "log4j", module = "log4j")
|
||||
}
|
||||
add(configuration.name, "com.alibaba:hessian-lite:3.2.4")
|
||||
add(configuration.name, "com.caucho:hessian:4.0.51")
|
||||
add(configuration.name, "org.apache.httpcomponents:httpclient:4.5.13")
|
||||
add(configuration.name, "com.github.briandilley.jsonrpc4j:jsonrpc4j:1.2.0")
|
||||
add(configuration.name, "org.springframework:spring-web:5.3.39")
|
||||
add(configuration.name, "org.apache.tomcat.embed:tomcat-embed-core:$tomcatVersion")
|
||||
add(configuration.name, "org.mortbay.jetty:jetty:6.1.26")
|
||||
add(configuration.name, "org.mortbay.jetty:jetty-util:6.1.26")
|
||||
add(configuration.name, "org.slf4j:slf4j-api:1.7.36")
|
||||
add(configuration.name, "ch.qos.logback:logback-classic:1.2.13")
|
||||
}
|
||||
|
||||
apacheDubbo27Provider(dubboProviderApache276Implementation, "2.7.6", "8.5.100")
|
||||
apacheDubbo27Provider(dubboProviderApache277Implementation, "2.7.7", "8.5.100")
|
||||
apacheDubbo27Provider(dubboProviderApache278Implementation, "2.7.8", "9.0.104")
|
||||
apacheDubbo27Provider(dubboProviderApache2723Implementation, "2.7.23", "9.0.104")
|
||||
|
||||
dubboProviderApache336Implementation(dubboProviderCommonOutput)
|
||||
dubboProviderApache336Implementation("org.apache.dubbo:dubbo:3.3.6") {
|
||||
exclude(group = "log4j", module = "log4j")
|
||||
}
|
||||
dubboProviderApache336Implementation("org.apache.dubbo:dubbo-rpc-triple:3.3.6")
|
||||
dubboProviderApache336Implementation("org.apache.dubbo.extensions:dubbo-rpc-http:3.3.1")
|
||||
dubboProviderApache336Implementation("org.apache.dubbo.extensions:dubbo-rpc-hessian:3.3.0")
|
||||
dubboProviderApache336Implementation("org.apache.dubbo:dubbo-remoting-http:3.3.0-beta.2")
|
||||
dubboProviderApache336Implementation("com.caucho:hessian:4.0.51")
|
||||
dubboProviderApache336Implementation("io.netty:netty-all:4.1.119.Final")
|
||||
dubboProviderApache336Implementation("org.slf4j:slf4j-api:2.0.17")
|
||||
dubboProviderApache336Implementation("ch.qos.logback:logback-classic:1.5.18")
|
||||
}
|
||||
|
||||
tasks.named<JavaCompile>(dubboProviderCommon.compileJavaTaskName) {
|
||||
options.release.set(8)
|
||||
}
|
||||
|
||||
listOf(
|
||||
dubboProviderAlibaba,
|
||||
dubboProviderApache276,
|
||||
dubboProviderApache277,
|
||||
dubboProviderApache278,
|
||||
dubboProviderApache2723,
|
||||
dubboProviderApache336
|
||||
).forEach { sourceSet ->
|
||||
tasks.named<JavaCompile>(sourceSet.compileJavaTaskName) {
|
||||
options.release.set(8)
|
||||
}
|
||||
}
|
||||
|
||||
fun registerDubboFatJar(
|
||||
taskName: String,
|
||||
sourceSet: SourceSet,
|
||||
mainClassName: String,
|
||||
mergeApacheProtocolSpi: Boolean = false
|
||||
): TaskProvider<Jar> {
|
||||
val protocolSpiPath = "META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol"
|
||||
val mergedProtocolSpi = layout.buildDirectory.file("generated/$taskName/$protocolSpiPath")
|
||||
val mergeTask = if (mergeApacheProtocolSpi) {
|
||||
tasks.register("${taskName}MergeProtocolSpi") {
|
||||
inputs.files(sourceSet.runtimeClasspath)
|
||||
outputs.file(mergedProtocolSpi)
|
||||
doLast {
|
||||
val outputFile = mergedProtocolSpi.get().asFile
|
||||
outputFile.parentFile.mkdirs()
|
||||
val mergedLines = linkedSetOf<String>()
|
||||
sourceSet.runtimeClasspath.files
|
||||
.filter { it.extension == "jar" }
|
||||
.forEach { runtimeJar ->
|
||||
zipTree(runtimeJar).matching {
|
||||
include(protocolSpiPath)
|
||||
}.forEach { spiFile ->
|
||||
spiFile.readLines()
|
||||
.map(String::trim)
|
||||
.filter { it.isNotEmpty() && !it.startsWith("#") }
|
||||
.forEach(mergedLines::add)
|
||||
}
|
||||
}
|
||||
outputFile.writeText(mergedLines.joinToString(System.lineSeparator()))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
return tasks.register<Jar>(taskName) {
|
||||
group = "verification"
|
||||
archiveClassifier.set(taskName.removePrefix("dubbo").removeSuffix("FatJar").lowercase())
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
dependsOn(sourceSet.classesTaskName, dubboProviderCommon.classesTaskName)
|
||||
manifest {
|
||||
attributes["Main-Class"] = mainClassName
|
||||
}
|
||||
from(sourceSet.output)
|
||||
from(dubboProviderCommon.output)
|
||||
if (mergeApacheProtocolSpi) {
|
||||
dependsOn(mergeTask)
|
||||
from({
|
||||
sourceSet.runtimeClasspath.files
|
||||
.filter { it.exists() }
|
||||
.map { if (it.isDirectory) it else zipTree(it) }
|
||||
}) {
|
||||
includeEmptyDirs = false
|
||||
exclude(protocolSpiPath)
|
||||
}
|
||||
into("META-INF/dubbo/internal") {
|
||||
from(mergedProtocolSpi) {
|
||||
rename { "org.apache.dubbo.rpc.Protocol" }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
from({
|
||||
sourceSet.runtimeClasspath.files
|
||||
.filter { it.exists() }
|
||||
.map { if (it.isDirectory) it else zipTree(it) }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val dubboAlibabaProviderFatJar = registerDubboFatJar(
|
||||
"dubboAlibabaProviderFatJar",
|
||||
dubboProviderAlibaba,
|
||||
"io.github.reajason.dubbo.fixture.alibaba.AlibabaDubbo2Provider"
|
||||
)
|
||||
val dubboApache276ProviderFatJar = registerDubboFatJar(
|
||||
"dubboApache276ProviderFatJar",
|
||||
dubboProviderApache276,
|
||||
"io.github.reajason.dubbo.fixture.apache2.ApacheDubbo276Provider"
|
||||
)
|
||||
val dubboApache277ProviderFatJar = registerDubboFatJar(
|
||||
"dubboApache277ProviderFatJar",
|
||||
dubboProviderApache277,
|
||||
"io.github.reajason.dubbo.fixture.apache2.ApacheDubbo277Provider"
|
||||
)
|
||||
val dubboApache278ProviderFatJar = registerDubboFatJar(
|
||||
"dubboApache278ProviderFatJar",
|
||||
dubboProviderApache278,
|
||||
"io.github.reajason.dubbo.fixture.apache2.ApacheDubbo278Provider"
|
||||
)
|
||||
val dubboApache2723ProviderFatJar = registerDubboFatJar(
|
||||
"dubboApache2723ProviderFatJar",
|
||||
dubboProviderApache2723,
|
||||
"io.github.reajason.dubbo.fixture.apache2.ApacheDubbo2723Provider"
|
||||
)
|
||||
val dubboApache336ProviderFatJar = registerDubboFatJar(
|
||||
"dubboApache336ProviderFatJar",
|
||||
dubboProviderApache336,
|
||||
"io.github.reajason.dubbo.fixture.apache3.ApacheDubbo336Provider",
|
||||
mergeApacheProtocolSpi = true
|
||||
)
|
||||
|
||||
tasks.register("dubboProviderFatJars") {
|
||||
group = "verification"
|
||||
dependsOn(
|
||||
dubboAlibabaProviderFatJar,
|
||||
dubboApache276ProviderFatJar,
|
||||
dubboApache277ProviderFatJar,
|
||||
dubboApache278ProviderFatJar,
|
||||
dubboApache2723ProviderFatJar,
|
||||
dubboApache336ProviderFatJar
|
||||
)
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package io.github.reajason.dubbo.fixture.alibaba;
|
||||
|
||||
import com.alibaba.dubbo.config.ApplicationConfig;
|
||||
import com.alibaba.dubbo.config.ProtocolConfig;
|
||||
import com.alibaba.dubbo.config.RegistryConfig;
|
||||
import com.alibaba.dubbo.config.ServiceConfig;
|
||||
import io.github.reajason.dubbo.fixture.api.BytecodeLoadingService;
|
||||
import io.github.reajason.dubbo.fixture.api.DemoService;
|
||||
import io.github.reajason.dubbo.fixture.common.BytecodeLoadingServiceImpl;
|
||||
import io.github.reajason.dubbo.fixture.common.DemoServiceImpl;
|
||||
import io.github.reajason.dubbo.fixture.common.LoadBytesExportContext;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class AlibabaDubbo2Provider {
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
System.setProperty("dubbo.compiler", "jdk");
|
||||
ApplicationConfig application = new ApplicationConfig("alibaba-dubbo2-provider");
|
||||
application.setQosEnable(true);
|
||||
application.setQosPort(22221);
|
||||
|
||||
ProtocolConfig dubboProtocol = new ProtocolConfig();
|
||||
dubboProtocol.setName("dubbo");
|
||||
dubboProtocol.setPort(20880);
|
||||
|
||||
ProtocolConfig hessianProtocol = new ProtocolConfig();
|
||||
hessianProtocol.setName("hessian");
|
||||
hessianProtocol.setPort(28080);
|
||||
|
||||
ProtocolConfig httpProtocol = new ProtocolConfig();
|
||||
httpProtocol.setName("http");
|
||||
httpProtocol.setPort(28081);
|
||||
|
||||
RegistryConfig registry = new RegistryConfig("N/A");
|
||||
LoadBytesExportContext.register(application, registry, Arrays.asList(dubboProtocol, hessianProtocol, httpProtocol));
|
||||
|
||||
ServiceConfig<DemoService> demoService = new ServiceConfig<DemoService>();
|
||||
demoService.setApplication(application);
|
||||
demoService.setRegistry(registry);
|
||||
demoService.setProtocols(Arrays.asList(dubboProtocol, hessianProtocol, httpProtocol));
|
||||
demoService.setInterface(DemoService.class);
|
||||
demoService.setRef(new DemoServiceImpl("alibaba-dubbo-2.6.12"));
|
||||
demoService.export();
|
||||
|
||||
ServiceConfig<BytecodeLoadingService> loaderService = new ServiceConfig<BytecodeLoadingService>();
|
||||
loaderService.setApplication(application);
|
||||
loaderService.setRegistry(registry);
|
||||
loaderService.setProtocols(Arrays.asList(dubboProtocol, hessianProtocol, httpProtocol));
|
||||
loaderService.setInterface(BytecodeLoadingService.class);
|
||||
loaderService.setRef(new BytecodeLoadingServiceImpl());
|
||||
loaderService.export();
|
||||
|
||||
System.out.println("==============================================");
|
||||
System.out.println(" alibaba-dubbo 2.6.12 Provider started");
|
||||
System.out.println(" dubbo -> dubbo://127.0.0.1:20880");
|
||||
System.out.println(" hessian -> hessian://127.0.0.1:28080");
|
||||
System.out.println(" http -> http://127.0.0.1:28081");
|
||||
System.out.println(" qos -> 127.0.0.1:22221");
|
||||
System.out.println("==============================================");
|
||||
|
||||
new CountDownLatch(1).await();
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package io.github.reajason.dubbo.fixture.apache2;
|
||||
|
||||
public class ApacheDubbo2723Provider {
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
ApacheDubbo2Provider.start("apache-dubbo-2.7.23", 20881, 28082, 28083, 22222);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package io.github.reajason.dubbo.fixture.apache2;
|
||||
|
||||
public class ApacheDubbo276Provider {
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
ApacheDubbo2Provider.start("apache-dubbo-2.7.6", 20885, 28086, 28087, 22226);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package io.github.reajason.dubbo.fixture.apache2;
|
||||
|
||||
public class ApacheDubbo277Provider {
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
ApacheDubbo2Provider.start("apache-dubbo-2.7.7", 20886, 28088, 28089, 22227);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package io.github.reajason.dubbo.fixture.apache2;
|
||||
|
||||
public class ApacheDubbo278Provider {
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
ApacheDubbo2Provider.start("apache-dubbo-2.7.8", 20887, 28090, 28091, 22228);
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package io.github.reajason.dubbo.fixture.apache3;
|
||||
|
||||
import io.github.reajason.dubbo.fixture.api.BytecodeLoadingService;
|
||||
import io.github.reajason.dubbo.fixture.api.DemoService;
|
||||
import io.github.reajason.dubbo.fixture.common.BytecodeLoadingServiceImpl;
|
||||
import io.github.reajason.dubbo.fixture.common.DemoServiceImpl;
|
||||
import io.github.reajason.dubbo.fixture.common.LoadBytesExportContext;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ProtocolConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ApacheDubbo336Provider {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("dubbo.compiler", "jdk");
|
||||
ApplicationConfig application = new ApplicationConfig("apache-dubbo-3.3.6-provider");
|
||||
application.setQosEnable(true);
|
||||
application.setQosPort(22223);
|
||||
|
||||
RegistryConfig registry = new RegistryConfig("N/A");
|
||||
ProtocolConfig dubboProtocol = new ProtocolConfig("dubbo", 20882);
|
||||
ProtocolConfig triProtocol = new ProtocolConfig("tri", 50051);
|
||||
ProtocolConfig hessianProtocol = new ProtocolConfig("hessian", 28084);
|
||||
ProtocolConfig httpProtocol = new ProtocolConfig("http", 28085);
|
||||
LoadBytesExportContext.register(
|
||||
application,
|
||||
registry,
|
||||
Arrays.asList(dubboProtocol, triProtocol, hessianProtocol, httpProtocol)
|
||||
);
|
||||
|
||||
ServiceConfig<DemoService> demoService = new ServiceConfig<DemoService>();
|
||||
demoService.setInterface(DemoService.class);
|
||||
demoService.setRef(new DemoServiceImpl("apache-dubbo-3.3.6"));
|
||||
|
||||
ServiceConfig<BytecodeLoadingService> loaderService = new ServiceConfig<BytecodeLoadingService>();
|
||||
loaderService.setInterface(BytecodeLoadingService.class);
|
||||
loaderService.setRef(new BytecodeLoadingServiceImpl());
|
||||
|
||||
DubboBootstrap.getInstance()
|
||||
.application(application)
|
||||
.registry(registry)
|
||||
.protocol(dubboProtocol)
|
||||
.protocol(triProtocol)
|
||||
.protocol(hessianProtocol)
|
||||
.protocol(httpProtocol)
|
||||
.service(demoService)
|
||||
.service(loaderService)
|
||||
.start();
|
||||
|
||||
System.out.println("==============================================");
|
||||
System.out.println(" apache-dubbo-3.3.6 Provider started");
|
||||
System.out.println(" dubbo -> dubbo://127.0.0.1:20882");
|
||||
System.out.println(" tri -> tri://127.0.0.1:50051");
|
||||
System.out.println(" hessian -> hessian://127.0.0.1:28084");
|
||||
System.out.println(" http -> http://127.0.0.1:28085");
|
||||
System.out.println(" qos -> 127.0.0.1:22223");
|
||||
System.out.println("==============================================");
|
||||
|
||||
DubboBootstrap.getInstance().await();
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package io.github.reajason.dubbo.fixture.apache2;
|
||||
|
||||
import io.github.reajason.dubbo.fixture.api.BytecodeLoadingService;
|
||||
import io.github.reajason.dubbo.fixture.api.DemoService;
|
||||
import io.github.reajason.dubbo.fixture.common.BytecodeLoadingServiceImpl;
|
||||
import io.github.reajason.dubbo.fixture.common.DemoServiceImpl;
|
||||
import io.github.reajason.dubbo.fixture.common.LoadBytesExportContext;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.config.ProtocolConfig;
|
||||
import org.apache.dubbo.config.RegistryConfig;
|
||||
import org.apache.dubbo.config.ServiceConfig;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public final class ApacheDubbo2Provider {
|
||||
|
||||
private ApacheDubbo2Provider() {
|
||||
}
|
||||
|
||||
public static void start(String providerName, int dubboPort, int hessianPort, int httpPort, int qosPort)
|
||||
throws InterruptedException {
|
||||
System.setProperty("dubbo.compiler", "jdk");
|
||||
ApplicationConfig application = new ApplicationConfig(providerName + "-provider");
|
||||
application.setQosEnable(true);
|
||||
application.setQosPort(qosPort);
|
||||
|
||||
ProtocolConfig dubboProtocol = new ProtocolConfig();
|
||||
dubboProtocol.setName("dubbo");
|
||||
dubboProtocol.setPort(dubboPort);
|
||||
|
||||
ProtocolConfig hessianProtocol = new ProtocolConfig();
|
||||
hessianProtocol.setName("hessian");
|
||||
hessianProtocol.setPort(hessianPort);
|
||||
hessianProtocol.setServer("tomcat");
|
||||
|
||||
ProtocolConfig httpProtocol = new ProtocolConfig();
|
||||
httpProtocol.setName("http");
|
||||
httpProtocol.setPort(httpPort);
|
||||
httpProtocol.setServer("tomcat");
|
||||
|
||||
RegistryConfig registry = new RegistryConfig("N/A");
|
||||
LoadBytesExportContext.register(application, registry, Arrays.asList(dubboProtocol, hessianProtocol, httpProtocol));
|
||||
|
||||
ServiceConfig<DemoService> demoService = new ServiceConfig<DemoService>();
|
||||
demoService.setApplication(application);
|
||||
demoService.setRegistry(registry);
|
||||
demoService.setProtocols(Arrays.asList(dubboProtocol, hessianProtocol, httpProtocol));
|
||||
demoService.setInterface(DemoService.class);
|
||||
demoService.setRef(new DemoServiceImpl(providerName));
|
||||
demoService.export();
|
||||
|
||||
ServiceConfig<BytecodeLoadingService> loaderService = new ServiceConfig<BytecodeLoadingService>();
|
||||
loaderService.setApplication(application);
|
||||
loaderService.setRegistry(registry);
|
||||
loaderService.setProtocols(Arrays.asList(dubboProtocol, hessianProtocol, httpProtocol));
|
||||
loaderService.setInterface(BytecodeLoadingService.class);
|
||||
loaderService.setRef(new BytecodeLoadingServiceImpl());
|
||||
loaderService.export();
|
||||
|
||||
System.out.println("==============================================");
|
||||
System.out.println(" " + providerName + " Provider started");
|
||||
System.out.println(" dubbo -> dubbo://127.0.0.1:" + dubboPort);
|
||||
System.out.println(" hessian -> hessian://127.0.0.1:" + hessianPort);
|
||||
System.out.println(" http -> http://127.0.0.1:" + httpPort);
|
||||
System.out.println(" qos -> 127.0.0.1:" + qosPort);
|
||||
System.out.println("==============================================");
|
||||
|
||||
new CountDownLatch(1).await();
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package io.github.reajason.dubbo.fixture.api;
|
||||
|
||||
public interface BytecodeLoadingService {
|
||||
String loadBytes(String base64);
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package io.github.reajason.dubbo.fixture.api;
|
||||
|
||||
public interface DemoService {
|
||||
String sayHello(String name);
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package io.github.reajason.dubbo.fixture.common;
|
||||
|
||||
import io.github.reajason.dubbo.fixture.api.BytecodeLoadingService;
|
||||
|
||||
public class BytecodeLoadingServiceImpl implements BytecodeLoadingService {
|
||||
|
||||
@Override
|
||||
public String loadBytes(String base64) {
|
||||
return BytecodeLoadingSupport.loadBase64(base64);
|
||||
}
|
||||
}
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
package io.github.reajason.dubbo.fixture.common;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
public final class BytecodeLoadingSupport {
|
||||
|
||||
private BytecodeLoadingSupport() {
|
||||
}
|
||||
|
||||
public static String loadBase64(String base64) {
|
||||
String normalized = normalizeBase64(base64);
|
||||
byte[] bytes = Base64.getMimeDecoder().decode(normalized);
|
||||
return loadClassBytes(bytes);
|
||||
}
|
||||
|
||||
public static String loadClassBytes(byte[] bytes) {
|
||||
requireClassBytes(bytes);
|
||||
try {
|
||||
return new PayloadClassLoader(hostClassLoader()).defineAndInstantiate(bytes);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new IllegalStateException("failed to load bytecode payload", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String normalizeBase64(String base64) {
|
||||
if (base64 == null) {
|
||||
throw new IllegalArgumentException("base64 must not be null");
|
||||
}
|
||||
String trimmed = base64.trim();
|
||||
if (trimmed.isEmpty()) {
|
||||
throw new IllegalArgumentException("base64 must not be blank");
|
||||
}
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
private static void requireClassBytes(byte[] bytes) {
|
||||
if (bytes == null || bytes.length == 0) {
|
||||
throw new IllegalArgumentException("class bytes must not be empty");
|
||||
}
|
||||
}
|
||||
|
||||
private static ClassLoader hostClassLoader() {
|
||||
ClassLoader classLoader = BytecodeLoadingSupport.class.getClassLoader();
|
||||
if (classLoader == null) {
|
||||
classLoader = Thread.currentThread().getContextClassLoader();
|
||||
}
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
public static Class<?> defineIntoHostClassLoader(String className, byte[] bytes) {
|
||||
if (className == null || className.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("class name must not be blank");
|
||||
}
|
||||
requireClassBytes(bytes);
|
||||
|
||||
ClassLoader classLoader = hostClassLoader();
|
||||
Class<?> loadedClass = findLoadedClass(className, classLoader);
|
||||
if (loadedClass != null) {
|
||||
return loadedClass;
|
||||
}
|
||||
|
||||
try {
|
||||
return defineClass(className, bytes, classLoader);
|
||||
} catch (LinkageError e) {
|
||||
loadedClass = findLoadedClass(className, classLoader);
|
||||
if (loadedClass != null) {
|
||||
return loadedClass;
|
||||
}
|
||||
throw e;
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new IllegalStateException("failed to define class in host class loader: " + className, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerWithDubboClassPool(String className, byte[] bytes) {
|
||||
if (className == null || className.trim().isEmpty() || bytes == null || bytes.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Class<?> classPoolClass = null;
|
||||
List<Object> classPools = new ArrayList<Object>();
|
||||
try {
|
||||
classPoolClass = Class.forName("javassist.ClassPool", false, hostClassLoader());
|
||||
classPools.add(classPoolClass.getMethod("getDefault").invoke(null));
|
||||
classPools.addAll(dubboClassGeneratorPools());
|
||||
|
||||
for (Object classPool : classPools) {
|
||||
if (classPoolContains(classPoolClass, classPool, className)) {
|
||||
continue;
|
||||
}
|
||||
Method makeClass = classPoolClass.getMethod("makeClass", InputStream.class);
|
||||
makeClass.invoke(classPool, new ByteArrayInputStream(bytes));
|
||||
}
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
// Javassist is not present for all clients.
|
||||
} catch (InvocationTargetException e) {
|
||||
if (classPoolClass != null && anyClassPoolContains(classPoolClass, classPools, className)) {
|
||||
return;
|
||||
}
|
||||
throw new IllegalStateException("failed to register class with Dubbo Javassist pool: " + className, e.getCause());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new IllegalStateException("failed to register class with Dubbo Javassist pool: " + className, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static Class<?> findLoadedClass(String className, ClassLoader classLoader) {
|
||||
try {
|
||||
return Class.forName(className, false, classLoader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Class<?> defineClass(String className, byte[] bytes, ClassLoader classLoader)
|
||||
throws ReflectiveOperationException {
|
||||
Method defineClass = ClassLoader.class.getDeclaredMethod(
|
||||
"defineClass",
|
||||
String.class,
|
||||
byte[].class,
|
||||
int.class,
|
||||
int.class,
|
||||
ProtectionDomain.class
|
||||
);
|
||||
defineClass.setAccessible(true);
|
||||
try {
|
||||
return (Class<?>) defineClass.invoke(
|
||||
classLoader,
|
||||
className,
|
||||
bytes,
|
||||
0,
|
||||
bytes.length,
|
||||
BytecodeLoadingSupport.class.getProtectionDomain()
|
||||
);
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof LinkageError) {
|
||||
throw (LinkageError) cause;
|
||||
}
|
||||
if (cause instanceof RuntimeException) {
|
||||
throw (RuntimeException) cause;
|
||||
}
|
||||
if (cause instanceof Error) {
|
||||
throw (Error) cause;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Object> dubboClassGeneratorPools() {
|
||||
List<Object> classPools = new ArrayList<Object>();
|
||||
List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
|
||||
addClassLoader(classLoaders, hostClassLoader());
|
||||
addClassLoader(classLoaders, Thread.currentThread().getContextClassLoader());
|
||||
|
||||
for (ClassLoader classLoader : classLoaders) {
|
||||
addDubboClassGeneratorPool(classPools, "com.alibaba.dubbo.common.bytecode.ClassGenerator", classLoader);
|
||||
addDubboClassGeneratorPool(classPools, "org.apache.dubbo.common.bytecode.ClassGenerator", classLoader);
|
||||
}
|
||||
return classPools;
|
||||
}
|
||||
|
||||
private static void addClassLoader(List<ClassLoader> classLoaders, ClassLoader classLoader) {
|
||||
if (classLoader != null && !classLoaders.contains(classLoader)) {
|
||||
classLoaders.add(classLoader);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addDubboClassGeneratorPool(List<Object> classPools, String className, ClassLoader classLoader) {
|
||||
try {
|
||||
Class<?> classGeneratorClass = Class.forName(className, false, hostClassLoader());
|
||||
Method getClassPool = classGeneratorClass.getMethod("getClassPool", ClassLoader.class);
|
||||
Object classPool = getClassPool.invoke(null, classLoader);
|
||||
if (classPool != null && !classPools.contains(classPool)) {
|
||||
classPools.add(classPool);
|
||||
}
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
// This runtime is using the other Dubbo namespace.
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new IllegalStateException("failed to resolve Dubbo class pool from " + className, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean anyClassPoolContains(Class<?> classPoolClass, List<Object> classPools, String className) {
|
||||
for (Object classPool : classPools) {
|
||||
try {
|
||||
if (classPoolContains(classPoolClass, classPool, className)) {
|
||||
return true;
|
||||
}
|
||||
} catch (ReflectiveOperationException ignored) {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean classPoolContains(Class<?> classPoolClass, Object classPool, String className)
|
||||
throws ReflectiveOperationException {
|
||||
try {
|
||||
Method getOrNull = classPoolClass.getMethod("getOrNull", String.class);
|
||||
return getOrNull.invoke(classPool, className) != null;
|
||||
} catch (NoSuchMethodException e) {
|
||||
try {
|
||||
Method get = classPoolClass.getMethod("get", String.class);
|
||||
return get.invoke(classPool, className) != null;
|
||||
} catch (InvocationTargetException invocationTargetException) {
|
||||
Throwable cause = invocationTargetException.getCause();
|
||||
if (cause != null && "javassist.NotFoundException".equals(cause.getClass().getName())) {
|
||||
return false;
|
||||
}
|
||||
throw invocationTargetException;
|
||||
}
|
||||
} catch (InvocationTargetException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause != null && "javassist.NotFoundException".equals(cause.getClass().getName())) {
|
||||
return false;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class PayloadClassLoader extends ClassLoader {
|
||||
|
||||
private PayloadClassLoader(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
private String defineAndInstantiate(byte[] bytes) throws ReflectiveOperationException {
|
||||
Thread thread = Thread.currentThread();
|
||||
ClassLoader original = thread.getContextClassLoader();
|
||||
thread.setContextClassLoader(this);
|
||||
try {
|
||||
Object instance = defineClass(bytes, 0, bytes.length).newInstance();
|
||||
return String.valueOf(instance);
|
||||
} finally {
|
||||
thread.setContextClassLoader(original);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package io.github.reajason.dubbo.fixture.common;
|
||||
|
||||
import io.github.reajason.dubbo.fixture.api.DemoService;
|
||||
|
||||
public class DemoServiceImpl implements DemoService {
|
||||
|
||||
private final String providerName;
|
||||
|
||||
public DemoServiceImpl(String providerName) {
|
||||
this.providerName = providerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sayHello(String name) {
|
||||
return "Hello, " + name + " from " + providerName;
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package io.github.reajason.dubbo.fixture.common;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class LoadBytesExportContext {
|
||||
|
||||
private static volatile Object application;
|
||||
private static volatile Object registry;
|
||||
private static volatile List<?> protocols;
|
||||
|
||||
private LoadBytesExportContext() {
|
||||
}
|
||||
|
||||
public static void register(Object applicationConfig, Object registryConfig, List<?> protocolConfigs) {
|
||||
application = applicationConfig;
|
||||
registry = registryConfig;
|
||||
protocols = protocolConfigs;
|
||||
}
|
||||
|
||||
public static Object application() {
|
||||
return application;
|
||||
}
|
||||
|
||||
public static Object registry() {
|
||||
return registry;
|
||||
}
|
||||
|
||||
public static List<?> protocols() {
|
||||
return protocols;
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package io.github.reajason.dubbo.fixture.common;
|
||||
|
||||
public final class Noop {
|
||||
private Noop() {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user