You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2021/09/11 13:49:45 UTC
[dubbo-spi-extensions] branch master updated: Extend rpc rmi
service (#41)
This is an automated email from the ASF dual-hosted git repository.
albumenj pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-spi-extensions.git
The following commit(s) were added to refs/heads/master by this push:
new e6a4522 Extend rpc rmi service (#41)
e6a4522 is described below
commit e6a452215f9afbfac017c50c6bb288274cff5e1b
Author: clown <32...@users.noreply.github.com>
AuthorDate: Sat Sep 11 21:49:38 2021 +0800
Extend rpc rmi service (#41)
* no message
* 添加rmi测试
* fix cli build error
* add new line
* disable testRemoteApplicationName()
* resolve conflicts
* resolve conflicts
* fix ci build
* fix ci build
* add http service
---
dubbo-rpc-extensions/{ => dubbo-rpc-rmi}/pom.xml | 39 ++--
.../rpc/protocol/rmi/RmiRemoteInvocation.java | 39 ++++
.../apache/dubbo/rpc/protocol/rmi/RmiProtocol.java | 154 ++++++++++++++
.../rpc/protocol/rmi/RmiRemoteInvocation.java | 64 ++++++
.../dubbo/internal/org.apache.dubbo.rpc.Protocol | 1 +
.../apache/dubbo/rpc/protocol/rmi/DemoService.java | 47 +++++
.../dubbo/rpc/protocol/rmi/DemoServiceImpl.java | 89 ++++++++
.../dubbo/rpc/protocol/rmi/RemoteService.java | 26 +++
.../dubbo/rpc/protocol/rmi/RemoteServiceImpl.java | 32 +++
.../dubbo/rpc/protocol/rmi/RmiProtocolTest.java | 232 +++++++++++++++++++++
.../org/apache/dubbo/rpc/protocol/rmi/Type.java | 21 ++
dubbo-rpc-extensions/pom.xml | 2 +
12 files changed, 730 insertions(+), 16 deletions(-)
diff --git a/dubbo-rpc-extensions/pom.xml b/dubbo-rpc-extensions/dubbo-rpc-rmi/pom.xml
similarity index 51%
copy from dubbo-rpc-extensions/pom.xml
copy to dubbo-rpc-extensions/dubbo-rpc-rmi/pom.xml
index dbfe401..d338835 100644
--- a/dubbo-rpc-extensions/pom.xml
+++ b/dubbo-rpc-extensions/dubbo-rpc-rmi/pom.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@@ -15,24 +14,32 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.dubbo.extensions</groupId>
- <artifactId>extensions-parent</artifactId>
+ <artifactId>dubbo-rpc-extensions</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <packaging>pom</packaging>
-
- <modelVersion>4.0.0</modelVersion>
-
- <artifactId>dubbo-rpc-extensions</artifactId>
-
- <modules>
- <module>dubbo-rpc-native-thrift</module>
- <module>dubbo-rpc-http</module>
- <module>dubbo-rpc-webservice</module>
- </modules>
+ <artifactId>dubbo-rpc-rmi</artifactId>
+ <packaging>jar</packaging>
+ <description>The rmi rpc module of dubbo project</description>
+ <properties>
+ <skip_maven_deploy>false</skip_maven_deploy>
+ </properties>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-rpc-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-cluster</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ </dependency>
+ </dependencies>
</project>
diff --git a/dubbo-rpc-extensions/dubbo-rpc-rmi/src/main/java/com/alibaba/dubbo/rpc/protocol/rmi/RmiRemoteInvocation.java b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/main/java/com/alibaba/dubbo/rpc/protocol/rmi/RmiRemoteInvocation.java
new file mode 100644
index 0000000..22a07b0
--- /dev/null
+++ b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/main/java/com/alibaba/dubbo/rpc/protocol/rmi/RmiRemoteInvocation.java
@@ -0,0 +1,39 @@
+/*
+ * 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 com.alibaba.dubbo.rpc.protocol.rmi;
+
+import org.aopalliance.intercept.MethodInvocation;
+
+/**
+ * This class is deprecated, please use {@link org.apache.dubbo.rpc.protocol.rmi.RmiRemoteInvocation}.
+ *
+ * @author chickenlj
+ * @deprecated
+ */
+@Deprecated
+public class RmiRemoteInvocation extends org.apache.dubbo.rpc.protocol.rmi.RmiRemoteInvocation {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * executed on consumer side
+ *
+ * @param methodInvocation
+ */
+ public RmiRemoteInvocation(MethodInvocation methodInvocation) {
+ super(methodInvocation);
+ }
+}
diff --git a/dubbo-rpc-extensions/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java
new file mode 100644
index 0000000..f08606b
--- /dev/null
+++ b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java
@@ -0,0 +1,154 @@
+/*
+ * 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.rpc.protocol.rmi;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;
+import org.apache.dubbo.rpc.service.GenericService;
+import org.apache.dubbo.rpc.support.ProtocolUtils;
+
+import org.springframework.remoting.RemoteAccessException;
+import org.springframework.remoting.rmi.RmiProxyFactoryBean;
+import org.springframework.remoting.rmi.RmiServiceExporter;
+import org.springframework.remoting.support.RemoteInvocation;
+
+import java.io.IOException;
+import java.net.SocketTimeoutException;
+import java.rmi.RemoteException;
+
+import static org.apache.dubbo.common.Version.isRelease263OrHigher;
+import static org.apache.dubbo.common.Version.isRelease270OrHigher;
+import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+
+/**
+ * RmiProtocol.
+ */
+public class RmiProtocol extends AbstractProxyProtocol{
+
+ public static final int DEFAULT_PORT = 1099;
+
+ public RmiProtocol() {
+ super(RemoteAccessException.class, RemoteException.class);
+ }
+
+ @Override
+ public int getDefaultPort() {
+ return DEFAULT_PORT;
+ }
+
+ @Override
+ protected <T> Runnable doExport(final T impl, Class<T> type, URL url) throws RpcException {
+ RmiServiceExporter rmiServiceExporter = createExporter(impl, type, url, false);
+ RmiServiceExporter genericServiceExporter = createExporter(impl, GenericService.class, url, true);
+ return new Runnable() {
+ @Override
+ public void run() {
+ try {
+ rmiServiceExporter.destroy();
+ genericServiceExporter.destroy();
+ } catch (Throwable e) {
+ logger.warn(e.getMessage(), e);
+ }
+ }
+ };
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcException {
+ final RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
+ final String generic = url.getParameter(GENERIC_KEY);
+ final boolean isGeneric = ProtocolUtils.isGeneric(generic) || serviceType.equals(GenericService.class);
+ /*
+ RMI needs extra parameter since it uses customized remote invocation object
+
+ The customized RemoteInvocation was firstly introduced in v2.6.3; The package was renamed to 'org.apache.*' since v2.7.0
+ Considering the above two conditions, we need to check before sending customized RemoteInvocation:
+ 1. if the provider version is v2.7.0 or higher, send 'org.apache.dubbo.rpc.protocol.rmi.RmiRemoteInvocation'.
+ 2. if the provider version is v2.6.3 or higher, send 'com.alibaba.dubbo.rpc.protocol.rmi.RmiRemoteInvocation'.
+ 3. if the provider version is lower than v2.6.3, does not use customized RemoteInvocation.
+ */
+ if (isRelease270OrHigher(url.getParameter(RELEASE_KEY))) {
+ rmiProxyFactoryBean.setRemoteInvocationFactory(methodInvocation -> {
+ RemoteInvocation invocation = new RmiRemoteInvocation(methodInvocation);
+ if (isGeneric) {
+ invocation.addAttribute(GENERIC_KEY, generic);
+ }
+ return invocation;
+ });
+ } else if (isRelease263OrHigher(url.getParameter(DUBBO_VERSION_KEY))) {
+ rmiProxyFactoryBean.setRemoteInvocationFactory(methodInvocation -> {
+ RemoteInvocation invocation = new com.alibaba.dubbo.rpc.protocol.rmi.RmiRemoteInvocation(methodInvocation);
+ if (isGeneric) {
+ invocation.addAttribute(GENERIC_KEY, generic);
+ }
+ return invocation;
+ });
+ }
+ String serviceUrl = url.toIdentityString();
+ if (isGeneric) {
+ serviceUrl = serviceUrl + "/" + GENERIC_KEY;
+ }
+ rmiProxyFactoryBean.setServiceUrl(serviceUrl);
+ rmiProxyFactoryBean.setServiceInterface(serviceType);
+ rmiProxyFactoryBean.setCacheStub(true);
+ rmiProxyFactoryBean.setLookupStubOnStartup(true);
+ rmiProxyFactoryBean.setRefreshStubOnConnectFailure(true);
+ rmiProxyFactoryBean.afterPropertiesSet();
+ return (T) rmiProxyFactoryBean.getObject();
+ }
+
+ @Override
+ protected int getErrorCode(Throwable e) {
+ if (e instanceof RemoteAccessException) {
+ e = e.getCause();
+ }
+ if (e != null && e.getCause() != null) {
+ Class<?> cls = e.getCause().getClass();
+ if (SocketTimeoutException.class.equals(cls)) {
+ return RpcException.TIMEOUT_EXCEPTION;
+ } else if (IOException.class.isAssignableFrom(cls)) {
+ return RpcException.NETWORK_EXCEPTION;
+ } else if (ClassNotFoundException.class.isAssignableFrom(cls)) {
+ return RpcException.SERIALIZATION_EXCEPTION;
+ }
+ }
+ return super.getErrorCode(e);
+ }
+
+ private <T> RmiServiceExporter createExporter(T impl, Class<?> type, URL url, boolean isGeneric) {
+ final RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();
+ rmiServiceExporter.setRegistryPort(url.getPort());
+ if (isGeneric) {
+ rmiServiceExporter.setServiceName(url.getPath() + "/" + GENERIC_KEY);
+ } else {
+ rmiServiceExporter.setServiceName(url.getPath());
+ }
+ rmiServiceExporter.setServiceInterface(type);
+ rmiServiceExporter.setService(impl);
+ try {
+ rmiServiceExporter.afterPropertiesSet();
+ } catch (RemoteException e) {
+ throw new RpcException(e.getMessage(), e);
+ }
+ return rmiServiceExporter;
+ }
+
+}
diff --git a/dubbo-rpc-extensions/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiRemoteInvocation.java b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiRemoteInvocation.java
new file mode 100644
index 0000000..729d695
--- /dev/null
+++ b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiRemoteInvocation.java
@@ -0,0 +1,64 @@
+/*
+ * 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.rpc.protocol.rmi;
+
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.rpc.RpcContext;
+
+import org.aopalliance.intercept.MethodInvocation;
+import org.springframework.remoting.support.RemoteInvocation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
+
+public class RmiRemoteInvocation extends RemoteInvocation {
+ private static final long serialVersionUID = 1L;
+ private static final String DUBBO_ATTACHMENTS_ATTR_NAME = "dubbo.attachments";
+
+ /**
+ * executed on consumer side
+ */
+ public RmiRemoteInvocation(MethodInvocation methodInvocation) {
+ super(methodInvocation);
+ addAttribute(DUBBO_ATTACHMENTS_ATTR_NAME, new HashMap<>(RpcContext.getContext().getObjectAttachments()));
+ }
+
+ /**
+ * Need to restore context on provider side (Though context will be overridden by Invocation's attachment
+ * when ContextFilter gets executed, we will restore the attachment when Invocation is constructed, check more
+ * from {@link org.apache.dubbo.rpc.proxy.InvokerInvocationHandler}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public Object invoke(Object targetObject) throws NoSuchMethodException, IllegalAccessException,
+ InvocationTargetException {
+ RpcContext context = RpcContext.getContext();
+ context.setObjectAttachments((Map<String, Object>) getAttribute(DUBBO_ATTACHMENTS_ATTR_NAME));
+ String generic = (String) getAttribute(GENERIC_KEY);
+ if (StringUtils.isNotEmpty(generic)) {
+ context.setAttachment(GENERIC_KEY, generic);
+ }
+ try {
+ return super.invoke(targetObject);
+ } finally {
+ context.setObjectAttachments(null);
+ }
+ }
+}
diff --git a/dubbo-rpc-extensions/dubbo-rpc-rmi/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol
new file mode 100644
index 0000000..a1e30e3
--- /dev/null
+++ b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol
@@ -0,0 +1 @@
+rmi=org.apache.dubbo.rpc.protocol.rmi.RmiProtocol
\ No newline at end of file
diff --git a/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/DemoService.java b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/DemoService.java
new file mode 100644
index 0000000..ca0a089
--- /dev/null
+++ b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/DemoService.java
@@ -0,0 +1,47 @@
+/*
+ * 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.rpc.protocol.rmi;
+
+/**
+ * <code>TestService</code>
+ */
+
+public interface DemoService {
+ void sayHello(String name);
+
+ String sayHi(String name);
+
+ String echo(String text);
+
+ long timestamp();
+
+ void throwTimeout();
+
+ String getThreadName();
+
+ int getSize(String[] strs);
+
+ int getSize(Object[] os);
+
+ Object invoke(String service, String method) throws Exception;
+
+ int stringLength(String str);
+
+ Type enumlength(Type... types);
+
+ String getRemoteApplicationName();
+}
\ No newline at end of file
diff --git a/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/DemoServiceImpl.java b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/DemoServiceImpl.java
new file mode 100644
index 0000000..15fe72e
--- /dev/null
+++ b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/DemoServiceImpl.java
@@ -0,0 +1,89 @@
+/*
+ * 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.rpc.protocol.rmi;
+
+import org.apache.dubbo.rpc.RpcContext;
+
+/**
+ * DemoServiceImpl
+ */
+
+public class DemoServiceImpl implements DemoService {
+ public DemoServiceImpl() {
+ super();
+ }
+
+ public void sayHello(String name) {
+ System.out.println("hello " + name);
+ }
+
+ public String sayHi(String name) {
+ return "Hi, " + name;
+ }
+
+ public String echo(String text) {
+ return text;
+ }
+
+ public long timestamp() {
+ return System.currentTimeMillis();
+ }
+
+ public String getThreadName() {
+ return Thread.currentThread().getName();
+ }
+
+ public int getSize(String[] strs) {
+ if (strs == null)
+ return -1;
+ return strs.length;
+ }
+
+ public int getSize(Object[] os) {
+ if (os == null)
+ return -1;
+ return os.length;
+ }
+
+ public Object invoke(String service, String method) throws Exception {
+ System.out.println("RpcContext.getContext().getRemoteHost()=" + RpcContext.getContext().getRemoteHost());
+ return service + ":" + method;
+ }
+
+ public Type enumlength(Type... types) {
+ if (types.length == 0)
+ return Type.Lower;
+ return types[0];
+ }
+
+ public int stringLength(String str) {
+ return str.length();
+ }
+
+ public void throwTimeout() {
+ try {
+ Thread.sleep(6000);
+ } catch (InterruptedException e) {
+ }
+ }
+
+
+ @Override
+ public String getRemoteApplicationName() {
+ return RpcContext.getContext().getRemoteApplicationName();
+ }
+}
diff --git a/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/RemoteService.java b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/RemoteService.java
new file mode 100644
index 0000000..1b1da9a
--- /dev/null
+++ b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/RemoteService.java
@@ -0,0 +1,26 @@
+/*
+ * 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.rpc.protocol.rmi;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+public interface RemoteService extends Remote {
+ String sayHello(String name) throws RemoteException;
+
+ String getThreadName() throws RemoteException;
+}
\ No newline at end of file
diff --git a/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/RemoteServiceImpl.java b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/RemoteServiceImpl.java
new file mode 100644
index 0000000..3de0ab7
--- /dev/null
+++ b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/RemoteServiceImpl.java
@@ -0,0 +1,32 @@
+/*
+ * 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.rpc.protocol.rmi;
+
+import org.apache.dubbo.rpc.RpcContext;
+
+import java.rmi.RemoteException;
+
+public class RemoteServiceImpl implements RemoteService {
+ public String getThreadName() throws RemoteException {
+ System.out.println("RpcContext.getContext().getRemoteHost()=" + RpcContext.getContext().getRemoteHost());
+ return Thread.currentThread().getName();
+ }
+
+ public String sayHello(String name) throws RemoteException {
+ return "hello " + name + "@" + RemoteServiceImpl.class.getName();
+ }
+}
\ No newline at end of file
diff --git a/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocolTest.java b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocolTest.java
new file mode 100644
index 0000000..dd4d11e
--- /dev/null
+++ b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocolTest.java
@@ -0,0 +1,232 @@
+/*
+ * 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.rpc.protocol.rmi;
+
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.ProxyFactory;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.service.EchoService;
+import org.apache.dubbo.rpc.service.GenericService;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@Disabled(value = "Disable for Github Actions Environment Issue")
+public class RmiProtocolTest {
+ private Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ private ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+
+ /*
+ @Test
+ public void test_getRemoteClass() throws Exception {
+ Class<NonStdRmiInterface> clazz = RmiProtocol.getRemoteClass(NonStdRmiInterface.class);
+ assertEquals(clazz, RmiProtocol.getRemoteClass(NonStdRmiInterface.class));
+ }
+ */
+ @Test
+ public void testRmiProtocolTimeout() throws Exception {
+ int availablePort = NetUtils.getAvailablePort();
+ System.setProperty("sun.rmi.transport.tcp.responseTimeout", "1000");
+ DemoService service = new DemoServiceImpl();
+ Exporter<?> rpcExporter = protocol.export(proxy.getInvoker(service, DemoService.class, URL.valueOf("rmi://127.0.0.1:" + availablePort + "/TestService")));
+ service = proxy.getProxy(protocol.refer(DemoService.class, URL.valueOf("rmi://127.0.0.1:" + availablePort + "/TestService")));
+ try {
+ try {
+ service.throwTimeout();
+ } catch (RpcException e) {
+ assertTrue(e.isTimeout());
+ assertTrue(e.getMessage().contains("Read timed out"));
+ }
+ } finally {
+ rpcExporter.unexport();
+ }
+ }
+
+ @Test
+ public void testRmiProtocol() throws Exception {
+ {
+ int availablePort = NetUtils.getAvailablePort();
+ DemoService service = new DemoServiceImpl();
+ Exporter<?> rpcExporter = protocol.export(proxy.getInvoker(service, DemoService.class, URL.valueOf("rmi://127.0.0.1:" + availablePort + "/TestService")));
+
+ service = proxy.getProxy(protocol.refer(DemoService.class, URL.valueOf("rmi://127.0.0.1:" + availablePort + "/TestService")));
+ assertEquals(service.getSize(null), -1);
+ assertEquals(service.getSize(new String[]{"", "", ""}), 3);
+ Object result = service.invoke("rmi://127.0.0.1:" + availablePort + "/TestService", "invoke");
+ assertEquals("rmi://127.0.0.1:" + availablePort + "/TestService:invoke", result);
+
+ rpcExporter.unexport();
+ }
+
+ {
+ int port = NetUtils.getAvailablePort();
+ RemoteService remoteService = new RemoteServiceImpl();
+ Exporter<?> rpcExporter = protocol.export(proxy.getInvoker(remoteService, RemoteService.class, URL.valueOf("rmi://127.0.0.1:" + port + "/remoteService")));
+
+ remoteService = proxy.getProxy(protocol.refer(RemoteService.class, URL.valueOf("rmi://127.0.0.1:" + port + "/remoteService")));
+ remoteService.getThreadName();
+ for (int i = 0; i < 100; i++) {
+ String say = remoteService.sayHello("abcd");
+ assertEquals("hello abcd@" + RemoteServiceImpl.class.getName(), say);
+ }
+ rpcExporter.unexport();
+ }
+ }
+
+ // FIXME RMI protocol doesn't support casting to EchoService yet.
+ @Disabled
+ @Test
+ public void testRmiProtocol_echoService() throws Exception {
+ int availablePort = NetUtils.getAvailablePort();
+ DemoService service = new DemoServiceImpl();
+ Exporter<?> rpcExporter = protocol.export(proxy.getInvoker(service, DemoService.class, URL.valueOf("rmi://127.0.0.1:" + availablePort + "/TestService")));
+
+ // cast to EchoService
+ EchoService echo = proxy.getProxy(protocol.refer(EchoService.class, URL.valueOf("rmi://127.0.0.1:" + availablePort + "/TestService")));
+ assertEquals(echo.$echo("test"), "test");
+ assertEquals(echo.$echo("abcdefg"), "abcdefg");
+ assertEquals(echo.$echo(1234), 1234);
+
+ rpcExporter.unexport();
+
+ availablePort = NetUtils.getAvailablePort();
+ RemoteService remoteService = new RemoteServiceImpl();
+ rpcExporter = protocol.export(proxy.getInvoker(remoteService, RemoteService.class, URL.valueOf("rmi://127.0.0.1:" + availablePort + "/remoteService")));
+
+ // cast to EchoService
+ echo = proxy.getProxy(protocol.refer(EchoService.class, URL.valueOf("rmi://127.0.0.1:" + availablePort + "/remoteService")));
+ assertEquals(echo.$echo("test"), "test");
+ assertEquals(echo.$echo("abcdefg"), "abcdefg");
+ assertEquals(echo.$echo(1234), 1234);
+
+ rpcExporter.unexport();
+ }
+
+ @Test
+ public void testGenericInvoke() {
+ int availablePort = NetUtils.getAvailablePort();
+ DemoService service = new DemoServiceImpl();
+ URL url = URL.valueOf("rmi://127.0.0.1:" + availablePort + "/" + DemoService.class.getName() + "?release=2.7.0");
+ Exporter<DemoService> exporter = protocol.export(proxy.getInvoker(service, DemoService.class, url));
+ Invoker<GenericService> invoker = protocol.refer(GenericService.class, url);
+ GenericService client = proxy.getProxy(invoker, true);
+ String result = (String) client.$invoke("sayHi", new String[]{"java.lang.String"}, new Object[]{"haha"});
+ Assertions.assertEquals("Hi, haha", result);
+ invoker.destroy();
+ exporter.unexport();
+ }
+
+ @Disabled
+ @Test
+ public void testRemoteApplicationName() throws Exception {
+ int availablePort = NetUtils.getAvailablePort();
+ DemoService service = new DemoServiceImpl();
+ URL url = URL.valueOf("rmi://127.0.0.1:" + availablePort + "/TestService?release=2.7.0").addParameter("application", "consumer");
+ Exporter<?> rpcExporter = protocol.export(proxy.getInvoker(service, DemoService.class, url));
+
+ service = proxy.getProxy(protocol.refer(DemoService.class, url));
+ assertEquals(service.getRemoteApplicationName(), "consumer");
+
+ rpcExporter.unexport();
+ }
+
+ public interface NonStdRmiInterface {
+ void bark();
+ }
+
+ /*@Test
+ public void testRpcInvokerGroup() throws Exception
+ {
+ DemoService service = new DemoServiceImpl();
+ RpcUtils.export("demo://127.0.0.1:9030/org.apache.dubbo.rpc.TestService",DemoService.class,service);
+ RpcUtils.export("dubbo://127.0.0.1:9031/TestService",DemoService.class,service);
+ RpcUtils.export("rmi://127.0.0.1:9032/org.apache.dubbo.rpc.TestService",DemoService.class,service);
+ RpcUtils.export("rmi://127.0.0.1:9033/org.apache.dubbo.rpc.TestService",DemoService.class,service);
+
+ service = RpcUtils.createProxy(DemoService.class,
+ new String[]{
+ "demo://127.0.0.1:9030/org.apache.dubbo.rpc.TestService?weight=20",
+ "dubbo://127.0.0.1:9031/TestService?weight=20",
+ "rmi://127.0.0.1:9032/org.apache.dubbo.rpc.TestService",
+ });
+ assertEquals(service.getSize(null), -1);
+ assertEquals(service.getSize(new String[]{"","",""}), 3);
+
+ // cast to EchoService
+ EchoService echo = RpcUtils.createProxy(EchoService.class,
+ new String[]{
+ "demo://127.0.0.1:9030/org.apache.dubbo.rpc.TestService?weight=20",
+ "dubbo://127.0.0.1:9031/TestService?weight=20",
+ "rmi://127.0.0.1:9032/org.apache.dubbo.rpc.TestService",
+ });
+ assertEquals(echo.$echo("test"), "test");
+ assertEquals(echo.$echo("abcdefg"), "abcdefg");
+ assertEquals(echo.$echo(1234), 1234);
+ }*/
+
+ /*public void testForkInvoke() throws Exception
+ {
+ DemoService service = new DemoServiceImpl();
+ protocol.export(proxy.createInvoker("dubbo://127.0.0.1:9040/TestService", DemoService.class, service);
+ protocol.export(proxy.createInvoker("dubbo://127.0.0.1:9041/TestService", DemoService.class, service);
+ protocol.export(proxy.createInvoker("rmi://127.0.0.1:9042/org.apache.dubbo.rpc.TestService", DemoService.class, service);
+ protocol.export(proxy.createInvoker("rmi://127.0.0.1:9043/org.apache.dubbo.rpc.TestService", DemoService.class, service);
+
+ RpcInvokerGroup group = Proxies.createInvoker(DemoService.class, new String[]{
+ "dubbo://127.0.0.1:9040/TestService",
+ "dubbo://127.0.0.1:9041/TestService",
+ "rmi://127.0.0.1:9042/org.apache.dubbo.rpc.TestService",
+ "rmi://127.0.0.1:9043/org.apache.dubbo.rpc.TestService",
+ });
+ group.getMethodSettings("echo").setFork(true);
+ group.getMethodSettings("echo").setForkInvokeCallback(new ForkInvokeCallback(){
+ public Object merge(RpcInvocation invocation, RpcResult[] results) throws Throwable
+ {
+ System.out.println("merge result begin:");
+ for( RpcResult result : results )
+ {
+ if( result.hasException() )
+ System.out.println("exception:"+result.getException().getMessage());
+ else
+ System.out.println("result:"+result.getResult());
+ }
+ System.out.println("merge result end:");
+ return "aaaa";
+ }
+ });
+
+ service = proxy.createProxy(protocol.refer(DemoService.class, group);
+ service.echo("test");
+
+ // cast to EchoService
+ EchoService echo = proxy.createProxy(protocol.refer(EchoService.class, group);
+ assertEquals(echo.$echo("test"), "test");
+ assertEquals(echo.$echo("abcdefg"), "abcdefg");
+ assertEquals(echo.$echo(1234), 1234);
+ }*/
+
+}
diff --git a/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/Type.java b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/Type.java
new file mode 100644
index 0000000..222d9d1
--- /dev/null
+++ b/dubbo-rpc-extensions/dubbo-rpc-rmi/src/test/java/org/apache/dubbo/rpc/protocol/rmi/Type.java
@@ -0,0 +1,21 @@
+/*
+ * 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.rpc.protocol.rmi;
+
+public enum Type {
+ High, Normal, Lower
+}
\ No newline at end of file
diff --git a/dubbo-rpc-extensions/pom.xml b/dubbo-rpc-extensions/pom.xml
index dbfe401..11f796a 100644
--- a/dubbo-rpc-extensions/pom.xml
+++ b/dubbo-rpc-extensions/pom.xml
@@ -34,5 +34,7 @@
<module>dubbo-rpc-native-thrift</module>
<module>dubbo-rpc-http</module>
<module>dubbo-rpc-webservice</module>
+ <module>dubbo-rpc-rmi</module>
</modules>
+
</project>