diff --git a/spring-context/src/main/java/org/springframework/remoting/RemoteAccessException.java b/spring-context/src/main/java/org/springframework/remoting/RemoteAccessException.java
deleted file mode 100644
index 0d6cde82e5..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/RemoteAccessException.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting;
-
-import org.springframework.core.NestedRuntimeException;
-
-/**
- * Generic remote access exception. A service proxy for any remoting
- * protocol should throw this exception or subclasses of it, in order
- * to transparently expose a plain Java business interface.
- *
- *
When using conforming proxies, switching the actual remoting protocol
- * e.g. from Hessian does not affect client code. Clients work with a plain
- * natural Java business interface that the service exposes. A client object
- * simply receives an implementation for the interface that it needs via a
- * bean reference, like it does for a local bean as well.
- *
- *
A client may catch RemoteAccessException if it wants to, but as
- * remote access errors are typically unrecoverable, it will probably let
- * such exceptions propagate to a higher level that handles them generically.
- * In this case, the client code doesn't show any signs of being involved in
- * remote access, as there aren't any remoting-specific dependencies.
- *
- *
Even when switching from a remote service proxy to a local implementation
- * of the same interface, this amounts to just a matter of configuration. Obviously,
- * the client code should be somewhat aware that it might be working
- * against a remote service, for example in terms of repeated method calls that
- * cause unnecessary roundtrips etc. However, it doesn't have to be aware whether
- * it is actually working against a remote service or a local implementation,
- * or with which remoting protocol it is working under the hood.
- *
- * @author Juergen Hoeller
- * @since 14.05.2003
- */
-public class RemoteAccessException extends NestedRuntimeException {
-
- /** Use serialVersionUID from Spring 1.2 for interoperability. */
- private static final long serialVersionUID = -4906825139312227864L;
-
-
- /**
- * Constructor for RemoteAccessException.
- * @param msg the detail message
- */
- public RemoteAccessException(String msg) {
- super(msg);
- }
-
- /**
- * Constructor for RemoteAccessException.
- * @param msg the detail message
- * @param cause the root cause (usually from using an underlying
- * remoting API such as RMI)
- */
- public RemoteAccessException(String msg, Throwable cause) {
- super(msg, cause);
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/RemoteConnectFailureException.java b/spring-context/src/main/java/org/springframework/remoting/RemoteConnectFailureException.java
deleted file mode 100644
index 99857c3694..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/RemoteConnectFailureException.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting;
-
-/**
- * RemoteAccessException subclass to be thrown when no connection
- * could be established with a remote service.
- *
- * @author Juergen Hoeller
- * @since 1.1
- */
-@SuppressWarnings("serial")
-public class RemoteConnectFailureException extends RemoteAccessException {
-
- /**
- * Constructor for RemoteConnectFailureException.
- * @param msg the detail message
- * @param cause the root cause from the remoting API in use
- */
- public RemoteConnectFailureException(String msg, Throwable cause) {
- super(msg, cause);
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/RemoteInvocationFailureException.java b/spring-context/src/main/java/org/springframework/remoting/RemoteInvocationFailureException.java
deleted file mode 100644
index 40e9521399..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/RemoteInvocationFailureException.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting;
-
-/**
- * RemoteAccessException subclass to be thrown when the execution
- * of the target method failed on the server side, for example
- * when a method was not found on the target object.
- *
- * @author Juergen Hoeller
- * @since 2.5
- * @see RemoteProxyFailureException
- */
-@SuppressWarnings("serial")
-public class RemoteInvocationFailureException extends RemoteAccessException {
-
- /**
- * Constructor for RemoteInvocationFailureException.
- * @param msg the detail message
- * @param cause the root cause from the remoting API in use
- */
- public RemoteInvocationFailureException(String msg, Throwable cause) {
- super(msg, cause);
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/RemoteLookupFailureException.java b/spring-context/src/main/java/org/springframework/remoting/RemoteLookupFailureException.java
deleted file mode 100644
index ee0e9fa042..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/RemoteLookupFailureException.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting;
-
-/**
- * RemoteAccessException subclass to be thrown in case of a lookup failure,
- * typically if the lookup happens on demand for each method invocation.
- *
- * @author Juergen Hoeller
- * @since 1.1
- */
-@SuppressWarnings("serial")
-public class RemoteLookupFailureException extends RemoteAccessException {
-
- /**
- * Constructor for RemoteLookupFailureException.
- * @param msg the detail message
- */
- public RemoteLookupFailureException(String msg) {
- super(msg);
- }
-
- /**
- * Constructor for RemoteLookupFailureException.
- * @param msg message
- * @param cause the root cause from the remoting API in use
- */
- public RemoteLookupFailureException(String msg, Throwable cause) {
- super(msg, cause);
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/RemoteProxyFailureException.java b/spring-context/src/main/java/org/springframework/remoting/RemoteProxyFailureException.java
deleted file mode 100644
index ce36152f4c..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/RemoteProxyFailureException.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting;
-
-/**
- * RemoteAccessException subclass to be thrown in case of a failure
- * within the client-side proxy for a remote service, for example
- * when a method was not found on the underlying RMI stub.
- *
- * @author Juergen Hoeller
- * @since 1.2.8
- * @see RemoteInvocationFailureException
- */
-@SuppressWarnings("serial")
-public class RemoteProxyFailureException extends RemoteAccessException {
-
- /**
- * Constructor for RemoteProxyFailureException.
- * @param msg the detail message
- * @param cause the root cause from the remoting API in use
- */
- public RemoteProxyFailureException(String msg, Throwable cause) {
- super(msg, cause);
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/RemoteTimeoutException.java b/spring-context/src/main/java/org/springframework/remoting/RemoteTimeoutException.java
deleted file mode 100644
index 8dbff587c6..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/RemoteTimeoutException.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2002-2015 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting;
-
-/**
- * RemoteAccessException subclass to be thrown when the execution
- * of the target method did not complete before a configurable
- * timeout, for example when a reply message was not received.
- * @author Stephane Nicoll
- * @since 4.2
- */
-@SuppressWarnings("serial")
-public class RemoteTimeoutException extends RemoteAccessException {
-
- /**
- * Constructor for RemoteTimeoutException.
- * @param msg the detail message
- */
- public RemoteTimeoutException(String msg) {
- super(msg);
- }
-
- /**
- * Constructor for RemoteTimeoutException.
- * @param msg the detail message
- * @param cause the root cause from the remoting API in use
- */
- public RemoteTimeoutException(String msg, Throwable cause) {
- super(msg, cause);
- }
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/package-info.java b/spring-context/src/main/java/org/springframework/remoting/package-info.java
deleted file mode 100644
index a4b3e95f5d..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/package-info.java
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Exception hierarchy for Spring's remoting infrastructure,
- * independent of any specific remote method invocation system.
- */
-@NonNullApi
-@NonNullFields
-package org.springframework.remoting;
-
-import org.springframework.lang.NonNullApi;
-import org.springframework.lang.NonNullFields;
diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/CodebaseAwareObjectInputStream.java b/spring-context/src/main/java/org/springframework/remoting/rmi/CodebaseAwareObjectInputStream.java
deleted file mode 100644
index 9c897b8a76..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/rmi/CodebaseAwareObjectInputStream.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.rmi;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.rmi.server.RMIClassLoader;
-
-import org.springframework.core.ConfigurableObjectInputStream;
-import org.springframework.lang.Nullable;
-
-/**
- * Special ObjectInputStream subclass that falls back to a specified codebase
- * to load classes from if not found locally. In contrast to standard RMI
- * conventions for dynamic class download, it is the client that determines
- * the codebase URL here, rather than the "java.rmi.server.codebase" system
- * property on the server.
- *
- *
Uses the JDK's RMIClassLoader to load classes from the specified codebase.
- * The codebase can consist of multiple URLs, separated by spaces.
- * Note that RMIClassLoader requires a SecurityManager to be set, like when
- * using dynamic class download with standard RMI! (See the RMI documentation
- * for details.)
- *
- *
Thanks to Lionel Mestre for suggesting the option and providing
- * a prototype!
- *
- * @author Juergen Hoeller
- * @since 1.1.3
- * @see java.rmi.server.RMIClassLoader
- * @see RemoteInvocationSerializingExporter#createObjectInputStream
- * @see org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor#setCodebaseUrl
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class CodebaseAwareObjectInputStream extends ConfigurableObjectInputStream {
-
- private final String codebaseUrl;
-
-
- /**
- * Create a new CodebaseAwareObjectInputStream for the given InputStream and codebase.
- * @param in the InputStream to read from
- * @param codebaseUrl the codebase URL to load classes from if not found locally
- * (can consist of multiple URLs, separated by spaces)
- * @see java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream)
- */
- public CodebaseAwareObjectInputStream(InputStream in, String codebaseUrl) throws IOException {
- this(in, null, codebaseUrl);
- }
-
- /**
- * Create a new CodebaseAwareObjectInputStream for the given InputStream and codebase.
- * @param in the InputStream to read from
- * @param classLoader the ClassLoader to use for loading local classes
- * (may be {@code null} to indicate RMI's default ClassLoader)
- * @param codebaseUrl the codebase URL to load classes from if not found locally
- * (can consist of multiple URLs, separated by spaces)
- * @see java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream)
- */
- public CodebaseAwareObjectInputStream(
- InputStream in, @Nullable ClassLoader classLoader, String codebaseUrl) throws IOException {
-
- super(in, classLoader);
- this.codebaseUrl = codebaseUrl;
- }
-
- /**
- * Create a new CodebaseAwareObjectInputStream for the given InputStream and codebase.
- * @param in the InputStream to read from
- * @param classLoader the ClassLoader to use for loading local classes
- * (may be {@code null} to indicate RMI's default ClassLoader)
- * @param acceptProxyClasses whether to accept deserialization of proxy classes
- * (may be deactivated as a security measure)
- * @see java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream)
- */
- public CodebaseAwareObjectInputStream(
- InputStream in, @Nullable ClassLoader classLoader, boolean acceptProxyClasses) throws IOException {
-
- super(in, classLoader, acceptProxyClasses);
- this.codebaseUrl = null;
- }
-
-
- @Override
- protected Class> resolveFallbackIfPossible(String className, ClassNotFoundException ex)
- throws IOException, ClassNotFoundException {
-
- // If codebaseUrl is set, try to load the class with the RMIClassLoader.
- // Else, propagate the ClassNotFoundException.
- if (this.codebaseUrl == null) {
- throw ex;
- }
- return RMIClassLoader.loadClass(this.codebaseUrl, className);
- }
-
- @Override
- protected ClassLoader getFallbackClassLoader() throws IOException {
- return RMIClassLoader.getClassLoader(this.codebaseUrl);
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiClientInterceptor.java b/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiClientInterceptor.java
deleted file mode 100644
index d90dd6a1a3..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiClientInterceptor.java
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * Copyright 2002-2020 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.rmi;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.rmi.RemoteException;
-
-import javax.naming.Context;
-import javax.naming.NamingException;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-
-import org.springframework.aop.support.AopUtils;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.jndi.JndiObjectLocator;
-import org.springframework.lang.Nullable;
-import org.springframework.remoting.RemoteConnectFailureException;
-import org.springframework.remoting.RemoteInvocationFailureException;
-import org.springframework.remoting.RemoteLookupFailureException;
-import org.springframework.remoting.support.DefaultRemoteInvocationFactory;
-import org.springframework.remoting.support.RemoteInvocation;
-import org.springframework.remoting.support.RemoteInvocationFactory;
-import org.springframework.util.Assert;
-
-/**
- * {@link org.aopalliance.intercept.MethodInterceptor} for accessing RMI services
- * from JNDI. Typically used for RMI-IIOP but can also be used for EJB home objects
- * (for example, a Stateful Session Bean home). In contrast to a plain JNDI lookup,
- * this accessor also performs narrowing through PortableRemoteObject.
- *
- *
With conventional RMI services, this invoker is typically used with the RMI
- * service interface. Alternatively, this invoker can also proxy a remote RMI service
- * with a matching non-RMI business interface, i.e. an interface that mirrors the RMI
- * service methods but does not declare RemoteExceptions. In the latter case,
- * RemoteExceptions thrown by the RMI stub will automatically get converted to
- * Spring's unchecked RemoteAccessException.
- *
- *
The JNDI environment can be specified as "jndiEnvironment" property,
- * or be configured in a {@code jndi.properties} file or as system properties.
- * For example:
- *
- *
Typically required to be able to create a suitable service proxy,
- * but can also be optional if the lookup returns a typed stub.
- */
- public void setServiceInterface(Class> serviceInterface) {
- Assert.notNull(serviceInterface, "'serviceInterface' must not be null");
- Assert.isTrue(serviceInterface.isInterface(), "'serviceInterface' must be an interface");
- this.serviceInterface = serviceInterface;
- }
-
- /**
- * Return the interface of the service to access.
- */
- public Class> getServiceInterface() {
- return this.serviceInterface;
- }
-
- /**
- * Set the RemoteInvocationFactory to use for this accessor.
- * Default is a {@link DefaultRemoteInvocationFactory}.
- *
A custom invocation factory can add further context information
- * to the invocation, for example user credentials.
- */
- public void setRemoteInvocationFactory(RemoteInvocationFactory remoteInvocationFactory) {
- this.remoteInvocationFactory = remoteInvocationFactory;
- }
-
- /**
- * Return the RemoteInvocationFactory used by this accessor.
- */
- public RemoteInvocationFactory getRemoteInvocationFactory() {
- return this.remoteInvocationFactory;
- }
-
- /**
- * Set whether to look up the RMI stub on startup. Default is "true".
- *
Can be turned off to allow for late start of the RMI server.
- * In this case, the RMI stub will be fetched on first access.
- * @see #setCacheStub
- */
- public void setLookupStubOnStartup(boolean lookupStubOnStartup) {
- this.lookupStubOnStartup = lookupStubOnStartup;
- }
-
- /**
- * Set whether to cache the RMI stub once it has been located.
- * Default is "true".
- *
Can be turned off to allow for hot restart of the RMI server.
- * In this case, the RMI stub will be fetched for each invocation.
- * @see #setLookupStubOnStartup
- */
- public void setCacheStub(boolean cacheStub) {
- this.cacheStub = cacheStub;
- }
-
- /**
- * Set whether to refresh the RMI stub on connect failure.
- * Default is "false".
- *
Can be turned on to allow for hot restart of the RMI server.
- * If a cached RMI stub throws an RMI exception that indicates a
- * remote connect failure, a fresh proxy will be fetched and the
- * invocation will be retried.
- * @see java.rmi.ConnectException
- * @see java.rmi.ConnectIOException
- * @see java.rmi.NoSuchObjectException
- */
- public void setRefreshStubOnConnectFailure(boolean refreshStubOnConnectFailure) {
- this.refreshStubOnConnectFailure = refreshStubOnConnectFailure;
- }
-
- /**
- * Set whether to expose the JNDI environment context for all access to the target
- * RMI stub, i.e. for all method invocations on the exposed object reference.
- *
Default is "false", i.e. to only expose the JNDI context for object lookup.
- * Switch this flag to "true" in order to expose the JNDI environment (including
- * the authorization context) for each RMI invocation, as needed by WebLogic
- * for RMI stubs with authorization requirements.
- */
- public void setExposeAccessContext(boolean exposeAccessContext) {
- this.exposeAccessContext = exposeAccessContext;
- }
-
-
- @Override
- public void afterPropertiesSet() throws NamingException {
- super.afterPropertiesSet();
- prepare();
- }
-
- /**
- * Fetches the RMI stub on startup, if necessary.
- * @throws RemoteLookupFailureException if RMI stub creation failed
- * @see #setLookupStubOnStartup
- * @see #lookupStub
- */
- public void prepare() throws RemoteLookupFailureException {
- // Cache RMI stub on initialization?
- if (this.lookupStubOnStartup) {
- Object remoteObj = lookupStub();
- if (logger.isDebugEnabled()) {
- if (remoteObj instanceof RmiInvocationHandler) {
- logger.debug("JNDI RMI object [" + getJndiName() + "] is an RMI invoker");
- }
- else if (getServiceInterface() != null) {
- boolean isImpl = getServiceInterface().isInstance(remoteObj);
- logger.debug("Using service interface [" + getServiceInterface().getName() +
- "] for JNDI RMI object [" + getJndiName() + "] - " +
- (!isImpl ? "not " : "") + "directly implemented");
- }
- }
- if (this.cacheStub) {
- this.cachedStub = remoteObj;
- }
- }
- }
-
- /**
- * Create the RMI stub, typically by looking it up.
- *
Called on interceptor initialization if "cacheStub" is "true";
- * else called for each invocation by {@link #getStub()}.
- *
The default implementation retrieves the service from the
- * JNDI environment. This can be overridden in subclasses.
- * @return the RMI stub to store in this interceptor
- * @throws RemoteLookupFailureException if RMI stub creation failed
- * @see #setCacheStub
- * @see #lookup
- */
- protected Object lookupStub() throws RemoteLookupFailureException {
- try {
- return lookup();
- }
- catch (NamingException ex) {
- throw new RemoteLookupFailureException("JNDI lookup for RMI service [" + getJndiName() + "] failed", ex);
- }
- }
-
- /**
- * Return the RMI stub to use. Called for each invocation.
- *
The default implementation returns the stub created on initialization,
- * if any. Else, it invokes {@link #lookupStub} to get a new stub for
- * each invocation. This can be overridden in subclasses, for example in
- * order to cache a stub for a given amount of time before recreating it,
- * or to test the stub whether it is still alive.
- * @return the RMI stub to use for an invocation
- * @throws NamingException if stub creation failed
- * @throws RemoteLookupFailureException if RMI stub creation failed
- */
- protected Object getStub() throws NamingException, RemoteLookupFailureException {
- if (!this.cacheStub || (this.lookupStubOnStartup && !this.refreshStubOnConnectFailure)) {
- return (this.cachedStub != null ? this.cachedStub : lookupStub());
- }
- else {
- synchronized (this.stubMonitor) {
- if (this.cachedStub == null) {
- this.cachedStub = lookupStub();
- }
- return this.cachedStub;
- }
- }
- }
-
-
- /**
- * Fetches an RMI stub and delegates to {@link #doInvoke}.
- * If configured to refresh on connect failure, it will call
- * {@link #refreshAndRetry} on corresponding RMI exceptions.
- * @see #getStub
- * @see #doInvoke
- * @see #refreshAndRetry
- * @see java.rmi.ConnectException
- * @see java.rmi.ConnectIOException
- * @see java.rmi.NoSuchObjectException
- */
- @Override
- @Nullable
- public Object invoke(MethodInvocation invocation) throws Throwable {
- Object stub;
- try {
- stub = getStub();
- }
- catch (NamingException ex) {
- throw new RemoteLookupFailureException("JNDI lookup for RMI service [" + getJndiName() + "] failed", ex);
- }
-
- Context ctx = (this.exposeAccessContext ? getJndiTemplate().getContext() : null);
- try {
- return doInvoke(invocation, stub);
- }
- catch (RemoteConnectFailureException ex) {
- return handleRemoteConnectFailure(invocation, ex);
- }
- catch (RemoteException ex) {
- if (isConnectFailure(ex)) {
- return handleRemoteConnectFailure(invocation, ex);
- }
- else {
- throw ex;
- }
- }
- finally {
- getJndiTemplate().releaseContext(ctx);
- }
- }
-
- /**
- * Determine whether the given RMI exception indicates a connect failure.
- *
The default implementation delegates to
- * {@link RmiClientInterceptorUtils#isConnectFailure}.
- * @param ex the RMI exception to check
- * @return whether the exception should be treated as connect failure
- */
- protected boolean isConnectFailure(RemoteException ex) {
- return RmiClientInterceptorUtils.isConnectFailure(ex);
- }
-
- /**
- * Refresh the stub and retry the remote invocation if necessary.
- *
If not configured to refresh on connect failure, this method
- * simply rethrows the original exception.
- * @param invocation the invocation that failed
- * @param ex the exception raised on remote invocation
- * @return the result value of the new invocation, if succeeded
- * @throws Throwable an exception raised by the new invocation, if failed too.
- */
- private Object handleRemoteConnectFailure(MethodInvocation invocation, Exception ex) throws Throwable {
- if (this.refreshStubOnConnectFailure) {
- if (logger.isDebugEnabled()) {
- logger.debug("Could not connect to RMI service [" + getJndiName() + "] - retrying", ex);
- }
- else if (logger.isInfoEnabled()) {
- logger.info("Could not connect to RMI service [" + getJndiName() + "] - retrying");
- }
- return refreshAndRetry(invocation);
- }
- else {
- throw ex;
- }
- }
-
- /**
- * Refresh the RMI stub and retry the given invocation.
- * Called by invoke on connect failure.
- * @param invocation the AOP method invocation
- * @return the invocation result, if any
- * @throws Throwable in case of invocation failure
- * @see #invoke
- */
- @Nullable
- protected Object refreshAndRetry(MethodInvocation invocation) throws Throwable {
- Object freshStub;
- synchronized (this.stubMonitor) {
- this.cachedStub = null;
- freshStub = lookupStub();
- if (this.cacheStub) {
- this.cachedStub = freshStub;
- }
- }
- return doInvoke(invocation, freshStub);
- }
-
-
- /**
- * Perform the given invocation on the given RMI stub.
- * @param invocation the AOP method invocation
- * @param stub the RMI stub to invoke
- * @return the invocation result, if any
- * @throws Throwable in case of invocation failure
- */
- @Nullable
- protected Object doInvoke(MethodInvocation invocation, Object stub) throws Throwable {
- if (stub instanceof RmiInvocationHandler) {
- // RMI invoker
- try {
- return doInvoke(invocation, (RmiInvocationHandler) stub);
- }
- catch (RemoteException ex) {
- throw convertRmiAccessException(ex, invocation.getMethod());
- }
- catch (InvocationTargetException ex) {
- throw ex.getTargetException();
- }
- catch (Throwable ex) {
- throw new RemoteInvocationFailureException("Invocation of method [" + invocation.getMethod() +
- "] failed in RMI service [" + getJndiName() + "]", ex);
- }
- }
- else {
- // traditional RMI stub
- try {
- return RmiClientInterceptorUtils.invokeRemoteMethod(invocation, stub);
- }
- catch (InvocationTargetException ex) {
- Throwable targetEx = ex.getTargetException();
- if (targetEx instanceof RemoteException) {
- throw convertRmiAccessException((RemoteException) targetEx, invocation.getMethod());
- }
- else {
- throw targetEx;
- }
- }
- }
- }
-
- /**
- * Apply the given AOP method invocation to the given {@link RmiInvocationHandler}.
- *
The default implementation delegates to {@link #createRemoteInvocation}.
- * @param methodInvocation the current AOP method invocation
- * @param invocationHandler the RmiInvocationHandler to apply the invocation to
- * @return the invocation result
- * @throws RemoteException in case of communication errors
- * @throws NoSuchMethodException if the method name could not be resolved
- * @throws IllegalAccessException if the method could not be accessed
- * @throws InvocationTargetException if the method invocation resulted in an exception
- * @see org.springframework.remoting.support.RemoteInvocation
- */
- protected Object doInvoke(MethodInvocation methodInvocation, RmiInvocationHandler invocationHandler)
- throws RemoteException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-
- if (AopUtils.isToStringMethod(methodInvocation.getMethod())) {
- return "RMI invoker proxy for service URL [" + getJndiName() + "]";
- }
-
- return invocationHandler.invoke(createRemoteInvocation(methodInvocation));
- }
-
- /**
- * Create a new RemoteInvocation object for the given AOP method invocation.
- *
The default implementation delegates to the configured
- * {@link #setRemoteInvocationFactory RemoteInvocationFactory}.
- * This can be overridden in subclasses in order to provide custom RemoteInvocation
- * subclasses, containing additional invocation parameters (e.g. user credentials).
- *
Note that it is preferable to build a custom RemoteInvocationFactory
- * as a reusable strategy, instead of overriding this method.
- * @param methodInvocation the current AOP method invocation
- * @return the RemoteInvocation object
- * @see RemoteInvocationFactory#createRemoteInvocation
- */
- protected RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) {
- return getRemoteInvocationFactory().createRemoteInvocation(methodInvocation);
- }
-
- /**
- * Convert the given RMI RemoteException that happened during remote access
- * to Spring's RemoteAccessException if the method signature does not declare
- * RemoteException. Else, return the original RemoteException.
- * @param method the invoked method
- * @param ex the RemoteException that happened
- * @return the exception to be thrown to the caller
- */
- private Exception convertRmiAccessException(RemoteException ex, Method method) {
- return RmiClientInterceptorUtils.convertRmiAccessException(method, ex, isConnectFailure(ex), getJndiName());
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiProxyFactoryBean.java b/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiProxyFactoryBean.java
deleted file mode 100644
index a9d33d8973..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiProxyFactoryBean.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2002-2017 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.rmi;
-
-import javax.naming.NamingException;
-
-import org.springframework.aop.framework.ProxyFactory;
-import org.springframework.beans.factory.BeanClassLoaderAware;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-
-/**
- * {@link FactoryBean} for RMI proxies from JNDI.
- *
- *
Typically used for RMI-IIOP (CORBA), but can also be used for EJB home objects
- * (for example, a Stateful Session Bean home). In contrast to a plain JNDI lookup,
- * this accessor also performs narrowing through {@link javax.rmi.PortableRemoteObject}.
- *
- *
With conventional RMI services, this invoker is typically used with the RMI
- * service interface. Alternatively, this invoker can also proxy a remote RMI service
- * with a matching non-RMI business interface, i.e. an interface that mirrors the RMI
- * service methods but does not declare RemoteExceptions. In the latter case,
- * RemoteExceptions thrown by the RMI stub will automatically get converted to
- * Spring's unchecked RemoteAccessException.
- *
- *
The JNDI environment can be specified as "jndiEnvironment" property,
- * or be configured in a {@code jndi.properties} file or as system properties.
- * For example:
- *
- *
, BeanClassLoaderAware {
-
- private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
-
- private Object serviceProxy;
-
-
- @Override
- public void setBeanClassLoader(ClassLoader classLoader) {
- this.beanClassLoader = classLoader;
- }
-
- @Override
- public void afterPropertiesSet() throws NamingException {
- super.afterPropertiesSet();
- Class> ifc = getServiceInterface();
- Assert.notNull(ifc, "Property 'serviceInterface' is required");
- this.serviceProxy = new ProxyFactory(ifc, this).getProxy(this.beanClassLoader);
- }
-
-
- @Override
- public Object getObject() {
- return this.serviceProxy;
- }
-
- @Override
- public Class> getObjectType() {
- return getServiceInterface();
- }
-
- @Override
- public boolean isSingleton() {
- return true;
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiServiceExporter.java b/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiServiceExporter.java
deleted file mode 100644
index 49b2db295a..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/rmi/JndiRmiServiceExporter.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.rmi;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.util.Properties;
-
-import javax.naming.NamingException;
-
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.jndi.JndiTemplate;
-import org.springframework.lang.Nullable;
-import org.springframework.util.ReflectionUtils;
-
-/**
- * Service exporter which binds RMI services to JNDI.
- * Typically used for RMI-IIOP (CORBA).
- *
- * Exports services via the {@link javax.rmi.PortableRemoteObject} class.
- * You need to run "rmic" with the "-iiop" option to generate corresponding
- * stubs and skeletons for each exported service.
- *
- *
Also supports exposing any non-RMI service via RMI invokers, to be accessed
- * via {@link JndiRmiClientInterceptor} / {@link JndiRmiProxyFactoryBean}'s
- * automatic detection of such invokers.
- *
- *
With an RMI invoker, RMI communication works on the {@link RmiInvocationHandler}
- * level, needing only one stub for any service. Service interfaces do not have to
- * extend {@code java.rmi.Remote} or throw {@code java.rmi.RemoteException}
- * on all methods, but in and out parameters have to be serializable.
- *
- *
The JNDI environment can be specified as "jndiEnvironment" bean property,
- * or be configured in a {@code jndi.properties} file or as system properties.
- * For example:
- *
- *
<property name="jndiEnvironment">
- * <props>
- * <prop key="java.naming.factory.initial">com.sun.jndi.cosnaming.CNCtxFactory</prop>
- * <prop key="java.naming.provider.url">iiop://localhost:1050</prop>
- * </props>
- * </property>
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @see #setService
- * @see #setJndiTemplate
- * @see #setJndiEnvironment
- * @see #setJndiName
- * @see JndiRmiClientInterceptor
- * @see JndiRmiProxyFactoryBean
- * @see javax.rmi.PortableRemoteObject#exportObject
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class JndiRmiServiceExporter extends RmiBasedExporter implements InitializingBean, DisposableBean {
-
- @Nullable
- private static Method exportObject;
-
- @Nullable
- private static Method unexportObject;
-
- static {
- try {
- Class> portableRemoteObject =
- JndiRmiServiceExporter.class.getClassLoader().loadClass("javax.rmi.PortableRemoteObject");
- exportObject = portableRemoteObject.getMethod("exportObject", Remote.class);
- unexportObject = portableRemoteObject.getMethod("unexportObject", Remote.class);
- }
- catch (Throwable ex) {
- // java.corba module not available on JDK 9+
- exportObject = null;
- unexportObject = null;
- }
- }
-
-
- private JndiTemplate jndiTemplate = new JndiTemplate();
-
- private String jndiName;
-
- private Remote exportedObject;
-
-
- /**
- * Set the JNDI template to use for JNDI lookups.
- * You can also specify JNDI environment settings via "jndiEnvironment".
- * @see #setJndiEnvironment
- */
- public void setJndiTemplate(JndiTemplate jndiTemplate) {
- this.jndiTemplate = (jndiTemplate != null ? jndiTemplate : new JndiTemplate());
- }
-
- /**
- * Set the JNDI environment to use for JNDI lookups.
- * Creates a JndiTemplate with the given environment settings.
- * @see #setJndiTemplate
- */
- public void setJndiEnvironment(Properties jndiEnvironment) {
- this.jndiTemplate = new JndiTemplate(jndiEnvironment);
- }
-
- /**
- * Set the JNDI name of the exported RMI service.
- */
- public void setJndiName(String jndiName) {
- this.jndiName = jndiName;
- }
-
-
- @Override
- public void afterPropertiesSet() throws NamingException, RemoteException {
- prepare();
- }
-
- /**
- * Initialize this service exporter, binding the specified service to JNDI.
- * @throws NamingException if service binding failed
- * @throws RemoteException if service export failed
- */
- public void prepare() throws NamingException, RemoteException {
- if (this.jndiName == null) {
- throw new IllegalArgumentException("Property 'jndiName' is required");
- }
-
- // Initialize and cache exported object.
- this.exportedObject = getObjectToExport();
- invokePortableRemoteObject(exportObject);
-
- rebind();
- }
-
- /**
- * Rebind the specified service to JNDI, for recovering in case
- * of the target registry having been restarted.
- * @throws NamingException if service binding failed
- */
- public void rebind() throws NamingException {
- if (logger.isDebugEnabled()) {
- logger.debug("Binding RMI service to JNDI location [" + this.jndiName + "]");
- }
- this.jndiTemplate.rebind(this.jndiName, this.exportedObject);
- }
-
- /**
- * Unbind the RMI service from JNDI on bean factory shutdown.
- */
- @Override
- public void destroy() throws NamingException, RemoteException {
- if (logger.isDebugEnabled()) {
- logger.debug("Unbinding RMI service from JNDI location [" + this.jndiName + "]");
- }
- this.jndiTemplate.unbind(this.jndiName);
- invokePortableRemoteObject(unexportObject);
- }
-
-
- private void invokePortableRemoteObject(@Nullable Method method) throws RemoteException {
- if (method != null) {
- try {
- method.invoke(null, this.exportedObject);
- }
- catch (InvocationTargetException ex) {
- Throwable targetEx = ex.getTargetException();
- if (targetEx instanceof RemoteException) {
- throw (RemoteException) targetEx;
- }
- ReflectionUtils.rethrowRuntimeException(targetEx);
- }
- catch (Throwable ex) {
- throw new IllegalStateException("PortableRemoteObject invocation failed", ex);
- }
- }
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RemoteInvocationSerializingExporter.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RemoteInvocationSerializingExporter.java
deleted file mode 100644
index 99e81a4e27..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/rmi/RemoteInvocationSerializingExporter.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.rmi;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.rmi.RemoteException;
-
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.remoting.support.RemoteInvocation;
-import org.springframework.remoting.support.RemoteInvocationBasedExporter;
-import org.springframework.remoting.support.RemoteInvocationResult;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-
-/**
- * Abstract base class for remote service exporters that explicitly deserialize
- * {@link org.springframework.remoting.support.RemoteInvocation} objects and serialize
- * {@link org.springframework.remoting.support.RemoteInvocationResult} objects,
- * for example Spring's HTTP invoker.
- *
- * Provides template methods for {@code ObjectInputStream} and
- * {@code ObjectOutputStream} handling.
- *
- * @author Juergen Hoeller
- * @since 2.5.1
- * @see java.io.ObjectInputStream
- * @see java.io.ObjectOutputStream
- * @see #doReadRemoteInvocation
- * @see #doWriteRemoteInvocationResult
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public abstract class RemoteInvocationSerializingExporter extends RemoteInvocationBasedExporter
- implements InitializingBean {
-
- /**
- * Default content type: "application/x-java-serialized-object".
- */
- public static final String CONTENT_TYPE_SERIALIZED_OBJECT = "application/x-java-serialized-object";
-
-
- private String contentType = CONTENT_TYPE_SERIALIZED_OBJECT;
-
- private boolean acceptProxyClasses = true;
-
- private Object proxy;
-
-
- /**
- * Specify the content type to use for sending remote invocation responses.
- *
Default is "application/x-java-serialized-object".
- */
- public void setContentType(String contentType) {
- Assert.notNull(contentType, "'contentType' must not be null");
- this.contentType = contentType;
- }
-
- /**
- * Return the content type to use for sending remote invocation responses.
- */
- public String getContentType() {
- return this.contentType;
- }
-
- /**
- * Set whether to accept deserialization of proxy classes.
- *
Default is "true". May be deactivated as a security measure.
- */
- public void setAcceptProxyClasses(boolean acceptProxyClasses) {
- this.acceptProxyClasses = acceptProxyClasses;
- }
-
- /**
- * Return whether to accept deserialization of proxy classes.
- */
- public boolean isAcceptProxyClasses() {
- return this.acceptProxyClasses;
- }
-
-
- @Override
- public void afterPropertiesSet() {
- prepare();
- }
-
- /**
- * Initialize this service exporter.
- */
- public void prepare() {
- this.proxy = getProxyForService();
- }
-
- protected final Object getProxy() {
- if (this.proxy == null) {
- throw new IllegalStateException(ClassUtils.getShortName(getClass()) + " has not been initialized");
- }
- return this.proxy;
- }
-
-
- /**
- * Create an ObjectInputStream for the given InputStream.
- *
The default implementation creates a Spring {@link CodebaseAwareObjectInputStream}.
- * @param is the InputStream to read from
- * @return the new ObjectInputStream instance to use
- * @throws java.io.IOException if creation of the ObjectInputStream failed
- */
- protected ObjectInputStream createObjectInputStream(InputStream is) throws IOException {
- return new CodebaseAwareObjectInputStream(is, getBeanClassLoader(), isAcceptProxyClasses());
- }
-
- /**
- * Perform the actual reading of an invocation result object from the
- * given ObjectInputStream.
- *
The default implementation simply calls
- * {@link java.io.ObjectInputStream#readObject()}.
- * Can be overridden for deserialization of a custom wrapper object rather
- * than the plain invocation, for example an encryption-aware holder.
- * @param ois the ObjectInputStream to read from
- * @return the RemoteInvocationResult object
- * @throws java.io.IOException in case of I/O failure
- * @throws ClassNotFoundException if case of a transferred class not
- * being found in the local ClassLoader
- */
- protected RemoteInvocation doReadRemoteInvocation(ObjectInputStream ois)
- throws IOException, ClassNotFoundException {
-
- Object obj = ois.readObject();
- if (!(obj instanceof RemoteInvocation)) {
- throw new RemoteException("Deserialized object needs to be assignable to type [" +
- RemoteInvocation.class.getName() + "]: " + ClassUtils.getDescriptiveType(obj));
- }
- return (RemoteInvocation) obj;
- }
-
- /**
- * Create an ObjectOutputStream for the given OutputStream.
- *
The default implementation creates a plain
- * {@link java.io.ObjectOutputStream}.
- * @param os the OutputStream to write to
- * @return the new ObjectOutputStream instance to use
- * @throws java.io.IOException if creation of the ObjectOutputStream failed
- */
- protected ObjectOutputStream createObjectOutputStream(OutputStream os) throws IOException {
- return new ObjectOutputStream(os);
- }
-
- /**
- * Perform the actual writing of the given invocation result object
- * to the given ObjectOutputStream.
- *
The default implementation simply calls
- * {@link java.io.ObjectOutputStream#writeObject}.
- * Can be overridden for serialization of a custom wrapper object rather
- * than the plain invocation, for example an encryption-aware holder.
- * @param result the RemoteInvocationResult object
- * @param oos the ObjectOutputStream to write to
- * @throws java.io.IOException if thrown by I/O methods
- */
- protected void doWriteRemoteInvocationResult(RemoteInvocationResult result, ObjectOutputStream oos)
- throws IOException {
-
- oos.writeObject(result);
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiBasedExporter.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiBasedExporter.java
deleted file mode 100644
index e6ae6529af..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiBasedExporter.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.rmi;
-
-import java.lang.reflect.InvocationTargetException;
-import java.rmi.Remote;
-
-import org.springframework.remoting.support.RemoteInvocation;
-import org.springframework.remoting.support.RemoteInvocationBasedExporter;
-
-/**
- * Convenient superclass for RMI-based remote exporters. Provides a facility
- * to automatically wrap a given plain Java service object with an
- * RmiInvocationWrapper, exposing the {@link RmiInvocationHandler} remote interface.
- *
- *
Using the RMI invoker mechanism, RMI communication operates at the {@link RmiInvocationHandler}
- * level, sharing a common invoker stub for any number of services. Service interfaces are not
- * required to extend {@code java.rmi.Remote} or declare {@code java.rmi.RemoteException}
- * on all service methods. However, in and out parameters still have to be serializable.
- *
- * @author Juergen Hoeller
- * @since 1.2.5
- * @see RmiServiceExporter
- * @see JndiRmiServiceExporter
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public abstract class RmiBasedExporter extends RemoteInvocationBasedExporter {
-
- /**
- * Determine the object to export: either the service object itself
- * or a RmiInvocationWrapper in case of a non-RMI service object.
- * @return the RMI object to export
- * @see #setService
- * @see #setServiceInterface
- */
- protected Remote getObjectToExport() {
- // determine remote object
- if (getService() instanceof Remote &&
- (getServiceInterface() == null || Remote.class.isAssignableFrom(getServiceInterface()))) {
- // conventional RMI service
- return (Remote) getService();
- }
- else {
- // RMI invoker
- if (logger.isDebugEnabled()) {
- logger.debug("RMI service [" + getService() + "] is an RMI invoker");
- }
- return new RmiInvocationWrapper(getProxyForService(), this);
- }
- }
-
- /**
- * Redefined here to be visible to RmiInvocationWrapper.
- * Simply delegates to the corresponding superclass method.
- */
- @Override
- protected Object invoke(RemoteInvocation invocation, Object targetObject)
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-
- return super.invoke(invocation, targetObject);
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiClientInterceptor.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiClientInterceptor.java
deleted file mode 100644
index 8d8569a8f1..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiClientInterceptor.java
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright 2002-2020 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.rmi;
-
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.net.URLStreamHandler;
-import java.rmi.Naming;
-import java.rmi.NotBoundException;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.rmi.server.RMIClientSocketFactory;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-
-import org.springframework.aop.support.AopUtils;
-import org.springframework.lang.Nullable;
-import org.springframework.remoting.RemoteConnectFailureException;
-import org.springframework.remoting.RemoteInvocationFailureException;
-import org.springframework.remoting.RemoteLookupFailureException;
-import org.springframework.remoting.support.RemoteInvocationBasedAccessor;
-import org.springframework.remoting.support.RemoteInvocationUtils;
-
-/**
- * {@link org.aopalliance.intercept.MethodInterceptor} for accessing conventional
- * RMI services or RMI invokers. The service URL must be a valid RMI URL
- * (e.g. "rmi://localhost:1099/myservice").
- *
- *
RMI invokers work at the RmiInvocationHandler level, needing only one stub for
- * any service. Service interfaces do not have to extend {@code java.rmi.Remote}
- * or throw {@code java.rmi.RemoteException}. Spring's unchecked
- * RemoteAccessException will be thrown on remote invocation failure.
- * Of course, in and out parameters have to be serializable.
- *
- *
With conventional RMI services, this invoker is typically used with the RMI
- * service interface. Alternatively, this invoker can also proxy a remote RMI service
- * with a matching non-RMI business interface, i.e. an interface that mirrors the RMI
- * service methods but does not declare RemoteExceptions. In the latter case,
- * RemoteExceptions thrown by the RMI stub will automatically get converted to
- * Spring's unchecked RemoteAccessException.
- *
- * @author Juergen Hoeller
- * @since 29.09.2003
- * @see RmiServiceExporter
- * @see RmiProxyFactoryBean
- * @see RmiInvocationHandler
- * @see org.springframework.remoting.RemoteAccessException
- * @see java.rmi.RemoteException
- * @see java.rmi.Remote
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class RmiClientInterceptor extends RemoteInvocationBasedAccessor
- implements MethodInterceptor {
-
- private boolean lookupStubOnStartup = true;
-
- private boolean cacheStub = true;
-
- private boolean refreshStubOnConnectFailure = false;
-
- private RMIClientSocketFactory registryClientSocketFactory;
-
- private Remote cachedStub;
-
- private final Object stubMonitor = new Object();
-
-
- /**
- * Set whether to look up the RMI stub on startup. Default is "true".
- *
Can be turned off to allow for late start of the RMI server.
- * In this case, the RMI stub will be fetched on first access.
- * @see #setCacheStub
- */
- public void setLookupStubOnStartup(boolean lookupStubOnStartup) {
- this.lookupStubOnStartup = lookupStubOnStartup;
- }
-
- /**
- * Set whether to cache the RMI stub once it has been located.
- * Default is "true".
- *
Can be turned off to allow for hot restart of the RMI server.
- * In this case, the RMI stub will be fetched for each invocation.
- * @see #setLookupStubOnStartup
- */
- public void setCacheStub(boolean cacheStub) {
- this.cacheStub = cacheStub;
- }
-
- /**
- * Set whether to refresh the RMI stub on connect failure.
- * Default is "false".
- *
Can be turned on to allow for hot restart of the RMI server.
- * If a cached RMI stub throws an RMI exception that indicates a
- * remote connect failure, a fresh proxy will be fetched and the
- * invocation will be retried.
- * @see java.rmi.ConnectException
- * @see java.rmi.ConnectIOException
- * @see java.rmi.NoSuchObjectException
- */
- public void setRefreshStubOnConnectFailure(boolean refreshStubOnConnectFailure) {
- this.refreshStubOnConnectFailure = refreshStubOnConnectFailure;
- }
-
- /**
- * Set a custom RMI client socket factory to use for accessing the RMI registry.
- * @see java.rmi.server.RMIClientSocketFactory
- * @see java.rmi.registry.LocateRegistry#getRegistry(String, int, RMIClientSocketFactory)
- */
- public void setRegistryClientSocketFactory(RMIClientSocketFactory registryClientSocketFactory) {
- this.registryClientSocketFactory = registryClientSocketFactory;
- }
-
-
- @Override
- public void afterPropertiesSet() {
- super.afterPropertiesSet();
- prepare();
- }
-
- /**
- * Fetches RMI stub on startup, if necessary.
- * @throws RemoteLookupFailureException if RMI stub creation failed
- * @see #setLookupStubOnStartup
- * @see #lookupStub
- */
- public void prepare() throws RemoteLookupFailureException {
- // Cache RMI stub on initialization?
- if (this.lookupStubOnStartup) {
- Remote remoteObj = lookupStub();
- if (logger.isDebugEnabled()) {
- if (remoteObj instanceof RmiInvocationHandler) {
- logger.debug("RMI stub [" + getServiceUrl() + "] is an RMI invoker");
- }
- else if (getServiceInterface() != null) {
- boolean isImpl = getServiceInterface().isInstance(remoteObj);
- logger.debug("Using service interface [" + getServiceInterface().getName() +
- "] for RMI stub [" + getServiceUrl() + "] - " +
- (!isImpl ? "not " : "") + "directly implemented");
- }
- }
- if (this.cacheStub) {
- this.cachedStub = remoteObj;
- }
- }
- }
-
- /**
- * Create the RMI stub, typically by looking it up.
- *
Called on interceptor initialization if "cacheStub" is "true";
- * else called for each invocation by {@link #getStub()}.
- *
The default implementation looks up the service URL via
- * {@code java.rmi.Naming}. This can be overridden in subclasses.
- * @return the RMI stub to store in this interceptor
- * @throws RemoteLookupFailureException if RMI stub creation failed
- * @see #setCacheStub
- * @see java.rmi.Naming#lookup
- */
- protected Remote lookupStub() throws RemoteLookupFailureException {
- try {
- Remote stub = null;
- if (this.registryClientSocketFactory != null) {
- // RMIClientSocketFactory specified for registry access.
- // Unfortunately, due to RMI API limitations, this means
- // that we need to parse the RMI URL ourselves and perform
- // straight LocateRegistry.getRegistry/Registry.lookup calls.
- URL url = new URL(null, getServiceUrl(), new DummyURLStreamHandler());
- String protocol = url.getProtocol();
- if (protocol != null && !"rmi".equals(protocol)) {
- throw new MalformedURLException("Invalid URL scheme '" + protocol + "'");
- }
- String host = url.getHost();
- int port = url.getPort();
- String name = url.getPath();
- if (name != null && name.startsWith("/")) {
- name = name.substring(1);
- }
- Registry registry = LocateRegistry.getRegistry(host, port, this.registryClientSocketFactory);
- stub = registry.lookup(name);
- }
- else {
- // Can proceed with standard RMI lookup API...
- stub = Naming.lookup(getServiceUrl());
- }
- if (logger.isDebugEnabled()) {
- logger.debug("Located RMI stub with URL [" + getServiceUrl() + "]");
- }
- return stub;
- }
- catch (MalformedURLException ex) {
- throw new RemoteLookupFailureException("Service URL [" + getServiceUrl() + "] is invalid", ex);
- }
- catch (NotBoundException ex) {
- throw new RemoteLookupFailureException(
- "Could not find RMI service [" + getServiceUrl() + "] in RMI registry", ex);
- }
- catch (RemoteException ex) {
- throw new RemoteLookupFailureException("Lookup of RMI stub failed", ex);
- }
- }
-
- /**
- * Return the RMI stub to use. Called for each invocation.
- *
The default implementation returns the stub created on initialization,
- * if any. Else, it invokes {@link #lookupStub} to get a new stub for
- * each invocation. This can be overridden in subclasses, for example in
- * order to cache a stub for a given amount of time before recreating it,
- * or to test the stub whether it is still alive.
- * @return the RMI stub to use for an invocation
- * @throws RemoteLookupFailureException if RMI stub creation failed
- * @see #lookupStub
- */
- protected Remote getStub() throws RemoteLookupFailureException {
- if (!this.cacheStub || (this.lookupStubOnStartup && !this.refreshStubOnConnectFailure)) {
- return (this.cachedStub != null ? this.cachedStub : lookupStub());
- }
- else {
- synchronized (this.stubMonitor) {
- if (this.cachedStub == null) {
- this.cachedStub = lookupStub();
- }
- return this.cachedStub;
- }
- }
- }
-
-
- /**
- * Fetches an RMI stub and delegates to {@code doInvoke}.
- * If configured to refresh on connect failure, it will call
- * {@link #refreshAndRetry} on corresponding RMI exceptions.
- * @see #getStub
- * @see #doInvoke(MethodInvocation, Remote)
- * @see #refreshAndRetry
- * @see java.rmi.ConnectException
- * @see java.rmi.ConnectIOException
- * @see java.rmi.NoSuchObjectException
- */
- @Override
- @Nullable
- public Object invoke(MethodInvocation invocation) throws Throwable {
- Remote stub = getStub();
- try {
- return doInvoke(invocation, stub);
- }
- catch (RemoteConnectFailureException ex) {
- return handleRemoteConnectFailure(invocation, ex);
- }
- catch (RemoteException ex) {
- if (isConnectFailure(ex)) {
- return handleRemoteConnectFailure(invocation, ex);
- }
- else {
- throw ex;
- }
- }
- }
-
- /**
- * Determine whether the given RMI exception indicates a connect failure.
- *
The default implementation delegates to
- * {@link RmiClientInterceptorUtils#isConnectFailure}.
- * @param ex the RMI exception to check
- * @return whether the exception should be treated as connect failure
- */
- protected boolean isConnectFailure(RemoteException ex) {
- return RmiClientInterceptorUtils.isConnectFailure(ex);
- }
-
- /**
- * Refresh the stub and retry the remote invocation if necessary.
- *
If not configured to refresh on connect failure, this method
- * simply rethrows the original exception.
- * @param invocation the invocation that failed
- * @param ex the exception raised on remote invocation
- * @return the result value of the new invocation, if succeeded
- * @throws Throwable an exception raised by the new invocation,
- * if it failed as well
- * @see #setRefreshStubOnConnectFailure
- * @see #doInvoke
- */
- @Nullable
- private Object handleRemoteConnectFailure(MethodInvocation invocation, Exception ex) throws Throwable {
- if (this.refreshStubOnConnectFailure) {
- String msg = "Could not connect to RMI service [" + getServiceUrl() + "] - retrying";
- if (logger.isDebugEnabled()) {
- logger.warn(msg, ex);
- }
- else if (logger.isWarnEnabled()) {
- logger.warn(msg);
- }
- return refreshAndRetry(invocation);
- }
- else {
- throw ex;
- }
- }
-
- /**
- * Refresh the RMI stub and retry the given invocation.
- * Called by invoke on connect failure.
- * @param invocation the AOP method invocation
- * @return the invocation result, if any
- * @throws Throwable in case of invocation failure
- * @see #invoke
- */
- @Nullable
- protected Object refreshAndRetry(MethodInvocation invocation) throws Throwable {
- Remote freshStub = null;
- synchronized (this.stubMonitor) {
- this.cachedStub = null;
- freshStub = lookupStub();
- if (this.cacheStub) {
- this.cachedStub = freshStub;
- }
- }
- return doInvoke(invocation, freshStub);
- }
-
- /**
- * Perform the given invocation on the given RMI stub.
- * @param invocation the AOP method invocation
- * @param stub the RMI stub to invoke
- * @return the invocation result, if any
- * @throws Throwable in case of invocation failure
- */
- @Nullable
- protected Object doInvoke(MethodInvocation invocation, Remote stub) throws Throwable {
- if (stub instanceof RmiInvocationHandler) {
- // RMI invoker
- try {
- return doInvoke(invocation, (RmiInvocationHandler) stub);
- }
- catch (RemoteException ex) {
- throw RmiClientInterceptorUtils.convertRmiAccessException(
- invocation.getMethod(), ex, isConnectFailure(ex), getServiceUrl());
- }
- catch (InvocationTargetException ex) {
- Throwable exToThrow = ex.getTargetException();
- RemoteInvocationUtils.fillInClientStackTraceIfPossible(exToThrow);
- throw exToThrow;
- }
- catch (Throwable ex) {
- throw new RemoteInvocationFailureException("Invocation of method [" + invocation.getMethod() +
- "] failed in RMI service [" + getServiceUrl() + "]", ex);
- }
- }
- else {
- // traditional RMI stub
- try {
- return RmiClientInterceptorUtils.invokeRemoteMethod(invocation, stub);
- }
- catch (InvocationTargetException ex) {
- Throwable targetEx = ex.getTargetException();
- if (targetEx instanceof RemoteException) {
- RemoteException rex = (RemoteException) targetEx;
- throw RmiClientInterceptorUtils.convertRmiAccessException(
- invocation.getMethod(), rex, isConnectFailure(rex), getServiceUrl());
- }
- else {
- throw targetEx;
- }
- }
- }
- }
-
- /**
- * Apply the given AOP method invocation to the given {@link RmiInvocationHandler}.
- *
The default implementation delegates to {@link #createRemoteInvocation}.
- * @param methodInvocation the current AOP method invocation
- * @param invocationHandler the RmiInvocationHandler to apply the invocation to
- * @return the invocation result
- * @throws RemoteException in case of communication errors
- * @throws NoSuchMethodException if the method name could not be resolved
- * @throws IllegalAccessException if the method could not be accessed
- * @throws InvocationTargetException if the method invocation resulted in an exception
- * @see org.springframework.remoting.support.RemoteInvocation
- */
- @Nullable
- protected Object doInvoke(MethodInvocation methodInvocation, RmiInvocationHandler invocationHandler)
- throws RemoteException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-
- if (AopUtils.isToStringMethod(methodInvocation.getMethod())) {
- return "RMI invoker proxy for service URL [" + getServiceUrl() + "]";
- }
-
- return invocationHandler.invoke(createRemoteInvocation(methodInvocation));
- }
-
-
- /**
- * Dummy URLStreamHandler that's just specified to suppress the standard
- * {@code java.net.URL} URLStreamHandler lookup, to be able to
- * use the standard URL class for parsing "rmi:..." URLs.
- */
- private static class DummyURLStreamHandler extends URLStreamHandler {
-
- @Override
- protected URLConnection openConnection(URL url) throws IOException {
- throw new UnsupportedOperationException();
- }
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiClientInterceptorUtils.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiClientInterceptorUtils.java
deleted file mode 100644
index 2842e06143..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiClientInterceptorUtils.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2002-2016 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.rmi;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.SocketException;
-import java.rmi.ConnectException;
-import java.rmi.ConnectIOException;
-import java.rmi.NoSuchObjectException;
-import java.rmi.RemoteException;
-import java.rmi.StubNotFoundException;
-import java.rmi.UnknownHostException;
-
-import org.aopalliance.intercept.MethodInvocation;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.lang.Nullable;
-import org.springframework.remoting.RemoteAccessException;
-import org.springframework.remoting.RemoteConnectFailureException;
-import org.springframework.remoting.RemoteProxyFailureException;
-import org.springframework.util.ReflectionUtils;
-
-/**
- * Factored-out methods for performing invocations within an RMI client.
- * Can handle both RMI and non-RMI service interfaces working on an RMI stub.
- *
- *
Note: This is an SPI class, not intended to be used by applications.
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public abstract class RmiClientInterceptorUtils {
-
- private static final Log logger = LogFactory.getLog(RmiClientInterceptorUtils.class);
-
-
- /**
- * Perform a raw method invocation on the given RMI stub,
- * letting reflection exceptions through as-is.
- * @param invocation the AOP MethodInvocation
- * @param stub the RMI stub
- * @return the invocation result, if any
- * @throws InvocationTargetException if thrown by reflection
- */
- @Nullable
- public static Object invokeRemoteMethod(MethodInvocation invocation, Object stub)
- throws InvocationTargetException {
-
- Method method = invocation.getMethod();
- try {
- if (method.getDeclaringClass().isInstance(stub)) {
- // directly implemented
- return method.invoke(stub, invocation.getArguments());
- }
- else {
- // not directly implemented
- Method stubMethod = stub.getClass().getMethod(method.getName(), method.getParameterTypes());
- return stubMethod.invoke(stub, invocation.getArguments());
- }
- }
- catch (InvocationTargetException ex) {
- throw ex;
- }
- catch (NoSuchMethodException ex) {
- throw new RemoteProxyFailureException("No matching RMI stub method found for: " + method, ex);
- }
- catch (Throwable ex) {
- throw new RemoteProxyFailureException("Invocation of RMI stub method failed: " + method, ex);
- }
- }
-
- /**
- * Wrap the given arbitrary exception that happened during remote access
- * in either a RemoteException or a Spring RemoteAccessException (if the
- * method signature does not support RemoteException).
- *
Only call this for remote access exceptions, not for exceptions
- * thrown by the target service itself!
- * @param method the invoked method
- * @param ex the exception that happened, to be used as cause for the
- * RemoteAccessException or RemoteException
- * @param message the message for the RemoteAccessException respectively
- * RemoteException
- * @return the exception to be thrown to the caller
- */
- public static Exception convertRmiAccessException(Method method, Throwable ex, String message) {
- if (logger.isDebugEnabled()) {
- logger.debug(message, ex);
- }
- if (ReflectionUtils.declaresException(method, RemoteException.class)) {
- return new RemoteException(message, ex);
- }
- else {
- return new RemoteAccessException(message, ex);
- }
- }
-
- /**
- * Convert the given RemoteException that happened during remote access
- * to Spring's RemoteAccessException if the method signature does not
- * support RemoteException. Else, return the original RemoteException.
- * @param method the invoked method
- * @param ex the RemoteException that happened
- * @param serviceName the name of the service (for debugging purposes)
- * @return the exception to be thrown to the caller
- */
- public static Exception convertRmiAccessException(Method method, RemoteException ex, String serviceName) {
- return convertRmiAccessException(method, ex, isConnectFailure(ex), serviceName);
- }
-
- /**
- * Convert the given RemoteException that happened during remote access
- * to Spring's RemoteAccessException if the method signature does not
- * support RemoteException. Else, return the original RemoteException.
- * @param method the invoked method
- * @param ex the RemoteException that happened
- * @param isConnectFailure whether the given exception should be considered
- * a connect failure
- * @param serviceName the name of the service (for debugging purposes)
- * @return the exception to be thrown to the caller
- */
- public static Exception convertRmiAccessException(
- Method method, RemoteException ex, boolean isConnectFailure, String serviceName) {
-
- if (logger.isDebugEnabled()) {
- logger.debug("Remote service [" + serviceName + "] threw exception", ex);
- }
- if (ReflectionUtils.declaresException(method, ex.getClass())) {
- return ex;
- }
- else {
- if (isConnectFailure) {
- return new RemoteConnectFailureException("Could not connect to remote service [" + serviceName + "]", ex);
- }
- else {
- return new RemoteAccessException("Could not access remote service [" + serviceName + "]", ex);
- }
- }
- }
-
- /**
- * Determine whether the given RMI exception indicates a connect failure.
- *
Treats RMI's ConnectException, ConnectIOException, UnknownHostException,
- * NoSuchObjectException and StubNotFoundException as connect failure.
- * @param ex the RMI exception to check
- * @return whether the exception should be treated as connect failure
- * @see java.rmi.ConnectException
- * @see java.rmi.ConnectIOException
- * @see java.rmi.UnknownHostException
- * @see java.rmi.NoSuchObjectException
- * @see java.rmi.StubNotFoundException
- */
- public static boolean isConnectFailure(RemoteException ex) {
- return (ex instanceof ConnectException || ex instanceof ConnectIOException ||
- ex instanceof UnknownHostException || ex instanceof NoSuchObjectException ||
- ex instanceof StubNotFoundException || ex.getCause() instanceof SocketException);
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiInvocationHandler.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiInvocationHandler.java
deleted file mode 100644
index fb26b071f5..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiInvocationHandler.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.rmi;
-
-import java.lang.reflect.InvocationTargetException;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-import org.springframework.lang.Nullable;
-import org.springframework.remoting.support.RemoteInvocation;
-
-/**
- * Interface for RMI invocation handlers instances on the server,
- * wrapping exported services. A client uses a stub implementing
- * this interface to access such a service.
- *
- *
This is an SPI interface, not to be used directly by applications.
- *
- * @author Juergen Hoeller
- * @since 14.05.2003
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public interface RmiInvocationHandler extends Remote {
-
- /**
- * Return the name of the target interface that this invoker operates on.
- * @return the name of the target interface, or {@code null} if none
- * @throws RemoteException in case of communication errors
- * @see RmiServiceExporter#getServiceInterface()
- */
- @Nullable
- public String getTargetInterfaceName() throws RemoteException;
-
- /**
- * Apply the given invocation to the target object.
- *
Called by
- * {@link RmiClientInterceptor#doInvoke(org.aopalliance.intercept.MethodInvocation, RmiInvocationHandler)}.
- * @param invocation object that encapsulates invocation parameters
- * @return the object returned from the invoked method, if any
- * @throws RemoteException in case of communication errors
- * @throws NoSuchMethodException if the method name could not be resolved
- * @throws IllegalAccessException if the method could not be accessed
- * @throws InvocationTargetException if the method invocation resulted in an exception
- */
- @Nullable
- public Object invoke(RemoteInvocation invocation)
- throws RemoteException, NoSuchMethodException, IllegalAccessException, InvocationTargetException;
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiInvocationWrapper.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiInvocationWrapper.java
deleted file mode 100644
index 1f030b327c..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiInvocationWrapper.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.rmi;
-
-import java.lang.reflect.InvocationTargetException;
-import java.rmi.RemoteException;
-
-import org.springframework.lang.Nullable;
-import org.springframework.remoting.support.RemoteInvocation;
-import org.springframework.util.Assert;
-
-/**
- * Server-side implementation of {@link RmiInvocationHandler}. An instance
- * of this class exists for each remote object. Automatically created
- * by {@link RmiServiceExporter} for non-RMI service implementations.
- *
- *
This is an SPI class, not to be used directly by applications.
- *
- * @author Juergen Hoeller
- * @since 14.05.2003
- * @see RmiServiceExporter
- */
-@Deprecated
-class RmiInvocationWrapper implements RmiInvocationHandler {
-
- private final Object wrappedObject;
-
- private final RmiBasedExporter rmiExporter;
-
-
- /**
- * Create a new RmiInvocationWrapper for the given object.
- * @param wrappedObject the object to wrap with an RmiInvocationHandler
- * @param rmiExporter the RMI exporter to handle the actual invocation
- */
- public RmiInvocationWrapper(Object wrappedObject, RmiBasedExporter rmiExporter) {
- Assert.notNull(wrappedObject, "Object to wrap is required");
- Assert.notNull(rmiExporter, "RMI exporter is required");
- this.wrappedObject = wrappedObject;
- this.rmiExporter = rmiExporter;
- }
-
-
- /**
- * Exposes the exporter's service interface, if any, as target interface.
- * @see RmiBasedExporter#getServiceInterface()
- */
- @Override
- @Nullable
- public String getTargetInterfaceName() {
- Class> ifc = this.rmiExporter.getServiceInterface();
- return (ifc != null ? ifc.getName() : null);
- }
-
- /**
- * Delegates the actual invocation handling to the RMI exporter.
- * @see RmiBasedExporter#invoke(org.springframework.remoting.support.RemoteInvocation, Object)
- */
- @Override
- @Nullable
- public Object invoke(RemoteInvocation invocation)
- throws RemoteException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-
- return this.rmiExporter.invoke(invocation, this.wrappedObject);
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiProxyFactoryBean.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiProxyFactoryBean.java
deleted file mode 100644
index 142640926d..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiProxyFactoryBean.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright 2002-2017 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.rmi;
-
-import org.springframework.aop.framework.ProxyFactory;
-import org.springframework.beans.factory.BeanClassLoaderAware;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.util.Assert;
-
-/**
- * {@link FactoryBean} for RMI proxies, supporting both conventional RMI services
- * and RMI invokers. Exposes the proxied service for use as a bean reference,
- * using the specified service interface. Proxies will throw Spring's unchecked
- * RemoteAccessException on remote invocation failure instead of RMI's RemoteException.
- *
- *
The service URL must be a valid RMI URL like "rmi://localhost:1099/myservice".
- * RMI invokers work at the RmiInvocationHandler level, using the same invoker stub
- * for any service. Service interfaces do not have to extend {@code java.rmi.Remote}
- * or throw {@code java.rmi.RemoteException}. Of course, in and out parameters
- * have to be serializable.
- *
- *
With conventional RMI services, this proxy factory is typically used with the
- * RMI service interface. Alternatively, this factory can also proxy a remote RMI
- * service with a matching non-RMI business interface, i.e. an interface that mirrors
- * the RMI service methods but does not declare RemoteExceptions. In the latter case,
- * RemoteExceptions thrown by the RMI stub will automatically get converted to
- * Spring's unchecked RemoteAccessException.
- *
- *
The major advantage of RMI, compared to Hessian, is serialization.
- * Effectively, any serializable Java object can be transported without hassle.
- * Hessian has its own (de-)serialization mechanisms, but is HTTP-based and thus
- * much easier to setup than RMI. Alternatively, consider Spring's HTTP invoker
- * to combine Java serialization with HTTP-based transport.
- *
- * @author Juergen Hoeller
- * @since 13.05.2003
- * @see #setServiceInterface
- * @see #setServiceUrl
- * @see RmiClientInterceptor
- * @see RmiServiceExporter
- * @see java.rmi.Remote
- * @see java.rmi.RemoteException
- * @see org.springframework.remoting.RemoteAccessException
- * @see org.springframework.remoting.caucho.HessianProxyFactoryBean
- * @see org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class RmiProxyFactoryBean extends RmiClientInterceptor implements FactoryBean, BeanClassLoaderAware {
-
- private Object serviceProxy;
-
-
- @Override
- public void afterPropertiesSet() {
- super.afterPropertiesSet();
- Class> ifc = getServiceInterface();
- Assert.notNull(ifc, "Property 'serviceInterface' is required");
- this.serviceProxy = new ProxyFactory(ifc, this).getProxy(getBeanClassLoader());
- }
-
-
- @Override
- public Object getObject() {
- return this.serviceProxy;
- }
-
- @Override
- public Class> getObjectType() {
- return getServiceInterface();
- }
-
- @Override
- public boolean isSingleton() {
- return true;
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiRegistryFactoryBean.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiRegistryFactoryBean.java
deleted file mode 100644
index e0b9cf6015..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiRegistryFactoryBean.java
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.rmi;
-
-import java.rmi.RemoteException;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.rmi.server.RMIClientSocketFactory;
-import java.rmi.server.RMIServerSocketFactory;
-import java.rmi.server.UnicastRemoteObject;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.lang.Nullable;
-
-/**
- * {@link FactoryBean} that locates a {@link java.rmi.registry.Registry} and
- * exposes it for bean references. Can also create a local RMI registry
- * on the fly if none exists already.
- *
- * Can be used to set up and pass around the actual Registry object to
- * applications objects that need to work with RMI. One example for such an
- * object that needs to work with RMI is Spring's {@link RmiServiceExporter},
- * which either works with a passed-in Registry reference or falls back to
- * the registry as specified by its local properties and defaults.
- *
- *
Also useful to enforce creation of a local RMI registry at a given port,
- * for example for a JMX connector. If used in conjunction with
- * {@link org.springframework.jmx.support.ConnectorServerFactoryBean},
- * it is recommended to mark the connector definition (ConnectorServerFactoryBean)
- * as "depends-on" the registry definition (RmiRegistryFactoryBean),
- * to guarantee starting up the registry first.
- *
- *
Note: The implementation of this class mirrors the corresponding logic
- * in {@link RmiServiceExporter}, and also offers the same customization hooks.
- * RmiServiceExporter implements its own registry lookup as a convenience:
- * It is very common to simply rely on the registry defaults.
- *
- * @author Juergen Hoeller
- * @since 1.2.3
- * @see RmiServiceExporter#setRegistry
- * @see org.springframework.jmx.support.ConnectorServerFactoryBean
- * @see java.rmi.registry.Registry
- * @see java.rmi.registry.LocateRegistry
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class RmiRegistryFactoryBean implements FactoryBean, InitializingBean, DisposableBean {
-
- protected final Log logger = LogFactory.getLog(getClass());
-
- private String host;
-
- private int port = Registry.REGISTRY_PORT;
-
- private RMIClientSocketFactory clientSocketFactory;
-
- private RMIServerSocketFactory serverSocketFactory;
-
- private Registry registry;
-
- private boolean alwaysCreate = false;
-
- private boolean created = false;
-
-
- /**
- * Set the host of the registry for the exported RMI service,
- * i.e. {@code rmi://HOST:port/name}
- * Default is localhost.
- */
- public void setHost(String host) {
- this.host = host;
- }
-
- /**
- * Return the host of the registry for the exported RMI service.
- */
- public String getHost() {
- return this.host;
- }
-
- /**
- * Set the port of the registry for the exported RMI service,
- * i.e. {@code rmi://host:PORT/name}
- *
Default is {@code Registry.REGISTRY_PORT} (1099).
- */
- public void setPort(int port) {
- this.port = port;
- }
-
- /**
- * Return the port of the registry for the exported RMI service.
- */
- public int getPort() {
- return this.port;
- }
-
- /**
- * Set a custom RMI client socket factory to use for the RMI registry.
- *
If the given object also implements {@code java.rmi.server.RMIServerSocketFactory},
- * it will automatically be registered as server socket factory too.
- * @see #setServerSocketFactory
- * @see java.rmi.server.RMIClientSocketFactory
- * @see java.rmi.server.RMIServerSocketFactory
- * @see java.rmi.registry.LocateRegistry#getRegistry(String, int, java.rmi.server.RMIClientSocketFactory)
- */
- public void setClientSocketFactory(RMIClientSocketFactory clientSocketFactory) {
- this.clientSocketFactory = clientSocketFactory;
- }
-
- /**
- * Set a custom RMI server socket factory to use for the RMI registry.
- *
Only needs to be specified when the client socket factory does not
- * implement {@code java.rmi.server.RMIServerSocketFactory} already.
- * @see #setClientSocketFactory
- * @see java.rmi.server.RMIClientSocketFactory
- * @see java.rmi.server.RMIServerSocketFactory
- * @see java.rmi.registry.LocateRegistry#createRegistry(int, RMIClientSocketFactory, java.rmi.server.RMIServerSocketFactory)
- */
- public void setServerSocketFactory(RMIServerSocketFactory serverSocketFactory) {
- this.serverSocketFactory = serverSocketFactory;
- }
-
- /**
- * Set whether to always create the registry in-process,
- * not attempting to locate an existing registry at the specified port.
- *
Default is "false". Switch this flag to "true" in order to avoid
- * the overhead of locating an existing registry when you always
- * intend to create a new registry in any case.
- */
- public void setAlwaysCreate(boolean alwaysCreate) {
- this.alwaysCreate = alwaysCreate;
- }
-
-
- @Override
- public void afterPropertiesSet() throws Exception {
- // Check socket factories for registry.
- if (this.clientSocketFactory instanceof RMIServerSocketFactory) {
- this.serverSocketFactory = (RMIServerSocketFactory) this.clientSocketFactory;
- }
- if ((this.clientSocketFactory != null && this.serverSocketFactory == null) ||
- (this.clientSocketFactory == null && this.serverSocketFactory != null)) {
- throw new IllegalArgumentException(
- "Both RMIClientSocketFactory and RMIServerSocketFactory or none required");
- }
-
- // Fetch RMI registry to expose.
- this.registry = getRegistry(this.host, this.port, this.clientSocketFactory, this.serverSocketFactory);
- }
-
-
- /**
- * Locate or create the RMI registry.
- * @param registryHost the registry host to use (if this is specified,
- * no implicit creation of a RMI registry will happen)
- * @param registryPort the registry port to use
- * @param clientSocketFactory the RMI client socket factory for the registry (if any)
- * @param serverSocketFactory the RMI server socket factory for the registry (if any)
- * @return the RMI registry
- * @throws java.rmi.RemoteException if the registry couldn't be located or created
- */
- protected Registry getRegistry(String registryHost, int registryPort,
- @Nullable RMIClientSocketFactory clientSocketFactory, @Nullable RMIServerSocketFactory serverSocketFactory)
- throws RemoteException {
-
- if (registryHost != null) {
- // Host explicitly specified: only lookup possible.
- if (logger.isDebugEnabled()) {
- logger.debug("Looking for RMI registry at port '" + registryPort + "' of host [" + registryHost + "]");
- }
- Registry reg = LocateRegistry.getRegistry(registryHost, registryPort, clientSocketFactory);
- testRegistry(reg);
- return reg;
- }
-
- else {
- return getRegistry(registryPort, clientSocketFactory, serverSocketFactory);
- }
- }
-
- /**
- * Locate or create the RMI registry.
- * @param registryPort the registry port to use
- * @param clientSocketFactory the RMI client socket factory for the registry (if any)
- * @param serverSocketFactory the RMI server socket factory for the registry (if any)
- * @return the RMI registry
- * @throws RemoteException if the registry couldn't be located or created
- */
- protected Registry getRegistry(int registryPort,
- @Nullable RMIClientSocketFactory clientSocketFactory, @Nullable RMIServerSocketFactory serverSocketFactory)
- throws RemoteException {
-
- if (clientSocketFactory != null) {
- if (this.alwaysCreate) {
- logger.debug("Creating new RMI registry");
- this.created = true;
- return LocateRegistry.createRegistry(registryPort, clientSocketFactory, serverSocketFactory);
- }
- if (logger.isDebugEnabled()) {
- logger.debug("Looking for RMI registry at port '" + registryPort + "', using custom socket factory");
- }
- synchronized (LocateRegistry.class) {
- try {
- // Retrieve existing registry.
- Registry reg = LocateRegistry.getRegistry(null, registryPort, clientSocketFactory);
- testRegistry(reg);
- return reg;
- }
- catch (RemoteException ex) {
- logger.trace("RMI registry access threw exception", ex);
- logger.debug("Could not detect RMI registry - creating new one");
- // Assume no registry found -> create new one.
- this.created = true;
- return LocateRegistry.createRegistry(registryPort, clientSocketFactory, serverSocketFactory);
- }
- }
- }
-
- else {
- return getRegistry(registryPort);
- }
- }
-
- /**
- * Locate or create the RMI registry.
- * @param registryPort the registry port to use
- * @return the RMI registry
- * @throws RemoteException if the registry couldn't be located or created
- */
- protected Registry getRegistry(int registryPort) throws RemoteException {
- if (this.alwaysCreate) {
- logger.debug("Creating new RMI registry");
- this.created = true;
- return LocateRegistry.createRegistry(registryPort);
- }
- if (logger.isDebugEnabled()) {
- logger.debug("Looking for RMI registry at port '" + registryPort + "'");
- }
- synchronized (LocateRegistry.class) {
- try {
- // Retrieve existing registry.
- Registry reg = LocateRegistry.getRegistry(registryPort);
- testRegistry(reg);
- return reg;
- }
- catch (RemoteException ex) {
- logger.trace("RMI registry access threw exception", ex);
- logger.debug("Could not detect RMI registry - creating new one");
- // Assume no registry found -> create new one.
- this.created = true;
- return LocateRegistry.createRegistry(registryPort);
- }
- }
- }
-
- /**
- * Test the given RMI registry, calling some operation on it to
- * check whether it is still active.
- *
Default implementation calls {@code Registry.list()}.
- * @param registry the RMI registry to test
- * @throws RemoteException if thrown by registry methods
- * @see java.rmi.registry.Registry#list()
- */
- protected void testRegistry(Registry registry) throws RemoteException {
- registry.list();
- }
-
-
- @Override
- public Registry getObject() throws Exception {
- return this.registry;
- }
-
- @Override
- public Class extends Registry> getObjectType() {
- return (this.registry != null ? this.registry.getClass() : Registry.class);
- }
-
- @Override
- public boolean isSingleton() {
- return true;
- }
-
-
- /**
- * Unexport the RMI registry on bean factory shutdown,
- * provided that this bean actually created a registry.
- */
- @Override
- public void destroy() throws RemoteException {
- if (this.created) {
- logger.debug("Unexporting RMI registry");
- UnicastRemoteObject.unexportObject(this.registry, true);
- }
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiServiceExporter.java b/spring-context/src/main/java/org/springframework/remoting/rmi/RmiServiceExporter.java
deleted file mode 100644
index 9ee3a6c112..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/rmi/RmiServiceExporter.java
+++ /dev/null
@@ -1,464 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.rmi;
-
-import java.rmi.AlreadyBoundException;
-import java.rmi.NoSuchObjectException;
-import java.rmi.NotBoundException;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
-import java.rmi.server.RMIClientSocketFactory;
-import java.rmi.server.RMIServerSocketFactory;
-import java.rmi.server.UnicastRemoteObject;
-
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.lang.Nullable;
-
-/**
- * RMI exporter that exposes the specified service as RMI object with the specified name.
- * Such services can be accessed via plain RMI or via {@link RmiProxyFactoryBean}.
- * Also supports exposing any non-RMI service via RMI invokers, to be accessed via
- * {@link RmiClientInterceptor} / {@link RmiProxyFactoryBean}'s automatic detection
- * of such invokers.
- *
- *
With an RMI invoker, RMI communication works on the {@link RmiInvocationHandler}
- * level, needing only one stub for any service. Service interfaces do not have to
- * extend {@code java.rmi.Remote} or throw {@code java.rmi.RemoteException}
- * on all methods, but in and out parameters have to be serializable.
- *
- *
The major advantage of RMI, compared to Hessian, is serialization.
- * Effectively, any serializable Java object can be transported without hassle.
- * Hessian has its own (de-)serialization mechanisms, but is HTTP-based and thus
- * much easier to setup than RMI. Alternatively, consider Spring's HTTP invoker
- * to combine Java serialization with HTTP-based transport.
- *
- *
Note: RMI makes a best-effort attempt to obtain the fully qualified host name.
- * If one cannot be determined, it will fall back and use the IP address. Depending
- * on your network configuration, in some cases it will resolve the IP to the loopback
- * address. To ensure that RMI will use the host name bound to the correct network
- * interface, you should pass the {@code java.rmi.server.hostname} property to the
- * JVM that will export the registry and/or the service using the "-D" JVM argument.
- * For example: {@code -Djava.rmi.server.hostname=myserver.com}
- *
- * @author Juergen Hoeller
- * @since 13.05.2003
- * @see RmiClientInterceptor
- * @see RmiProxyFactoryBean
- * @see java.rmi.Remote
- * @see java.rmi.RemoteException
- * @see org.springframework.remoting.caucho.HessianServiceExporter
- * @see org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class RmiServiceExporter extends RmiBasedExporter implements InitializingBean, DisposableBean {
-
- private String serviceName;
-
- private int servicePort = 0; // anonymous port
-
- private RMIClientSocketFactory clientSocketFactory;
-
- private RMIServerSocketFactory serverSocketFactory;
-
- private Registry registry;
-
- private String registryHost;
-
- private int registryPort = Registry.REGISTRY_PORT;
-
- private RMIClientSocketFactory registryClientSocketFactory;
-
- private RMIServerSocketFactory registryServerSocketFactory;
-
- private boolean alwaysCreateRegistry = false;
-
- private boolean replaceExistingBinding = true;
-
- private Remote exportedObject;
-
- private boolean createdRegistry = false;
-
-
- /**
- * Set the name of the exported RMI service,
- * i.e. {@code rmi://host:port/NAME}
- */
- public void setServiceName(String serviceName) {
- this.serviceName = serviceName;
- }
-
- /**
- * Set the port that the exported RMI service will use.
- *
Default is 0 (anonymous port).
- */
- public void setServicePort(int servicePort) {
- this.servicePort = servicePort;
- }
-
- /**
- * Set a custom RMI client socket factory to use for exporting the service.
- *
If the given object also implements {@code java.rmi.server.RMIServerSocketFactory},
- * it will automatically be registered as server socket factory too.
- * @see #setServerSocketFactory
- * @see java.rmi.server.RMIClientSocketFactory
- * @see java.rmi.server.RMIServerSocketFactory
- * @see UnicastRemoteObject#exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory)
- */
- public void setClientSocketFactory(RMIClientSocketFactory clientSocketFactory) {
- this.clientSocketFactory = clientSocketFactory;
- }
-
- /**
- * Set a custom RMI server socket factory to use for exporting the service.
- *
Only needs to be specified when the client socket factory does not
- * implement {@code java.rmi.server.RMIServerSocketFactory} already.
- * @see #setClientSocketFactory
- * @see java.rmi.server.RMIClientSocketFactory
- * @see java.rmi.server.RMIServerSocketFactory
- * @see UnicastRemoteObject#exportObject(Remote, int, RMIClientSocketFactory, RMIServerSocketFactory)
- */
- public void setServerSocketFactory(RMIServerSocketFactory serverSocketFactory) {
- this.serverSocketFactory = serverSocketFactory;
- }
-
- /**
- * Specify the RMI registry to register the exported service with.
- * Typically used in combination with RmiRegistryFactoryBean.
- *
Alternatively, you can specify all registry properties locally.
- * This exporter will then try to locate the specified registry,
- * automatically creating a new local one if appropriate.
- *
Default is a local registry at the default port (1099),
- * created on the fly if necessary.
- * @see RmiRegistryFactoryBean
- * @see #setRegistryHost
- * @see #setRegistryPort
- * @see #setRegistryClientSocketFactory
- * @see #setRegistryServerSocketFactory
- */
- public void setRegistry(Registry registry) {
- this.registry = registry;
- }
-
- /**
- * Set the host of the registry for the exported RMI service,
- * i.e. {@code rmi://HOST:port/name}
- *
Default is localhost.
- */
- public void setRegistryHost(String registryHost) {
- this.registryHost = registryHost;
- }
-
- /**
- * Set the port of the registry for the exported RMI service,
- * i.e. {@code rmi://host:PORT/name}
- *
Default is {@code Registry.REGISTRY_PORT} (1099).
- * @see java.rmi.registry.Registry#REGISTRY_PORT
- */
- public void setRegistryPort(int registryPort) {
- this.registryPort = registryPort;
- }
-
- /**
- * Set a custom RMI client socket factory to use for the RMI registry.
- *
If the given object also implements {@code java.rmi.server.RMIServerSocketFactory},
- * it will automatically be registered as server socket factory too.
- * @see #setRegistryServerSocketFactory
- * @see java.rmi.server.RMIClientSocketFactory
- * @see java.rmi.server.RMIServerSocketFactory
- * @see LocateRegistry#getRegistry(String, int, RMIClientSocketFactory)
- */
- public void setRegistryClientSocketFactory(RMIClientSocketFactory registryClientSocketFactory) {
- this.registryClientSocketFactory = registryClientSocketFactory;
- }
-
- /**
- * Set a custom RMI server socket factory to use for the RMI registry.
- *
Only needs to be specified when the client socket factory does not
- * implement {@code java.rmi.server.RMIServerSocketFactory} already.
- * @see #setRegistryClientSocketFactory
- * @see java.rmi.server.RMIClientSocketFactory
- * @see java.rmi.server.RMIServerSocketFactory
- * @see LocateRegistry#createRegistry(int, RMIClientSocketFactory, RMIServerSocketFactory)
- */
- public void setRegistryServerSocketFactory(RMIServerSocketFactory registryServerSocketFactory) {
- this.registryServerSocketFactory = registryServerSocketFactory;
- }
-
- /**
- * Set whether to always create the registry in-process,
- * not attempting to locate an existing registry at the specified port.
- *
Default is "false". Switch this flag to "true" in order to avoid
- * the overhead of locating an existing registry when you always
- * intend to create a new registry in any case.
- */
- public void setAlwaysCreateRegistry(boolean alwaysCreateRegistry) {
- this.alwaysCreateRegistry = alwaysCreateRegistry;
- }
-
- /**
- * Set whether to replace an existing binding in the RMI registry,
- * that is, whether to simply override an existing binding with the
- * specified service in case of a naming conflict in the registry.
- *
Default is "true", assuming that an existing binding for this
- * exporter's service name is an accidental leftover from a previous
- * execution. Switch this to "false" to make the exporter fail in such
- * a scenario, indicating that there was already an RMI object bound.
- */
- public void setReplaceExistingBinding(boolean replaceExistingBinding) {
- this.replaceExistingBinding = replaceExistingBinding;
- }
-
-
- @Override
- public void afterPropertiesSet() throws RemoteException {
- prepare();
- }
-
- /**
- * Initialize this service exporter, registering the service as RMI object.
- *
Creates an RMI registry on the specified port if none exists.
- * @throws RemoteException if service registration failed
- */
- public void prepare() throws RemoteException {
- checkService();
-
- if (this.serviceName == null) {
- throw new IllegalArgumentException("Property 'serviceName' is required");
- }
-
- // Check socket factories for exported object.
- if (this.clientSocketFactory instanceof RMIServerSocketFactory) {
- this.serverSocketFactory = (RMIServerSocketFactory) this.clientSocketFactory;
- }
- if ((this.clientSocketFactory != null && this.serverSocketFactory == null) ||
- (this.clientSocketFactory == null && this.serverSocketFactory != null)) {
- throw new IllegalArgumentException(
- "Both RMIClientSocketFactory and RMIServerSocketFactory or none required");
- }
-
- // Check socket factories for RMI registry.
- if (this.registryClientSocketFactory instanceof RMIServerSocketFactory) {
- this.registryServerSocketFactory = (RMIServerSocketFactory) this.registryClientSocketFactory;
- }
- if (this.registryClientSocketFactory == null && this.registryServerSocketFactory != null) {
- throw new IllegalArgumentException(
- "RMIServerSocketFactory without RMIClientSocketFactory for registry not supported");
- }
-
- this.createdRegistry = false;
-
- // Determine RMI registry to use.
- if (this.registry == null) {
- this.registry = getRegistry(this.registryHost, this.registryPort,
- this.registryClientSocketFactory, this.registryServerSocketFactory);
- this.createdRegistry = true;
- }
-
- // Initialize and cache exported object.
- this.exportedObject = getObjectToExport();
-
- if (logger.isDebugEnabled()) {
- logger.debug("Binding service '" + this.serviceName + "' to RMI registry: " + this.registry);
- }
-
- // Export RMI object.
- if (this.clientSocketFactory != null) {
- UnicastRemoteObject.exportObject(
- this.exportedObject, this.servicePort, this.clientSocketFactory, this.serverSocketFactory);
- }
- else {
- UnicastRemoteObject.exportObject(this.exportedObject, this.servicePort);
- }
-
- // Bind RMI object to registry.
- try {
- if (this.replaceExistingBinding) {
- this.registry.rebind(this.serviceName, this.exportedObject);
- }
- else {
- this.registry.bind(this.serviceName, this.exportedObject);
- }
- }
- catch (AlreadyBoundException ex) {
- // Already an RMI object bound for the specified service name...
- unexportObjectSilently();
- throw new IllegalStateException(
- "Already an RMI object bound for name '" + this.serviceName + "': " + ex.toString());
- }
- catch (RemoteException ex) {
- // Registry binding failed: let's unexport the RMI object as well.
- unexportObjectSilently();
- throw ex;
- }
- }
-
-
- /**
- * Locate or create the RMI registry for this exporter.
- * @param registryHost the registry host to use (if this is specified,
- * no implicit creation of a RMI registry will happen)
- * @param registryPort the registry port to use
- * @param clientSocketFactory the RMI client socket factory for the registry (if any)
- * @param serverSocketFactory the RMI server socket factory for the registry (if any)
- * @return the RMI registry
- * @throws RemoteException if the registry couldn't be located or created
- */
- protected Registry getRegistry(String registryHost, int registryPort,
- @Nullable RMIClientSocketFactory clientSocketFactory, @Nullable RMIServerSocketFactory serverSocketFactory)
- throws RemoteException {
-
- if (registryHost != null) {
- // Host explicitly specified: only lookup possible.
- if (logger.isDebugEnabled()) {
- logger.debug("Looking for RMI registry at port '" + registryPort + "' of host [" + registryHost + "]");
- }
- Registry reg = LocateRegistry.getRegistry(registryHost, registryPort, clientSocketFactory);
- testRegistry(reg);
- return reg;
- }
-
- else {
- return getRegistry(registryPort, clientSocketFactory, serverSocketFactory);
- }
- }
-
- /**
- * Locate or create the RMI registry for this exporter.
- * @param registryPort the registry port to use
- * @param clientSocketFactory the RMI client socket factory for the registry (if any)
- * @param serverSocketFactory the RMI server socket factory for the registry (if any)
- * @return the RMI registry
- * @throws RemoteException if the registry couldn't be located or created
- */
- protected Registry getRegistry(int registryPort,
- @Nullable RMIClientSocketFactory clientSocketFactory, @Nullable RMIServerSocketFactory serverSocketFactory)
- throws RemoteException {
-
- if (clientSocketFactory != null) {
- if (this.alwaysCreateRegistry) {
- logger.debug("Creating new RMI registry");
- return LocateRegistry.createRegistry(registryPort, clientSocketFactory, serverSocketFactory);
- }
- if (logger.isDebugEnabled()) {
- logger.debug("Looking for RMI registry at port '" + registryPort + "', using custom socket factory");
- }
- synchronized (LocateRegistry.class) {
- try {
- // Retrieve existing registry.
- Registry reg = LocateRegistry.getRegistry(null, registryPort, clientSocketFactory);
- testRegistry(reg);
- return reg;
- }
- catch (RemoteException ex) {
- logger.trace("RMI registry access threw exception", ex);
- logger.debug("Could not detect RMI registry - creating new one");
- // Assume no registry found -> create new one.
- return LocateRegistry.createRegistry(registryPort, clientSocketFactory, serverSocketFactory);
- }
- }
- }
-
- else {
- return getRegistry(registryPort);
- }
- }
-
- /**
- * Locate or create the RMI registry for this exporter.
- * @param registryPort the registry port to use
- * @return the RMI registry
- * @throws RemoteException if the registry couldn't be located or created
- */
- protected Registry getRegistry(int registryPort) throws RemoteException {
- if (this.alwaysCreateRegistry) {
- logger.debug("Creating new RMI registry");
- return LocateRegistry.createRegistry(registryPort);
- }
- if (logger.isDebugEnabled()) {
- logger.debug("Looking for RMI registry at port '" + registryPort + "'");
- }
- synchronized (LocateRegistry.class) {
- try {
- // Retrieve existing registry.
- Registry reg = LocateRegistry.getRegistry(registryPort);
- testRegistry(reg);
- return reg;
- }
- catch (RemoteException ex) {
- logger.trace("RMI registry access threw exception", ex);
- logger.debug("Could not detect RMI registry - creating new one");
- // Assume no registry found -> create new one.
- return LocateRegistry.createRegistry(registryPort);
- }
- }
- }
-
- /**
- * Test the given RMI registry, calling some operation on it to
- * check whether it is still active.
- *
Default implementation calls {@code Registry.list()}.
- * @param registry the RMI registry to test
- * @throws RemoteException if thrown by registry methods
- * @see java.rmi.registry.Registry#list()
- */
- protected void testRegistry(Registry registry) throws RemoteException {
- registry.list();
- }
-
-
- /**
- * Unbind the RMI service from the registry on bean factory shutdown.
- */
- @Override
- public void destroy() throws RemoteException {
- if (logger.isDebugEnabled()) {
- logger.debug("Unbinding RMI service '" + this.serviceName +
- "' from registry" + (this.createdRegistry ? (" at port '" + this.registryPort + "'") : ""));
- }
- try {
- this.registry.unbind(this.serviceName);
- }
- catch (NotBoundException ex) {
- if (logger.isInfoEnabled()) {
- logger.info("RMI service '" + this.serviceName + "' is not bound to registry" +
- (this.createdRegistry ? (" at port '" + this.registryPort + "' anymore") : ""), ex);
- }
- }
- finally {
- unexportObjectSilently();
- }
- }
-
- /**
- * Unexport the registered RMI object, logging any exception that arises.
- */
- private void unexportObjectSilently() {
- try {
- UnicastRemoteObject.unexportObject(this.exportedObject, true);
- }
- catch (NoSuchObjectException ex) {
- if (logger.isInfoEnabled()) {
- logger.info("RMI object for service '" + this.serviceName + "' is not exported anymore", ex);
- }
- }
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/rmi/package-info.java b/spring-context/src/main/java/org/springframework/remoting/rmi/package-info.java
deleted file mode 100644
index 8296464c34..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/rmi/package-info.java
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * Remoting classes for conventional RMI and transparent remoting via
- * RMI invokers. Provides a proxy factory for accessing RMI services,
- * and an exporter for making beans available to RMI clients.
- */
-package org.springframework.remoting.rmi;
diff --git a/spring-context/src/main/java/org/springframework/remoting/soap/SoapFaultException.java b/spring-context/src/main/java/org/springframework/remoting/soap/SoapFaultException.java
deleted file mode 100644
index 175c351cf3..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/soap/SoapFaultException.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.soap;
-
-import javax.xml.namespace.QName;
-
-import org.springframework.remoting.RemoteInvocationFailureException;
-
-/**
- * RemoteInvocationFailureException subclass that provides the details
- * of a SOAP fault.
- *
- * @author Juergen Hoeller
- * @since 2.5
- * @see javax.xml.rpc.soap.SOAPFaultException
- * @see javax.xml.ws.soap.SOAPFaultException
- */
-@SuppressWarnings("serial")
-public abstract class SoapFaultException extends RemoteInvocationFailureException {
-
- /**
- * Constructor for SoapFaultException.
- * @param msg the detail message
- * @param cause the root cause from the SOAP API in use
- */
- protected SoapFaultException(String msg, Throwable cause) {
- super(msg, cause);
- }
-
-
- /**
- * Return the SOAP fault code.
- */
- public abstract String getFaultCode();
-
- /**
- * Return the SOAP fault code as a {@code QName} object.
- */
- public abstract QName getFaultCodeAsQName();
-
- /**
- * Return the descriptive SOAP fault string.
- */
- public abstract String getFaultString();
-
- /**
- * Return the actor that caused this fault.
- */
- public abstract String getFaultActor();
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/soap/package-info.java b/spring-context/src/main/java/org/springframework/remoting/soap/package-info.java
deleted file mode 100644
index e1e1107409..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/soap/package-info.java
+++ /dev/null
@@ -1,4 +0,0 @@
-/**
- * SOAP-specific exceptions and support classes for Spring's remoting subsystem.
- */
-package org.springframework.remoting.soap;
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/DefaultRemoteInvocationExecutor.java b/spring-context/src/main/java/org/springframework/remoting/support/DefaultRemoteInvocationExecutor.java
deleted file mode 100644
index 870fe87ff1..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/DefaultRemoteInvocationExecutor.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import java.lang.reflect.InvocationTargetException;
-
-import org.springframework.util.Assert;
-
-/**
- * Default implementation of the {@link RemoteInvocationExecutor} interface.
- * Simply delegates to {@link RemoteInvocation}'s invoke method.
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @see RemoteInvocation#invoke
- */
-public class DefaultRemoteInvocationExecutor implements RemoteInvocationExecutor {
-
- @Override
- public Object invoke(RemoteInvocation invocation, Object targetObject)
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException{
-
- Assert.notNull(invocation, "RemoteInvocation must not be null");
- Assert.notNull(targetObject, "Target object must not be null");
- return invocation.invoke(targetObject);
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/DefaultRemoteInvocationFactory.java b/spring-context/src/main/java/org/springframework/remoting/support/DefaultRemoteInvocationFactory.java
deleted file mode 100644
index 10f3ab184a..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/DefaultRemoteInvocationFactory.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import org.aopalliance.intercept.MethodInvocation;
-
-/**
- * Default implementation of the {@link RemoteInvocationFactory} interface.
- * Simply creates a new standard {@link RemoteInvocation} object.
- *
- * @author Juergen Hoeller
- * @since 1.1
- */
-public class DefaultRemoteInvocationFactory implements RemoteInvocationFactory {
-
- @Override
- public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) {
- return new RemoteInvocation(methodInvocation);
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteAccessor.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteAccessor.java
deleted file mode 100644
index f26ca9a849..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteAccessor.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2002-2017 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import org.springframework.util.Assert;
-
-/**
- * Abstract base class for classes that access a remote service.
- * Provides a "serviceInterface" bean property.
- *
- *
Note that the service interface being used will show some signs of
- * remotability, like the granularity of method calls that it offers.
- * Furthermore, it has to have serializable arguments etc.
- *
- *
Accessors are supposed to throw Spring's generic
- * {@link org.springframework.remoting.RemoteAccessException} in case
- * of remote invocation failure, provided that the service interface
- * does not declare {@code java.rmi.RemoteException}.
- *
- * @author Juergen Hoeller
- * @since 13.05.2003
- * @see org.springframework.remoting.RemoteAccessException
- * @see java.rmi.RemoteException
- */
-public abstract class RemoteAccessor extends RemotingSupport {
-
- private Class> serviceInterface;
-
-
- /**
- * Set the interface of the service to access.
- * The interface must be suitable for the particular service and remoting strategy.
- *
Typically required to be able to create a suitable service proxy,
- * but can also be optional if the lookup returns a typed proxy.
- */
- public void setServiceInterface(Class> serviceInterface) {
- Assert.notNull(serviceInterface, "'serviceInterface' must not be null");
- Assert.isTrue(serviceInterface.isInterface(), "'serviceInterface' must be an interface");
- this.serviceInterface = serviceInterface;
- }
-
- /**
- * Return the interface of the service to access.
- */
- public Class> getServiceInterface() {
- return this.serviceInterface;
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteExporter.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteExporter.java
deleted file mode 100644
index 2c590ff548..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteExporter.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright 2002-2017 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import org.springframework.aop.framework.ProxyFactory;
-import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry;
-import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-
-/**
- * Abstract base class for classes that export a remote service.
- * Provides "service" and "serviceInterface" bean properties.
- *
- *
Note that the service interface being used will show some signs of
- * remotability, like the granularity of method calls that it offers.
- * Furthermore, it has to have serializable arguments etc.
- *
- * @author Juergen Hoeller
- * @since 26.12.2003
- */
-public abstract class RemoteExporter extends RemotingSupport {
-
- private Object service;
-
- private Class> serviceInterface;
-
- private Boolean registerTraceInterceptor;
-
- private Object[] interceptors;
-
-
- /**
- * Set the service to export.
- * Typically populated via a bean reference.
- */
- public void setService(Object service) {
- this.service = service;
- }
-
- /**
- * Return the service to export.
- */
- public Object getService() {
- return this.service;
- }
-
- /**
- * Set the interface of the service to export.
- * The interface must be suitable for the particular service and remoting strategy.
- */
- public void setServiceInterface(Class> serviceInterface) {
- Assert.notNull(serviceInterface, "'serviceInterface' must not be null");
- Assert.isTrue(serviceInterface.isInterface(), "'serviceInterface' must be an interface");
- this.serviceInterface = serviceInterface;
- }
-
- /**
- * Return the interface of the service to export.
- */
- public Class> getServiceInterface() {
- return this.serviceInterface;
- }
-
- /**
- * Set whether to register a RemoteInvocationTraceInterceptor for exported
- * services. Only applied when a subclass uses {@code getProxyForService}
- * for creating the proxy to expose.
- *
Default is "true". RemoteInvocationTraceInterceptor's most important value
- * is that it logs exception stacktraces on the server, before propagating an
- * exception to the client. Note that RemoteInvocationTraceInterceptor will not
- * be registered by default if the "interceptors" property has been specified.
- * @see #setInterceptors
- * @see #getProxyForService
- * @see RemoteInvocationTraceInterceptor
- */
- public void setRegisterTraceInterceptor(boolean registerTraceInterceptor) {
- this.registerTraceInterceptor = registerTraceInterceptor;
- }
-
- /**
- * Set additional interceptors (or advisors) to be applied before the
- * remote endpoint, e.g. a PerformanceMonitorInterceptor.
- *
You may specify any AOP Alliance MethodInterceptors or other
- * Spring AOP Advices, as well as Spring AOP Advisors.
- * @see #getProxyForService
- * @see org.springframework.aop.interceptor.PerformanceMonitorInterceptor
- */
- public void setInterceptors(Object[] interceptors) {
- this.interceptors = interceptors;
- }
-
-
- /**
- * Check whether the service reference has been set.
- * @see #setService
- */
- protected void checkService() throws IllegalArgumentException {
- Assert.notNull(getService(), "Property 'service' is required");
- }
-
- /**
- * Check whether a service reference has been set,
- * and whether it matches the specified service.
- * @see #setServiceInterface
- * @see #setService
- */
- protected void checkServiceInterface() throws IllegalArgumentException {
- Class> serviceInterface = getServiceInterface();
- Assert.notNull(serviceInterface, "Property 'serviceInterface' is required");
-
- Object service = getService();
- if (service instanceof String) {
- throw new IllegalArgumentException("Service [" + service + "] is a String " +
- "rather than an actual service reference: Have you accidentally specified " +
- "the service bean name as value instead of as reference?");
- }
- if (!serviceInterface.isInstance(service)) {
- throw new IllegalArgumentException("Service interface [" + serviceInterface.getName() +
- "] needs to be implemented by service [" + service + "] of class [" +
- service.getClass().getName() + "]");
- }
- }
-
- /**
- * Get a proxy for the given service object, implementing the specified
- * service interface.
- *
Used to export a proxy that does not expose any internals but just
- * a specific interface intended for remote access. Furthermore, a
- * {@link RemoteInvocationTraceInterceptor} will be registered (by default).
- * @return the proxy
- * @see #setServiceInterface
- * @see #setRegisterTraceInterceptor
- * @see RemoteInvocationTraceInterceptor
- */
- protected Object getProxyForService() {
- checkService();
- checkServiceInterface();
-
- ProxyFactory proxyFactory = new ProxyFactory();
- proxyFactory.addInterface(getServiceInterface());
-
- if (this.registerTraceInterceptor != null ? this.registerTraceInterceptor : this.interceptors == null) {
- proxyFactory.addAdvice(new RemoteInvocationTraceInterceptor(getExporterName()));
- }
- if (this.interceptors != null) {
- AdvisorAdapterRegistry adapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
- for (Object interceptor : this.interceptors) {
- proxyFactory.addAdvisor(adapterRegistry.wrap(interceptor));
- }
- }
-
- proxyFactory.setTarget(getService());
- proxyFactory.setOpaque(true);
-
- return proxyFactory.getProxy(getBeanClassLoader());
- }
-
- /**
- * Return a short name for this exporter.
- * Used for tracing of remote invocations.
- *
Default is the unqualified class name (without package).
- * Can be overridden in subclasses.
- * @see #getProxyForService
- * @see RemoteInvocationTraceInterceptor
- * @see org.springframework.util.ClassUtils#getShortName
- */
- protected String getExporterName() {
- return ClassUtils.getShortName(getClass());
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocation.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocation.java
deleted file mode 100644
index fec43c6bb2..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocation.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.aopalliance.intercept.MethodInvocation;
-
-import org.springframework.lang.Nullable;
-import org.springframework.util.ClassUtils;
-
-/**
- * Encapsulates a remote invocation, providing core method invocation properties
- * in a serializable fashion. Used for RMI and HTTP-based serialization invokers.
- *
- *
This is an SPI class, typically not used directly by applications.
- * Can be subclassed for additional invocation parameters.
- *
- *
Both {@link RemoteInvocation} and {@link RemoteInvocationResult} are designed
- * for use with standard Java serialization as well as JavaBean-style serialization.
- *
- * @author Juergen Hoeller
- * @since 25.02.2004
- * @see RemoteInvocationResult
- * @see RemoteInvocationFactory
- * @see RemoteInvocationExecutor
- * @see org.springframework.remoting.rmi.RmiProxyFactoryBean
- * @see org.springframework.remoting.rmi.RmiServiceExporter
- * @see org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean
- * @see org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter
- */
-public class RemoteInvocation implements Serializable {
-
- /** use serialVersionUID from Spring 1.1 for interoperability. */
- private static final long serialVersionUID = 6876024250231820554L;
-
-
- private String methodName;
-
- private Class>[] parameterTypes;
-
- private Object[] arguments;
-
- private Map attributes;
-
-
- /**
- * Create a new RemoteInvocation for the given AOP method invocation.
- * @param methodInvocation the AOP invocation to convert
- */
- public RemoteInvocation(MethodInvocation methodInvocation) {
- this.methodName = methodInvocation.getMethod().getName();
- this.parameterTypes = methodInvocation.getMethod().getParameterTypes();
- this.arguments = methodInvocation.getArguments();
- }
-
- /**
- * Create a new RemoteInvocation for the given parameters.
- * @param methodName the name of the method to invoke
- * @param parameterTypes the parameter types of the method
- * @param arguments the arguments for the invocation
- */
- public RemoteInvocation(String methodName, Class>[] parameterTypes, Object[] arguments) {
- this.methodName = methodName;
- this.parameterTypes = parameterTypes;
- this.arguments = arguments;
- }
-
- /**
- * Create a new RemoteInvocation for JavaBean-style deserialization
- * (e.g. with Jackson).
- */
- public RemoteInvocation() {
- }
-
-
- /**
- * Set the name of the target method.
- * This setter is intended for JavaBean-style deserialization.
- */
- public void setMethodName(String methodName) {
- this.methodName = methodName;
- }
-
- /**
- * Return the name of the target method.
- */
- public String getMethodName() {
- return this.methodName;
- }
-
- /**
- * Set the parameter types of the target method.
- *
This setter is intended for JavaBean-style deserialization.
- */
- public void setParameterTypes(Class>[] parameterTypes) {
- this.parameterTypes = parameterTypes;
- }
-
- /**
- * Return the parameter types of the target method.
- */
- public Class>[] getParameterTypes() {
- return this.parameterTypes;
- }
-
- /**
- * Set the arguments for the target method call.
- *
This setter is intended for JavaBean-style deserialization.
- */
- public void setArguments(Object[] arguments) {
- this.arguments = arguments;
- }
-
- /**
- * Return the arguments for the target method call.
- */
- public Object[] getArguments() {
- return this.arguments;
- }
-
-
- /**
- * Add an additional invocation attribute. Useful to add additional
- * invocation context without having to subclass RemoteInvocation.
- *
Attribute keys have to be unique, and no overriding of existing
- * attributes is allowed.
- *
The implementation avoids to unnecessarily create the attributes
- * Map, to minimize serialization size.
- * @param key the attribute key
- * @param value the attribute value
- * @throws IllegalStateException if the key is already bound
- */
- public void addAttribute(String key, Serializable value) throws IllegalStateException {
- if (this.attributes == null) {
- this.attributes = new HashMap<>();
- }
- if (this.attributes.containsKey(key)) {
- throw new IllegalStateException("There is already an attribute with key '" + key + "' bound");
- }
- this.attributes.put(key, value);
- }
-
- /**
- * Retrieve the attribute for the given key, if any.
- *
The implementation avoids to unnecessarily create the attributes
- * Map, to minimize serialization size.
- * @param key the attribute key
- * @return the attribute value, or {@code null} if not defined
- */
- @Nullable
- public Serializable getAttribute(String key) {
- if (this.attributes == null) {
- return null;
- }
- return this.attributes.get(key);
- }
-
- /**
- * Set the attributes Map. Only here for special purposes:
- * Preferably, use {@link #addAttribute} and {@link #getAttribute}.
- * @param attributes the attributes Map
- * @see #addAttribute
- * @see #getAttribute
- */
- public void setAttributes(@Nullable Map attributes) {
- this.attributes = attributes;
- }
-
- /**
- * Return the attributes Map. Mainly here for debugging purposes:
- * Preferably, use {@link #addAttribute} and {@link #getAttribute}.
- * @return the attributes Map, or {@code null} if none created
- * @see #addAttribute
- * @see #getAttribute
- */
- @Nullable
- public Map getAttributes() {
- return this.attributes;
- }
-
-
- /**
- * Perform this invocation on the given target object.
- * Typically called when a RemoteInvocation is received on the server.
- * @param targetObject the target object to apply the invocation to
- * @return the invocation result
- * @throws NoSuchMethodException if the method name could not be resolved
- * @throws IllegalAccessException if the method could not be accessed
- * @throws InvocationTargetException if the method invocation resulted in an exception
- * @see java.lang.reflect.Method#invoke
- */
- public Object invoke(Object targetObject)
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-
- Method method = targetObject.getClass().getMethod(this.methodName, this.parameterTypes);
- return method.invoke(targetObject, this.arguments);
- }
-
-
- @Override
- public String toString() {
- return "RemoteInvocation: method name '" + this.methodName + "'; parameter types " +
- ClassUtils.classNamesToString(this.parameterTypes);
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationBasedAccessor.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationBasedAccessor.java
deleted file mode 100644
index c7f58152c0..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationBasedAccessor.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright 2002-2020 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import org.aopalliance.intercept.MethodInvocation;
-
-import org.springframework.lang.Nullable;
-
-/**
- * Abstract base class for remote service accessors that are based
- * on serialization of {@link RemoteInvocation} objects.
- *
- * Provides a "remoteInvocationFactory" property, with a
- * {@link DefaultRemoteInvocationFactory} as default strategy.
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @see #setRemoteInvocationFactory
- * @see RemoteInvocation
- * @see RemoteInvocationFactory
- * @see DefaultRemoteInvocationFactory
- */
-public abstract class RemoteInvocationBasedAccessor extends UrlBasedRemoteAccessor {
-
- private RemoteInvocationFactory remoteInvocationFactory = new DefaultRemoteInvocationFactory();
-
-
- /**
- * Set the RemoteInvocationFactory to use for this accessor.
- * Default is a {@link DefaultRemoteInvocationFactory}.
- * A custom invocation factory can add further context information
- * to the invocation, for example user credentials.
- */
- public void setRemoteInvocationFactory(RemoteInvocationFactory remoteInvocationFactory) {
- this.remoteInvocationFactory =
- (remoteInvocationFactory != null ? remoteInvocationFactory : new DefaultRemoteInvocationFactory());
- }
-
- /**
- * Return the RemoteInvocationFactory used by this accessor.
- */
- public RemoteInvocationFactory getRemoteInvocationFactory() {
- return this.remoteInvocationFactory;
- }
-
- /**
- * Create a new RemoteInvocation object for the given AOP method invocation.
- *
The default implementation delegates to the configured
- * {@link #setRemoteInvocationFactory RemoteInvocationFactory}.
- * This can be overridden in subclasses in order to provide custom RemoteInvocation
- * subclasses, containing additional invocation parameters (e.g. user credentials).
- *
Note that it is preferable to build a custom RemoteInvocationFactory
- * as a reusable strategy, instead of overriding this method.
- * @param methodInvocation the current AOP method invocation
- * @return the RemoteInvocation object
- * @see RemoteInvocationFactory#createRemoteInvocation
- */
- protected RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) {
- return getRemoteInvocationFactory().createRemoteInvocation(methodInvocation);
- }
-
- /**
- * Recreate the invocation result contained in the given RemoteInvocationResult object.
- *
The default implementation calls the default {@code recreate()} method.
- * This can be overridden in subclass to provide custom recreation, potentially
- * processing the returned result object.
- * @param result the RemoteInvocationResult to recreate
- * @return a return value if the invocation result is a successful return
- * @throws Throwable if the invocation result is an exception
- * @see RemoteInvocationResult#recreate()
- */
- @Nullable
- protected Object recreateRemoteInvocationResult(RemoteInvocationResult result) throws Throwable {
- return result.recreate();
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationBasedExporter.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationBasedExporter.java
deleted file mode 100644
index a25aae4a74..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationBasedExporter.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import java.lang.reflect.InvocationTargetException;
-
-/**
- * Abstract base class for remote service exporters that are based
- * on deserialization of {@link RemoteInvocation} objects.
- *
- *
Provides a "remoteInvocationExecutor" property, with a
- * {@link DefaultRemoteInvocationExecutor} as default strategy.
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @see RemoteInvocationExecutor
- * @see DefaultRemoteInvocationExecutor
- */
-public abstract class RemoteInvocationBasedExporter extends RemoteExporter {
-
- private RemoteInvocationExecutor remoteInvocationExecutor = new DefaultRemoteInvocationExecutor();
-
-
- /**
- * Set the RemoteInvocationExecutor to use for this exporter.
- * Default is a DefaultRemoteInvocationExecutor.
- *
A custom invocation executor can extract further context information
- * from the invocation, for example user credentials.
- */
- public void setRemoteInvocationExecutor(RemoteInvocationExecutor remoteInvocationExecutor) {
- this.remoteInvocationExecutor = remoteInvocationExecutor;
- }
-
- /**
- * Return the RemoteInvocationExecutor used by this exporter.
- */
- public RemoteInvocationExecutor getRemoteInvocationExecutor() {
- return this.remoteInvocationExecutor;
- }
-
-
- /**
- * Apply the given remote invocation to the given target object.
- * The default implementation delegates to the RemoteInvocationExecutor.
- *
Can be overridden in subclasses for custom invocation behavior,
- * possibly for applying additional invocation parameters from a
- * custom RemoteInvocation subclass. Note that it is preferable to use
- * a custom RemoteInvocationExecutor which is a reusable strategy.
- * @param invocation the remote invocation
- * @param targetObject the target object to apply the invocation to
- * @return the invocation result
- * @throws NoSuchMethodException if the method name could not be resolved
- * @throws IllegalAccessException if the method could not be accessed
- * @throws InvocationTargetException if the method invocation resulted in an exception
- * @see RemoteInvocationExecutor#invoke
- */
- protected Object invoke(RemoteInvocation invocation, Object targetObject)
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
-
- if (logger.isTraceEnabled()) {
- logger.trace("Executing " + invocation);
- }
- try {
- return getRemoteInvocationExecutor().invoke(invocation, targetObject);
- }
- catch (NoSuchMethodException ex) {
- if (logger.isDebugEnabled()) {
- logger.debug("Could not find target method for " + invocation, ex);
- }
- throw ex;
- }
- catch (IllegalAccessException ex) {
- if (logger.isDebugEnabled()) {
- logger.debug("Could not access target method for " + invocation, ex);
- }
- throw ex;
- }
- catch (InvocationTargetException ex) {
- if (logger.isDebugEnabled()) {
- logger.debug("Target method failed for " + invocation, ex.getTargetException());
- }
- throw ex;
- }
- }
-
- /**
- * Apply the given remote invocation to the given target object, wrapping
- * the invocation result in a serializable RemoteInvocationResult object.
- * The default implementation creates a plain RemoteInvocationResult.
- *
Can be overridden in subclasses for custom invocation behavior,
- * for example to return additional context information. Note that this
- * is not covered by the RemoteInvocationExecutor strategy!
- * @param invocation the remote invocation
- * @param targetObject the target object to apply the invocation to
- * @return the invocation result
- * @see #invoke
- */
- protected RemoteInvocationResult invokeAndCreateResult(RemoteInvocation invocation, Object targetObject) {
- try {
- Object value = invoke(invocation, targetObject);
- return new RemoteInvocationResult(value);
- }
- catch (Throwable ex) {
- return new RemoteInvocationResult(ex);
- }
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationExecutor.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationExecutor.java
deleted file mode 100644
index 02d456b3a4..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationExecutor.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright 2002-2007 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import java.lang.reflect.InvocationTargetException;
-
-/**
- * Strategy interface for executing a {@link RemoteInvocation} on a target object.
- *
- *
Used by {@link org.springframework.remoting.rmi.RmiServiceExporter} (for RMI invokers)
- * and by {@link org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter}.
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @see DefaultRemoteInvocationFactory
- * @see org.springframework.remoting.rmi.RmiServiceExporter#setRemoteInvocationExecutor
- * @see org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter#setRemoteInvocationExecutor
- */
-public interface RemoteInvocationExecutor {
-
- /**
- * Perform this invocation on the given target object.
- * Typically called when a RemoteInvocation is received on the server.
- * @param invocation the RemoteInvocation
- * @param targetObject the target object to apply the invocation to
- * @return the invocation result
- * @throws NoSuchMethodException if the method name could not be resolved
- * @throws IllegalAccessException if the method could not be accessed
- * @throws InvocationTargetException if the method invocation resulted in an exception
- * @see java.lang.reflect.Method#invoke
- */
- Object invoke(RemoteInvocation invocation, Object targetObject)
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException;
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationFactory.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationFactory.java
deleted file mode 100644
index 5fba21f81b..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationFactory.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2002-2007 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import org.aopalliance.intercept.MethodInvocation;
-
-/**
- * Strategy interface for creating a {@link RemoteInvocation} from an AOP Alliance
- * {@link org.aopalliance.intercept.MethodInvocation}.
- *
- *
Used by {@link org.springframework.remoting.rmi.RmiClientInterceptor} (for RMI invokers)
- * and by {@link org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor}.
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @see DefaultRemoteInvocationFactory
- * @see org.springframework.remoting.rmi.RmiClientInterceptor#setRemoteInvocationFactory
- * @see org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor#setRemoteInvocationFactory
- */
-public interface RemoteInvocationFactory {
-
- /**
- * Create a serializable RemoteInvocation object from the given AOP
- * MethodInvocation.
- *
Can be implemented to add custom context information to the
- * remote invocation, for example user credentials.
- * @param methodInvocation the original AOP MethodInvocation object
- * @return the RemoteInvocation object
- */
- RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation);
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationResult.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationResult.java
deleted file mode 100644
index 76de6b8b4a..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationResult.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-
-import org.springframework.lang.Nullable;
-
-/**
- * Encapsulates a remote invocation result, holding a result value or an exception.
- * Used for HTTP-based serialization invokers.
- *
- *
This is an SPI class, typically not used directly by applications.
- * Can be subclassed for additional invocation parameters.
- *
- *
Both {@link RemoteInvocation} and {@link RemoteInvocationResult} are designed
- * for use with standard Java serialization as well as JavaBean-style serialization.
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @see RemoteInvocation
- */
-public class RemoteInvocationResult implements Serializable {
-
- /** Use serialVersionUID from Spring 1.1 for interoperability. */
- private static final long serialVersionUID = 2138555143707773549L;
-
-
- @Nullable
- private Object value;
-
- @Nullable
- private Throwable exception;
-
-
- /**
- * Create a new RemoteInvocationResult for the given result value.
- * @param value the result value returned by a successful invocation
- * of the target method
- */
- public RemoteInvocationResult(@Nullable Object value) {
- this.value = value;
- }
-
- /**
- * Create a new RemoteInvocationResult for the given exception.
- * @param exception the exception thrown by an unsuccessful invocation
- * of the target method
- */
- public RemoteInvocationResult(@Nullable Throwable exception) {
- this.exception = exception;
- }
-
- /**
- * Create a new RemoteInvocationResult for JavaBean-style deserialization
- * (e.g. with Jackson).
- * @see #setValue
- * @see #setException
- */
- public RemoteInvocationResult() {
- }
-
-
- /**
- * Set the result value returned by a successful invocation of the
- * target method, if any.
- *
This setter is intended for JavaBean-style deserialization.
- * Use {@link #RemoteInvocationResult(Object)} otherwise.
- * @see #RemoteInvocationResult()
- */
- public void setValue(@Nullable Object value) {
- this.value = value;
- }
-
- /**
- * Return the result value returned by a successful invocation
- * of the target method, if any.
- * @see #hasException
- */
- @Nullable
- public Object getValue() {
- return this.value;
- }
-
- /**
- * Set the exception thrown by an unsuccessful invocation of the
- * target method, if any.
- *
This setter is intended for JavaBean-style deserialization.
- * Use {@link #RemoteInvocationResult(Throwable)} otherwise.
- * @see #RemoteInvocationResult()
- */
- public void setException(@Nullable Throwable exception) {
- this.exception = exception;
- }
-
- /**
- * Return the exception thrown by an unsuccessful invocation
- * of the target method, if any.
- * @see #hasException
- */
- @Nullable
- public Throwable getException() {
- return this.exception;
- }
-
- /**
- * Return whether this invocation result holds an exception.
- * If this returns {@code false}, the result value applies
- * (even if it is {@code null}).
- * @see #getValue
- * @see #getException
- */
- public boolean hasException() {
- return (this.exception != null);
- }
-
- /**
- * Return whether this invocation result holds an InvocationTargetException,
- * thrown by an invocation of the target method itself.
- * @see #hasException()
- */
- public boolean hasInvocationTargetException() {
- return (this.exception instanceof InvocationTargetException);
- }
-
-
- /**
- * Recreate the invocation result, either returning the result value
- * in case of a successful invocation of the target method, or
- * rethrowing the exception thrown by the target method.
- * @return the result value, if any
- * @throws Throwable the exception, if any
- */
- @Nullable
- public Object recreate() throws Throwable {
- if (this.exception != null) {
- Throwable exToThrow = this.exception;
- if (this.exception instanceof InvocationTargetException) {
- exToThrow = ((InvocationTargetException) this.exception).getTargetException();
- }
- RemoteInvocationUtils.fillInClientStackTraceIfPossible(exToThrow);
- throw exToThrow;
- }
- else {
- return this.value;
- }
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationTraceInterceptor.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationTraceInterceptor.java
deleted file mode 100644
index 2d5dc8e392..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationTraceInterceptor.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2002-2020 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import java.lang.reflect.Method;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.lang.Nullable;
-import org.springframework.util.ClassUtils;
-
-/**
- * AOP Alliance MethodInterceptor for tracing remote invocations.
- * Automatically applied by RemoteExporter and its subclasses.
- *
- *
Logs an incoming remote call as well as the finished processing of a remote call
- * at DEBUG level. If the processing of a remote call results in a checked exception,
- * the exception will get logged at INFO level; if it results in an unchecked
- * exception (or error), the exception will get logged at WARN level.
- *
- *
The logging of exceptions is particularly useful to save the stacktrace
- * information on the server-side rather than just propagating the exception
- * to the client (who might or might not log it properly).
- *
- * @author Juergen Hoeller
- * @since 1.2
- * @see RemoteExporter#setRegisterTraceInterceptor
- * @see RemoteExporter#getProxyForService
- */
-public class RemoteInvocationTraceInterceptor implements MethodInterceptor {
-
- protected static final Log logger = LogFactory.getLog(RemoteInvocationTraceInterceptor.class);
-
- private final String exporterNameClause;
-
-
- /**
- * Create a new RemoteInvocationTraceInterceptor.
- */
- public RemoteInvocationTraceInterceptor() {
- this.exporterNameClause = "";
- }
-
- /**
- * Create a new RemoteInvocationTraceInterceptor.
- * @param exporterName the name of the remote exporter
- * (to be used as context information in log messages)
- */
- public RemoteInvocationTraceInterceptor(String exporterName) {
- this.exporterNameClause = exporterName + " ";
- }
-
-
- @Override
- @Nullable
- public Object invoke(MethodInvocation invocation) throws Throwable {
- Method method = invocation.getMethod();
- if (logger.isDebugEnabled()) {
- logger.debug("Incoming " + this.exporterNameClause + "remote call: " +
- ClassUtils.getQualifiedMethodName(method));
- }
- try {
- Object retVal = invocation.proceed();
- if (logger.isDebugEnabled()) {
- logger.debug("Finished processing of " + this.exporterNameClause + "remote call: " +
- ClassUtils.getQualifiedMethodName(method));
- }
- return retVal;
- }
- catch (Throwable ex) {
- if (ex instanceof RuntimeException || ex instanceof Error) {
- if (logger.isWarnEnabled()) {
- logger.warn("Processing of " + this.exporterNameClause + "remote call resulted in fatal exception: " +
- ClassUtils.getQualifiedMethodName(method), ex);
- }
- }
- else {
- if (logger.isInfoEnabled()) {
- logger.info("Processing of " + this.exporterNameClause + "remote call resulted in exception: " +
- ClassUtils.getQualifiedMethodName(method), ex);
- }
- }
- throw ex;
- }
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationUtils.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationUtils.java
deleted file mode 100644
index 612b73c2e9..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationUtils.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2002-2016 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * General utilities for handling remote invocations.
- *
- *
Mainly intended for use within the remoting framework.
- *
- * @author Juergen Hoeller
- * @since 2.0
- */
-public abstract class RemoteInvocationUtils {
-
- /**
- * Fill the current client-side stack trace into the given exception.
- *
The given exception is typically thrown on the server and serialized
- * as-is, with the client wanting it to contain the client-side portion
- * of the stack trace as well. What we can do here is to update the
- * {@code StackTraceElement} array with the current client-side stack
- * trace, provided that we run on JDK 1.4+.
- * @param ex the exception to update
- * @see Throwable#getStackTrace()
- * @see Throwable#setStackTrace(StackTraceElement[])
- */
- public static void fillInClientStackTraceIfPossible(Throwable ex) {
- if (ex != null) {
- StackTraceElement[] clientStack = new Throwable().getStackTrace();
- Set visitedExceptions = new HashSet<>();
- Throwable exToUpdate = ex;
- while (exToUpdate != null && !visitedExceptions.contains(exToUpdate)) {
- StackTraceElement[] serverStack = exToUpdate.getStackTrace();
- StackTraceElement[] combinedStack = new StackTraceElement[serverStack.length + clientStack.length];
- System.arraycopy(serverStack, 0, combinedStack, 0, serverStack.length);
- System.arraycopy(clientStack, 0, combinedStack, serverStack.length, clientStack.length);
- exToUpdate.setStackTrace(combinedStack);
- visitedExceptions.add(exToUpdate);
- exToUpdate = exToUpdate.getCause();
- }
- }
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemotingSupport.java b/spring-context/src/main/java/org/springframework/remoting/support/RemotingSupport.java
deleted file mode 100644
index 51acfdf4f4..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/RemotingSupport.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.beans.factory.BeanClassLoaderAware;
-import org.springframework.lang.Nullable;
-import org.springframework.util.ClassUtils;
-
-/**
- * Generic support base class for remote accessor and exporters,
- * providing common bean ClassLoader handling.
- *
- * @author Juergen Hoeller
- * @since 2.5.2
- */
-public abstract class RemotingSupport implements BeanClassLoaderAware {
-
- /** Logger available to subclasses. */
- protected final Log logger = LogFactory.getLog(getClass());
-
- private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
-
-
- @Override
- public void setBeanClassLoader(ClassLoader classLoader) {
- this.beanClassLoader = classLoader;
- }
-
- /**
- * Return the ClassLoader that this accessor operates in,
- * to be used for deserializing and for generating proxies.
- */
- protected ClassLoader getBeanClassLoader() {
- return this.beanClassLoader;
- }
-
-
- /**
- * Override the thread context ClassLoader with the environment's bean ClassLoader
- * if necessary, i.e. if the bean ClassLoader is not equivalent to the thread
- * context ClassLoader already.
- * @return the original thread context ClassLoader, or {@code null} if not overridden
- */
- @Nullable
- protected ClassLoader overrideThreadContextClassLoader() {
- return ClassUtils.overrideThreadContextClassLoader(getBeanClassLoader());
- }
-
- /**
- * Reset the original thread context ClassLoader if necessary.
- * @param original the original thread context ClassLoader,
- * or {@code null} if not overridden (and hence nothing to reset)
- */
- protected void resetThreadContextClassLoader(@Nullable ClassLoader original) {
- if (original != null) {
- Thread.currentThread().setContextClassLoader(original);
- }
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/SimpleHttpServerFactoryBean.java b/spring-context/src/main/java/org/springframework/remoting/support/SimpleHttpServerFactoryBean.java
deleted file mode 100644
index f72fb9fdba..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/SimpleHttpServerFactoryBean.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executor;
-
-import com.sun.net.httpserver.Authenticator;
-import com.sun.net.httpserver.Filter;
-import com.sun.net.httpserver.HttpContext;
-import com.sun.net.httpserver.HttpHandler;
-import com.sun.net.httpserver.HttpServer;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.InitializingBean;
-
-/**
- * {@link org.springframework.beans.factory.FactoryBean} that creates a simple
- * HTTP server, based on the HTTP server that is included in Sun's JRE 1.6.
- * Starts the HTTP server on initialization and stops it on destruction.
- * Exposes the resulting {@link com.sun.net.httpserver.HttpServer} object.
- *
- * Allows for registering {@link com.sun.net.httpserver.HttpHandler HttpHandlers}
- * for specific {@link #setContexts context paths}. Alternatively,
- * register such context-specific handlers programmatically on the
- * {@link com.sun.net.httpserver.HttpServer} itself.
- *
- * @author Juergen Hoeller
- * @author Arjen Poutsma
- * @since 2.5.1
- * @see #setPort
- * @see #setContexts
- * @deprecated as of Spring Framework 5.1, in favor of embedded Tomcat/Jetty/Undertow
- */
-@Deprecated
-@org.springframework.lang.UsesSunHttpServer
-public class SimpleHttpServerFactoryBean implements FactoryBean, InitializingBean, DisposableBean {
-
- protected final Log logger = LogFactory.getLog(getClass());
-
- private int port = 8080;
-
- private String hostname;
-
- private int backlog = -1;
-
- private int shutdownDelay = 0;
-
- private Executor executor;
-
- private Map contexts;
-
- private List filters;
-
- private Authenticator authenticator;
-
- private HttpServer server;
-
-
- /**
- * Specify the HTTP server's port. Default is 8080.
- */
- public void setPort(int port) {
- this.port = port;
- }
-
- /**
- * Specify the HTTP server's hostname to bind to. Default is localhost;
- * can be overridden with a specific network address to bind to.
- */
- public void setHostname(String hostname) {
- this.hostname = hostname;
- }
-
- /**
- * Specify the HTTP server's TCP backlog. Default is -1,
- * indicating the system's default value.
- */
- public void setBacklog(int backlog) {
- this.backlog = backlog;
- }
-
- /**
- * Specify the number of seconds to wait until HTTP exchanges have
- * completed when shutting down the HTTP server. Default is 0.
- */
- public void setShutdownDelay(int shutdownDelay) {
- this.shutdownDelay = shutdownDelay;
- }
-
- /**
- * Set the JDK concurrent executor to use for dispatching incoming requests.
- * @see com.sun.net.httpserver.HttpServer#setExecutor
- */
- public void setExecutor(Executor executor) {
- this.executor = executor;
- }
-
- /**
- * Register {@link com.sun.net.httpserver.HttpHandler HttpHandlers}
- * for specific context paths.
- * @param contexts a Map with context paths as keys and HttpHandler
- * objects as values
- * @see org.springframework.remoting.httpinvoker.SimpleHttpInvokerServiceExporter
- * @see org.springframework.remoting.caucho.SimpleHessianServiceExporter
- */
- public void setContexts(Map contexts) {
- this.contexts = contexts;
- }
-
- /**
- * Register common {@link com.sun.net.httpserver.Filter Filters} to be
- * applied to all locally registered {@link #setContexts contexts}.
- */
- public void setFilters(List filters) {
- this.filters = filters;
- }
-
- /**
- * Register a common {@link com.sun.net.httpserver.Authenticator} to be
- * applied to all locally registered {@link #setContexts contexts}.
- */
- public void setAuthenticator(Authenticator authenticator) {
- this.authenticator = authenticator;
- }
-
-
- @Override
- public void afterPropertiesSet() throws IOException {
- InetSocketAddress address = (this.hostname != null ?
- new InetSocketAddress(this.hostname, this.port) : new InetSocketAddress(this.port));
- this.server = HttpServer.create(address, this.backlog);
- if (this.executor != null) {
- this.server.setExecutor(this.executor);
- }
- if (this.contexts != null) {
- this.contexts.forEach((key, context) -> {
- HttpContext httpContext = this.server.createContext(key, context);
- if (this.filters != null) {
- httpContext.getFilters().addAll(this.filters);
- }
- if (this.authenticator != null) {
- httpContext.setAuthenticator(this.authenticator);
- }
- });
- }
- if (logger.isInfoEnabled()) {
- logger.info("Starting HttpServer at address " + address);
- }
- this.server.start();
- }
-
- @Override
- public HttpServer getObject() {
- return this.server;
- }
-
- @Override
- public Class extends HttpServer> getObjectType() {
- return (this.server != null ? this.server.getClass() : HttpServer.class);
- }
-
- @Override
- public boolean isSingleton() {
- return true;
- }
-
- @Override
- public void destroy() {
- logger.info("Stopping HttpServer");
- this.server.stop(this.shutdownDelay);
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/UrlBasedRemoteAccessor.java b/spring-context/src/main/java/org/springframework/remoting/support/UrlBasedRemoteAccessor.java
deleted file mode 100644
index 93c65ac220..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/UrlBasedRemoteAccessor.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import org.springframework.beans.factory.InitializingBean;
-
-/**
- * Abstract base class for classes that access remote services via URLs.
- * Provides a "serviceUrl" bean property, which is considered as required.
- *
- * @author Juergen Hoeller
- * @since 15.12.2003
- */
-public abstract class UrlBasedRemoteAccessor extends RemoteAccessor implements InitializingBean {
-
- private String serviceUrl;
-
-
- /**
- * Set the URL of this remote accessor's target service.
- * The URL must be compatible with the rules of the particular remoting provider.
- */
- public void setServiceUrl(String serviceUrl) {
- this.serviceUrl = serviceUrl;
- }
-
- /**
- * Return the URL of this remote accessor's target service.
- */
- public String getServiceUrl() {
- return this.serviceUrl;
- }
-
-
- @Override
- public void afterPropertiesSet() {
- if (getServiceUrl() == null) {
- throw new IllegalArgumentException("Property 'serviceUrl' is required");
- }
- }
-
-}
diff --git a/spring-context/src/main/java/org/springframework/remoting/support/package-info.java b/spring-context/src/main/java/org/springframework/remoting/support/package-info.java
deleted file mode 100644
index 316306149a..0000000000
--- a/spring-context/src/main/java/org/springframework/remoting/support/package-info.java
+++ /dev/null
@@ -1,5 +0,0 @@
-/**
- * Generic support classes for remoting implementations.
- * Provides abstract base classes for remote proxy factories.
- */
-package org.springframework.remoting.support;
diff --git a/spring-context/src/test/java/org/springframework/remoting/rmi/RmiSupportTests.java b/spring-context/src/test/java/org/springframework/remoting/rmi/RmiSupportTests.java
deleted file mode 100644
index 82780251a5..0000000000
--- a/spring-context/src/test/java/org/springframework/remoting/rmi/RmiSupportTests.java
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * Copyright 2002-2019 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.rmi;
-
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.rmi.ConnectException;
-import java.rmi.ConnectIOException;
-import java.rmi.MarshalException;
-import java.rmi.NoSuchObjectException;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.StubNotFoundException;
-import java.rmi.UnknownHostException;
-import java.rmi.UnmarshalException;
-
-import org.aopalliance.intercept.MethodInvocation;
-import org.junit.jupiter.api.Test;
-
-import org.springframework.remoting.RemoteAccessException;
-import org.springframework.remoting.RemoteConnectFailureException;
-import org.springframework.remoting.RemoteProxyFailureException;
-import org.springframework.remoting.support.RemoteInvocation;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-
-/**
- * @author Juergen Hoeller
- * @since 16.05.2003
- */
-public class RmiSupportTests {
-
- @Test
- public void rmiProxyFactoryBean() throws Exception {
- CountingRmiProxyFactoryBean factory = new CountingRmiProxyFactoryBean();
- factory.setServiceInterface(IRemoteBean.class);
- factory.setServiceUrl("rmi://localhost:1090/test");
- factory.afterPropertiesSet();
- assertThat(factory.isSingleton()).as("Correct singleton value").isTrue();
- boolean condition = factory.getObject() instanceof IRemoteBean;
- assertThat(condition).isTrue();
- IRemoteBean proxy = (IRemoteBean) factory.getObject();
- proxy.setName("myName");
- assertThat(RemoteBean.name).isEqualTo("myName");
- assertThat(factory.counter).isEqualTo(1);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithRemoteException() throws Exception {
- doTestRmiProxyFactoryBeanWithException(RemoteException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithConnectException() throws Exception {
- doTestRmiProxyFactoryBeanWithException(ConnectException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithConnectIOException() throws Exception {
- doTestRmiProxyFactoryBeanWithException(ConnectIOException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithUnknownHostException() throws Exception {
- doTestRmiProxyFactoryBeanWithException(UnknownHostException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithNoSuchObjectException() throws Exception {
- doTestRmiProxyFactoryBeanWithException(NoSuchObjectException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithStubNotFoundException() throws Exception {
- doTestRmiProxyFactoryBeanWithException(StubNotFoundException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithMarshalException() throws Exception {
- doTestRmiProxyFactoryBeanWithException(MarshalException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithUnmarshalException() throws Exception {
- doTestRmiProxyFactoryBeanWithException(UnmarshalException.class);
- }
-
- private void doTestRmiProxyFactoryBeanWithException(Class extends Throwable> exceptionClass) throws Exception {
- CountingRmiProxyFactoryBean factory = new CountingRmiProxyFactoryBean();
- factory.setServiceInterface(IRemoteBean.class);
- factory.setServiceUrl("rmi://localhost:1090/test");
- factory.afterPropertiesSet();
- boolean condition = factory.getObject() instanceof IRemoteBean;
- assertThat(condition).isTrue();
- IRemoteBean proxy = (IRemoteBean) factory.getObject();
- assertThatExceptionOfType(exceptionClass).isThrownBy(() ->
- proxy.setName(exceptionClass.getName()));
- assertThat(factory.counter).isEqualTo(1);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithConnectExceptionAndRefresh() throws Exception {
- doTestRmiProxyFactoryBeanWithExceptionAndRefresh(ConnectException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithConnectIOExceptionAndRefresh() throws Exception {
- doTestRmiProxyFactoryBeanWithExceptionAndRefresh(ConnectIOException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithUnknownHostExceptionAndRefresh() throws Exception {
- doTestRmiProxyFactoryBeanWithExceptionAndRefresh(UnknownHostException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithNoSuchObjectExceptionAndRefresh() throws Exception {
- doTestRmiProxyFactoryBeanWithExceptionAndRefresh(NoSuchObjectException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithStubNotFoundExceptionAndRefresh() throws Exception {
- doTestRmiProxyFactoryBeanWithExceptionAndRefresh(StubNotFoundException.class);
- }
-
- private void doTestRmiProxyFactoryBeanWithExceptionAndRefresh(Class extends Throwable> exceptionClass) throws Exception {
- CountingRmiProxyFactoryBean factory = new CountingRmiProxyFactoryBean();
- factory.setServiceInterface(IRemoteBean.class);
- factory.setServiceUrl("rmi://localhost:1090/test");
- factory.setRefreshStubOnConnectFailure(true);
- factory.afterPropertiesSet();
- boolean condition = factory.getObject() instanceof IRemoteBean;
- assertThat(condition).isTrue();
- IRemoteBean proxy = (IRemoteBean) factory.getObject();
- assertThatExceptionOfType(exceptionClass).isThrownBy(() ->
- proxy.setName(exceptionClass.getName()));
- assertThat(factory.counter).isEqualTo(2);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithBusinessInterface() throws Exception {
- CountingRmiProxyFactoryBean factory = new CountingRmiProxyFactoryBean();
- factory.setServiceInterface(IBusinessBean.class);
- factory.setServiceUrl("rmi://localhost:1090/test");
- factory.afterPropertiesSet();
- boolean condition = factory.getObject() instanceof IBusinessBean;
- assertThat(condition).isTrue();
- IBusinessBean proxy = (IBusinessBean) factory.getObject();
- boolean condition1 = proxy instanceof IRemoteBean;
- assertThat(condition1).isFalse();
- proxy.setName("myName");
- assertThat(RemoteBean.name).isEqualTo("myName");
- assertThat(factory.counter).isEqualTo(1);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithWrongBusinessInterface() throws Exception {
- CountingRmiProxyFactoryBean factory = new CountingRmiProxyFactoryBean();
- factory.setServiceInterface(IWrongBusinessBean.class);
- factory.setServiceUrl("rmi://localhost:1090/test");
- factory.afterPropertiesSet();
- boolean condition = factory.getObject() instanceof IWrongBusinessBean;
- assertThat(condition).isTrue();
- IWrongBusinessBean proxy = (IWrongBusinessBean) factory.getObject();
- boolean condition1 = proxy instanceof IRemoteBean;
- assertThat(condition1).isFalse();
- assertThatExceptionOfType(RemoteProxyFailureException.class).isThrownBy(() ->
- proxy.setOtherName("name"))
- .withCauseInstanceOf(NoSuchMethodException.class)
- .withMessageContaining("setOtherName")
- .withMessageContaining("IWrongBusinessBean");
- assertThat(factory.counter).isEqualTo(1);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithBusinessInterfaceAndRemoteException() throws Exception {
- doTestRmiProxyFactoryBeanWithBusinessInterfaceAndException(
- RemoteException.class, RemoteAccessException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithBusinessInterfaceAndConnectException() throws Exception {
- doTestRmiProxyFactoryBeanWithBusinessInterfaceAndException(
- ConnectException.class, RemoteConnectFailureException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithBusinessInterfaceAndConnectIOException() throws Exception {
- doTestRmiProxyFactoryBeanWithBusinessInterfaceAndException(
- ConnectIOException.class, RemoteConnectFailureException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithBusinessInterfaceAndUnknownHostException() throws Exception {
- doTestRmiProxyFactoryBeanWithBusinessInterfaceAndException(
- UnknownHostException.class, RemoteConnectFailureException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithBusinessInterfaceAndNoSuchObjectExceptionException() throws Exception {
- doTestRmiProxyFactoryBeanWithBusinessInterfaceAndException(
- NoSuchObjectException.class, RemoteConnectFailureException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithBusinessInterfaceAndStubNotFoundException() throws Exception {
- doTestRmiProxyFactoryBeanWithBusinessInterfaceAndException(
- StubNotFoundException.class, RemoteConnectFailureException.class);
- }
-
- private void doTestRmiProxyFactoryBeanWithBusinessInterfaceAndException(
- Class> rmiExceptionClass, Class extends Throwable> springExceptionClass) throws Exception {
-
- CountingRmiProxyFactoryBean factory = new CountingRmiProxyFactoryBean();
- factory.setServiceInterface(IBusinessBean.class);
- factory.setServiceUrl("rmi://localhost:1090/test");
- factory.afterPropertiesSet();
- boolean condition = factory.getObject() instanceof IBusinessBean;
- assertThat(condition).isTrue();
- IBusinessBean proxy = (IBusinessBean) factory.getObject();
- boolean condition1 = proxy instanceof IRemoteBean;
- assertThat(condition1).isFalse();
- assertThatExceptionOfType(springExceptionClass).isThrownBy(() ->
- proxy.setName(rmiExceptionClass.getName()));
- assertThat(factory.counter).isEqualTo(1);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithBusinessInterfaceAndRemoteExceptionAndRefresh() throws Exception {
- doTestRmiProxyFactoryBeanWithBusinessInterfaceAndExceptionAndRefresh(
- RemoteException.class, RemoteAccessException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithBusinessInterfaceAndConnectExceptionAndRefresh() throws Exception {
- doTestRmiProxyFactoryBeanWithBusinessInterfaceAndExceptionAndRefresh(
- ConnectException.class, RemoteConnectFailureException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithBusinessInterfaceAndConnectIOExceptionAndRefresh() throws Exception {
- doTestRmiProxyFactoryBeanWithBusinessInterfaceAndExceptionAndRefresh(
- ConnectIOException.class, RemoteConnectFailureException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithBusinessInterfaceAndUnknownHostExceptionAndRefresh() throws Exception {
- doTestRmiProxyFactoryBeanWithBusinessInterfaceAndExceptionAndRefresh(
- UnknownHostException.class, RemoteConnectFailureException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithBusinessInterfaceAndNoSuchObjectExceptionAndRefresh() throws Exception {
- doTestRmiProxyFactoryBeanWithBusinessInterfaceAndExceptionAndRefresh(
- NoSuchObjectException.class, RemoteConnectFailureException.class);
- }
-
- @Test
- public void rmiProxyFactoryBeanWithBusinessInterfaceAndStubNotFoundExceptionAndRefresh() throws Exception {
- doTestRmiProxyFactoryBeanWithBusinessInterfaceAndExceptionAndRefresh(
- StubNotFoundException.class, RemoteConnectFailureException.class);
- }
-
- private void doTestRmiProxyFactoryBeanWithBusinessInterfaceAndExceptionAndRefresh(
- Class> rmiExceptionClass, Class extends Throwable> springExceptionClass) throws Exception {
-
- CountingRmiProxyFactoryBean factory = new CountingRmiProxyFactoryBean();
- factory.setServiceInterface(IBusinessBean.class);
- factory.setServiceUrl("rmi://localhost:1090/test");
- factory.setRefreshStubOnConnectFailure(true);
- factory.afterPropertiesSet();
- boolean condition = factory.getObject() instanceof IBusinessBean;
- assertThat(condition).isTrue();
- IBusinessBean proxy = (IBusinessBean) factory.getObject();
- boolean condition1 = proxy instanceof IRemoteBean;
- assertThat(condition1).isFalse();
- assertThatExceptionOfType(springExceptionClass).isThrownBy(() ->
- proxy.setName(rmiExceptionClass.getName()));
- boolean isRemoteConnectFailure = RemoteConnectFailureException.class.isAssignableFrom(springExceptionClass);
- assertThat(factory.counter).isEqualTo(isRemoteConnectFailure ? 2 : 1);
- }
-
- @Test
- public void rmiClientInterceptorRequiresUrl() throws Exception{
- RmiClientInterceptor client = new RmiClientInterceptor();
- client.setServiceInterface(IRemoteBean.class);
- assertThatIllegalArgumentException().isThrownBy(client::afterPropertiesSet);
- }
-
- @Test
- public void remoteInvocation() throws NoSuchMethodException {
- // let's see if the remote invocation object works
-
- final RemoteBean rb = new RemoteBean();
- final Method setNameMethod = rb.getClass().getDeclaredMethod("setName", String.class);
-
- MethodInvocation mi = new MethodInvocation() {
- @Override
- public Method getMethod() {
- return setNameMethod;
- }
- @Override
- public Object[] getArguments() {
- return new Object[] {"bla"};
- }
- @Override
- public Object proceed() throws Throwable {
- throw new UnsupportedOperationException();
- }
- @Override
- public Object getThis() {
- return rb;
- }
- @Override
- public AccessibleObject getStaticPart() {
- return setNameMethod;
- }
- };
-
- RemoteInvocation inv = new RemoteInvocation(mi);
-
- assertThat(inv.getMethodName()).isEqualTo("setName");
- assertThat(inv.getArguments()[0]).isEqualTo("bla");
- assertThat(inv.getParameterTypes()[0]).isEqualTo(String.class);
-
- // this is a bit BS, but we need to test it
- inv = new RemoteInvocation();
- inv.setArguments(new Object[] { "bla" });
- assertThat(inv.getArguments()[0]).isEqualTo("bla");
- inv.setMethodName("setName");
- assertThat(inv.getMethodName()).isEqualTo("setName");
- inv.setParameterTypes(new Class>[] {String.class});
- assertThat(inv.getParameterTypes()[0]).isEqualTo(String.class);
-
- inv = new RemoteInvocation("setName", new Class>[] {String.class}, new Object[] {"bla"});
- assertThat(inv.getArguments()[0]).isEqualTo("bla");
- assertThat(inv.getMethodName()).isEqualTo("setName");
- assertThat(inv.getParameterTypes()[0]).isEqualTo(String.class);
- }
-
- @Test
- public void rmiInvokerWithSpecialLocalMethods() throws Exception {
- String serviceUrl = "rmi://localhost:1090/test";
- RmiProxyFactoryBean factory = new RmiProxyFactoryBean() {
- @Override
- protected Remote lookupStub() {
- return new RmiInvocationHandler() {
- @Override
- public String getTargetInterfaceName() {
- return null;
- }
- @Override
- public Object invoke(RemoteInvocation invocation) throws RemoteException {
- throw new RemoteException();
- }
- };
- }
- };
- factory.setServiceInterface(IBusinessBean.class);
- factory.setServiceUrl(serviceUrl);
- factory.afterPropertiesSet();
- IBusinessBean proxy = (IBusinessBean) factory.getObject();
-
- // shouldn't go through to remote service
- assertThat(proxy.toString().contains("RMI invoker")).isTrue();
- assertThat(proxy.toString().contains(serviceUrl)).isTrue();
- assertThat(proxy.hashCode()).isEqualTo(proxy.hashCode());
- assertThat(proxy.equals(proxy)).isTrue();
-
- // should go through
- assertThatExceptionOfType(RemoteAccessException.class).isThrownBy(() ->
- proxy.setName("test"));
- }
-
-
- private static class CountingRmiProxyFactoryBean extends RmiProxyFactoryBean {
-
- private int counter = 0;
-
- @Override
- protected Remote lookupStub() {
- counter++;
- return new RemoteBean();
- }
- }
-
-
- public interface IBusinessBean {
-
- void setName(String name);
- }
-
-
- public interface IWrongBusinessBean {
-
- void setOtherName(String name);
- }
-
-
- public interface IRemoteBean extends Remote {
-
- void setName(String name) throws RemoteException;
- }
-
-
- public static class RemoteBean implements IRemoteBean {
-
- private static String name;
-
- @Override
- public void setName(String nam) throws RemoteException {
- if (nam != null && nam.endsWith("Exception")) {
- RemoteException rex;
- try {
- Class> exClass = Class.forName(nam);
- Constructor> ctor = exClass.getConstructor(String.class);
- rex = (RemoteException) ctor.newInstance("myMessage");
- }
- catch (Exception ex) {
- throw new RemoteException("Illegal exception class name: " + nam, ex);
- }
- throw rex;
- }
- name = nam;
- }
- }
-
-}
diff --git a/spring-context/src/test/java/org/springframework/remoting/support/RemoteInvocationUtilsTests.java b/spring-context/src/test/java/org/springframework/remoting/support/RemoteInvocationUtilsTests.java
deleted file mode 100644
index dbaa7a4294..0000000000
--- a/spring-context/src/test/java/org/springframework/remoting/support/RemoteInvocationUtilsTests.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2002-2019 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.support;
-
-import org.junit.jupiter.api.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-/**
- * @author Rick Evans
- */
-public class RemoteInvocationUtilsTests {
-
- @Test
- public void fillInClientStackTraceIfPossibleSunnyDay() throws Exception {
- try {
- throw new IllegalStateException("Mmm");
- }
- catch (Exception ex) {
- int originalStackTraceLngth = ex.getStackTrace().length;
- RemoteInvocationUtils.fillInClientStackTraceIfPossible(ex);
- assertThat(ex.getStackTrace().length > originalStackTraceLngth).as("Stack trace not being filled in").isTrue();
- }
- }
-
- @Test
- public void fillInClientStackTraceIfPossibleWithNullThrowable() throws Exception {
- // just want to ensure that it doesn't bomb
- RemoteInvocationUtils.fillInClientStackTraceIfPossible(null);
- }
-
-}
diff --git a/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerClientInterceptor.java b/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerClientInterceptor.java
deleted file mode 100644
index 04566b4109..0000000000
--- a/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerClientInterceptor.java
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * Copyright 2002-2017 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.jms.remoting;
-
-import javax.jms.Connection;
-import javax.jms.ConnectionFactory;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageConsumer;
-import javax.jms.MessageFormatException;
-import javax.jms.MessageProducer;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.TemporaryQueue;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-
-import org.springframework.aop.support.AopUtils;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.jms.connection.ConnectionFactoryUtils;
-import org.springframework.jms.support.JmsUtils;
-import org.springframework.jms.support.converter.MessageConverter;
-import org.springframework.jms.support.converter.SimpleMessageConverter;
-import org.springframework.jms.support.destination.DestinationResolver;
-import org.springframework.jms.support.destination.DynamicDestinationResolver;
-import org.springframework.lang.Nullable;
-import org.springframework.remoting.RemoteAccessException;
-import org.springframework.remoting.RemoteInvocationFailureException;
-import org.springframework.remoting.RemoteTimeoutException;
-import org.springframework.remoting.support.DefaultRemoteInvocationFactory;
-import org.springframework.remoting.support.RemoteInvocation;
-import org.springframework.remoting.support.RemoteInvocationFactory;
-import org.springframework.remoting.support.RemoteInvocationResult;
-import org.springframework.util.Assert;
-
-/**
- * {@link org.aopalliance.intercept.MethodInterceptor} for accessing a
- * JMS-based remote service.
- *
- * Serializes remote invocation objects and deserializes remote invocation
- * result objects. Uses Java serialization just like RMI, but with the JMS
- * provider as communication infrastructure.
- *
- *
To be configured with a {@link javax.jms.QueueConnectionFactory} and a
- * target queue (either as {@link javax.jms.Queue} reference or as queue name).
- *
- *
Thanks to James Strachan for the original prototype that this
- * JMS invoker mechanism was inspired by!
- *
- * @author Juergen Hoeller
- * @author James Strachan
- * @author Stephane Nicoll
- * @since 2.0
- * @see #setConnectionFactory
- * @see #setQueue
- * @see #setQueueName
- * @see org.springframework.jms.remoting.JmsInvokerServiceExporter
- * @see org.springframework.jms.remoting.JmsInvokerProxyFactoryBean
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class JmsInvokerClientInterceptor implements MethodInterceptor, InitializingBean {
-
- @Nullable
- private ConnectionFactory connectionFactory;
-
- @Nullable
- private Object queue;
-
- private DestinationResolver destinationResolver = new DynamicDestinationResolver();
-
- private RemoteInvocationFactory remoteInvocationFactory = new DefaultRemoteInvocationFactory();
-
- private MessageConverter messageConverter = new SimpleMessageConverter();
-
- private long receiveTimeout = 0;
-
-
- /**
- * Set the QueueConnectionFactory to use for obtaining JMS QueueConnections.
- */
- public void setConnectionFactory(@Nullable ConnectionFactory connectionFactory) {
- this.connectionFactory = connectionFactory;
- }
-
- /**
- * Return the QueueConnectionFactory to use for obtaining JMS QueueConnections.
- */
- @Nullable
- protected ConnectionFactory getConnectionFactory() {
- return this.connectionFactory;
- }
-
- /**
- * Set the target Queue to send invoker requests to.
- */
- public void setQueue(Queue queue) {
- this.queue = queue;
- }
-
- /**
- * Set the name of target queue to send invoker requests to.
- *
The specified name will be dynamically resolved via the
- * {@link #setDestinationResolver DestinationResolver}.
- */
- public void setQueueName(String queueName) {
- this.queue = queueName;
- }
-
- /**
- * Set the DestinationResolver that is to be used to resolve Queue
- * references for this accessor.
- *
The default resolver is a {@code DynamicDestinationResolver}. Specify a
- * {@code JndiDestinationResolver} for resolving destination names as JNDI locations.
- * @see org.springframework.jms.support.destination.DynamicDestinationResolver
- * @see org.springframework.jms.support.destination.JndiDestinationResolver
- */
- public void setDestinationResolver(@Nullable DestinationResolver destinationResolver) {
- this.destinationResolver =
- (destinationResolver != null ? destinationResolver : new DynamicDestinationResolver());
- }
-
- /**
- * Set the {@link RemoteInvocationFactory} to use for this accessor.
- *
Default is a {@link DefaultRemoteInvocationFactory}.
- *
A custom invocation factory can add further context information
- * to the invocation, for example user credentials.
- */
- public void setRemoteInvocationFactory(@Nullable RemoteInvocationFactory remoteInvocationFactory) {
- this.remoteInvocationFactory =
- (remoteInvocationFactory != null ? remoteInvocationFactory : new DefaultRemoteInvocationFactory());
- }
-
- /**
- * Specify the {@link MessageConverter} to use for turning
- * {@link org.springframework.remoting.support.RemoteInvocation}
- * objects into request messages, as well as response messages into
- * {@link org.springframework.remoting.support.RemoteInvocationResult} objects.
- *
Default is a {@link SimpleMessageConverter}, using a standard JMS
- * {@link javax.jms.ObjectMessage} for each invocation / invocation result
- * object.
- *
Custom implementations may generally adapt {@link java.io.Serializable}
- * objects into special kinds of messages, or might be specifically tailored for
- * translating {@code RemoteInvocation(Result)s} into specific kinds of messages.
- */
- public void setMessageConverter(@Nullable MessageConverter messageConverter) {
- this.messageConverter = (messageConverter != null ? messageConverter : new SimpleMessageConverter());
- }
-
- /**
- * Set the timeout to use for receiving the response message for a request
- * (in milliseconds).
- *
The default is 0, which indicates a blocking receive without timeout.
- * @see javax.jms.MessageConsumer#receive(long)
- * @see javax.jms.MessageConsumer#receive()
- */
- public void setReceiveTimeout(long receiveTimeout) {
- this.receiveTimeout = receiveTimeout;
- }
-
- /**
- * Return the timeout to use for receiving the response message for a request
- * (in milliseconds).
- */
- protected long getReceiveTimeout() {
- return this.receiveTimeout;
- }
-
-
- @Override
- public void afterPropertiesSet() {
- if (getConnectionFactory() == null) {
- throw new IllegalArgumentException("Property 'connectionFactory' is required");
- }
- if (this.queue == null) {
- throw new IllegalArgumentException("'queue' or 'queueName' is required");
- }
- }
-
-
- @Override
- @Nullable
- public Object invoke(MethodInvocation methodInvocation) throws Throwable {
- if (AopUtils.isToStringMethod(methodInvocation.getMethod())) {
- return "JMS invoker proxy for queue [" + this.queue + "]";
- }
-
- RemoteInvocation invocation = createRemoteInvocation(methodInvocation);
- RemoteInvocationResult result;
- try {
- result = executeRequest(invocation);
- }
- catch (JMSException ex) {
- throw convertJmsInvokerAccessException(ex);
- }
- try {
- return recreateRemoteInvocationResult(result);
- }
- catch (Throwable ex) {
- if (result.hasInvocationTargetException()) {
- throw ex;
- }
- else {
- throw new RemoteInvocationFailureException("Invocation of method [" + methodInvocation.getMethod() +
- "] failed in JMS invoker remote service at queue [" + this.queue + "]", ex);
- }
- }
- }
-
- /**
- * Create a new {@code RemoteInvocation} object for the given AOP method invocation.
- *
The default implementation delegates to the {@link RemoteInvocationFactory}.
- *
Can be overridden in subclasses to provide custom {@code RemoteInvocation}
- * subclasses, containing additional invocation parameters like user credentials.
- * Note that it is preferable to use a custom {@code RemoteInvocationFactory} which
- * is a reusable strategy.
- * @param methodInvocation the current AOP method invocation
- * @return the RemoteInvocation object
- * @see RemoteInvocationFactory#createRemoteInvocation
- */
- protected RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) {
- return this.remoteInvocationFactory.createRemoteInvocation(methodInvocation);
- }
-
- /**
- * Execute the given remote invocation, sending an invoker request message
- * to this accessor's target queue and waiting for a corresponding response.
- * @param invocation the RemoteInvocation to execute
- * @return the RemoteInvocationResult object
- * @throws JMSException in case of JMS failure
- * @see #doExecuteRequest
- */
- protected RemoteInvocationResult executeRequest(RemoteInvocation invocation) throws JMSException {
- Connection con = createConnection();
- Session session = null;
- try {
- session = createSession(con);
- Queue queueToUse = resolveQueue(session);
- Message requestMessage = createRequestMessage(session, invocation);
- con.start();
- Message responseMessage = doExecuteRequest(session, queueToUse, requestMessage);
- if (responseMessage != null) {
- return extractInvocationResult(responseMessage);
- }
- else {
- return onReceiveTimeout(invocation);
- }
- }
- finally {
- JmsUtils.closeSession(session);
- ConnectionFactoryUtils.releaseConnection(con, getConnectionFactory(), true);
- }
- }
-
- /**
- * Create a new JMS Connection for this JMS invoker.
- */
- protected Connection createConnection() throws JMSException {
- ConnectionFactory connectionFactory = getConnectionFactory();
- Assert.state(connectionFactory != null, "No ConnectionFactory set");
- return connectionFactory.createConnection();
- }
-
- /**
- * Create a new JMS Session for this JMS invoker.
- */
- protected Session createSession(Connection con) throws JMSException {
- return con.createSession(false, Session.AUTO_ACKNOWLEDGE);
- }
-
- /**
- * Resolve this accessor's target queue.
- * @param session the current JMS Session
- * @return the resolved target Queue
- * @throws JMSException if resolution failed
- */
- protected Queue resolveQueue(Session session) throws JMSException {
- if (this.queue instanceof Queue) {
- return (Queue) this.queue;
- }
- else if (this.queue instanceof String) {
- return resolveQueueName(session, (String) this.queue);
- }
- else {
- throw new javax.jms.IllegalStateException(
- "Queue object [" + this.queue + "] is neither a [javax.jms.Queue] nor a queue name String");
- }
- }
-
- /**
- * Resolve the given queue name into a JMS {@link javax.jms.Queue},
- * via this accessor's {@link DestinationResolver}.
- * @param session the current JMS Session
- * @param queueName the name of the queue
- * @return the located Queue
- * @throws JMSException if resolution failed
- * @see #setDestinationResolver
- */
- protected Queue resolveQueueName(Session session, String queueName) throws JMSException {
- return (Queue) this.destinationResolver.resolveDestinationName(session, queueName, false);
- }
-
- /**
- * Create the invoker request message.
- *
The default implementation creates a JMS {@link javax.jms.ObjectMessage}
- * for the given RemoteInvocation object.
- * @param session the current JMS Session
- * @param invocation the remote invocation to send
- * @return the JMS Message to send
- * @throws JMSException if the message could not be created
- */
- protected Message createRequestMessage(Session session, RemoteInvocation invocation) throws JMSException {
- return this.messageConverter.toMessage(invocation, session);
- }
-
- /**
- * Actually execute the given request, sending the invoker request message
- * to the specified target queue and waiting for a corresponding response.
- *
The default implementation is based on standard JMS send/receive,
- * using a {@link javax.jms.TemporaryQueue} for receiving the response.
- * @param session the JMS Session to use
- * @param queue the resolved target Queue to send to
- * @param requestMessage the JMS Message to send
- * @return the RemoteInvocationResult object
- * @throws JMSException in case of JMS failure
- */
- @Nullable
- protected Message doExecuteRequest(Session session, Queue queue, Message requestMessage) throws JMSException {
- TemporaryQueue responseQueue = null;
- MessageProducer producer = null;
- MessageConsumer consumer = null;
- try {
- responseQueue = session.createTemporaryQueue();
- producer = session.createProducer(queue);
- consumer = session.createConsumer(responseQueue);
- requestMessage.setJMSReplyTo(responseQueue);
- producer.send(requestMessage);
- long timeout = getReceiveTimeout();
- return (timeout > 0 ? consumer.receive(timeout) : consumer.receive());
- }
- finally {
- JmsUtils.closeMessageConsumer(consumer);
- JmsUtils.closeMessageProducer(producer);
- if (responseQueue != null) {
- responseQueue.delete();
- }
- }
- }
-
- /**
- * Extract the invocation result from the response message.
- *
The default implementation expects a JMS {@link javax.jms.ObjectMessage}
- * carrying a {@link RemoteInvocationResult} object. If an invalid response
- * message is encountered, the {@code onInvalidResponse} callback gets invoked.
- * @param responseMessage the response message
- * @return the invocation result
- * @throws JMSException is thrown if a JMS exception occurs
- * @see #onInvalidResponse
- */
- protected RemoteInvocationResult extractInvocationResult(Message responseMessage) throws JMSException {
- Object content = this.messageConverter.fromMessage(responseMessage);
- if (content instanceof RemoteInvocationResult) {
- return (RemoteInvocationResult) content;
- }
- return onInvalidResponse(responseMessage);
- }
-
- /**
- * Callback that is invoked by {@link #executeRequest} when the receive
- * timeout has expired for the specified {@link RemoteInvocation}.
- *
By default, an {@link RemoteTimeoutException} is thrown. Sub-classes
- * can choose to either throw a more dedicated exception or even return
- * a default {@link RemoteInvocationResult} as a fallback.
- * @param invocation the invocation
- * @return a default result when the receive timeout has expired
- */
- protected RemoteInvocationResult onReceiveTimeout(RemoteInvocation invocation) {
- throw new RemoteTimeoutException("Receive timeout after " + this.receiveTimeout + " ms for " + invocation);
- }
-
- /**
- * Callback that is invoked by {@link #extractInvocationResult} when
- * it encounters an invalid response message.
- *
The default implementation throws a {@link MessageFormatException}.
- * @param responseMessage the invalid response message
- * @return an alternative invocation result that should be returned to
- * the caller (if desired)
- * @throws JMSException if the invalid response should lead to an
- * infrastructure exception propagated to the caller
- * @see #extractInvocationResult
- */
- protected RemoteInvocationResult onInvalidResponse(Message responseMessage) throws JMSException {
- throw new MessageFormatException("Invalid response message: " + responseMessage);
- }
-
- /**
- * Recreate the invocation result contained in the given {@link RemoteInvocationResult}
- * object.
- *
The default implementation calls the default {@code recreate()} method.
- *
Can be overridden in subclasses to provide custom recreation, potentially
- * processing the returned result object.
- * @param result the RemoteInvocationResult to recreate
- * @return a return value if the invocation result is a successful return
- * @throws Throwable if the invocation result is an exception
- * @see org.springframework.remoting.support.RemoteInvocationResult#recreate()
- */
- @Nullable
- protected Object recreateRemoteInvocationResult(RemoteInvocationResult result) throws Throwable {
- return result.recreate();
- }
-
- /**
- * Convert the given JMS invoker access exception to an appropriate
- * Spring {@link RemoteAccessException}.
- * @param ex the exception to convert
- * @return the RemoteAccessException to throw
- */
- protected RemoteAccessException convertJmsInvokerAccessException(JMSException ex) {
- return new RemoteAccessException("Could not access JMS invoker queue [" + this.queue + "]", ex);
- }
-
-}
diff --git a/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerProxyFactoryBean.java b/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerProxyFactoryBean.java
deleted file mode 100644
index 4562b602a5..0000000000
--- a/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerProxyFactoryBean.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2002-2017 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.jms.remoting;
-
-import org.springframework.aop.framework.ProxyFactory;
-import org.springframework.beans.factory.BeanClassLoaderAware;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.lang.Nullable;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-
-/**
- * FactoryBean for JMS invoker proxies. Exposes the proxied service for use
- * as a bean reference, using the specified service interface.
- *
- *
Serializes remote invocation objects and deserializes remote invocation
- * result objects. Uses Java serialization just like RMI, but with the JMS
- * provider as communication infrastructure.
- *
- *
To be configured with a {@link javax.jms.QueueConnectionFactory} and a
- * target queue (either as {@link javax.jms.Queue} reference or as queue name).
- *
- * @author Juergen Hoeller
- * @since 2.0
- * @see #setConnectionFactory
- * @see #setQueueName
- * @see #setServiceInterface
- * @see org.springframework.jms.remoting.JmsInvokerClientInterceptor
- * @see org.springframework.jms.remoting.JmsInvokerServiceExporter
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class JmsInvokerProxyFactoryBean extends JmsInvokerClientInterceptor
- implements FactoryBean, BeanClassLoaderAware {
-
- @Nullable
- private Class> serviceInterface;
-
- @Nullable
- private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
-
- @Nullable
- private Object serviceProxy;
-
-
- /**
- * Set the interface that the proxy must implement.
- * @param serviceInterface the interface that the proxy must implement
- * @throws IllegalArgumentException if the supplied {@code serviceInterface}
- * is not an interface type
- */
- public void setServiceInterface(Class> serviceInterface) {
- Assert.notNull(serviceInterface, "'serviceInterface' must not be null");
- Assert.isTrue(serviceInterface.isInterface(), "'serviceInterface' must be an interface");
- this.serviceInterface = serviceInterface;
- }
-
- @Override
- public void setBeanClassLoader(ClassLoader classLoader) {
- this.beanClassLoader = classLoader;
- }
-
- @Override
- public void afterPropertiesSet() {
- super.afterPropertiesSet();
- Assert.notNull(this.serviceInterface, "Property 'serviceInterface' is required");
- this.serviceProxy = new ProxyFactory(this.serviceInterface, this).getProxy(this.beanClassLoader);
- }
-
-
- @Override
- @Nullable
- public Object getObject() {
- return this.serviceProxy;
- }
-
- @Override
- public Class> getObjectType() {
- return this.serviceInterface;
- }
-
- @Override
- public boolean isSingleton() {
- return true;
- }
-
-}
diff --git a/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerServiceExporter.java b/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerServiceExporter.java
deleted file mode 100644
index 80e5f51b47..0000000000
--- a/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerServiceExporter.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.jms.remoting;
-
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageFormatException;
-import javax.jms.MessageProducer;
-import javax.jms.Session;
-
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.jms.listener.SessionAwareMessageListener;
-import org.springframework.jms.support.JmsUtils;
-import org.springframework.jms.support.converter.MessageConverter;
-import org.springframework.jms.support.converter.SimpleMessageConverter;
-import org.springframework.lang.Nullable;
-import org.springframework.remoting.support.RemoteInvocation;
-import org.springframework.remoting.support.RemoteInvocationBasedExporter;
-import org.springframework.remoting.support.RemoteInvocationResult;
-
-/**
- * JMS message listener that exports the specified service bean as a
- * JMS service endpoint, accessible via a JMS invoker proxy.
- *
- * Note that this class implements Spring's
- * {@link org.springframework.jms.listener.SessionAwareMessageListener}
- * interface, since it requires access to the active JMS Session.
- * Hence, this class can only be used with message listener containers
- * which support the SessionAwareMessageListener interface (e.g. Spring's
- * {@link org.springframework.jms.listener.DefaultMessageListenerContainer}).
- *
- *
Thanks to James Strachan for the original prototype that this
- * JMS invoker mechanism was inspired by!
- *
- * @author Juergen Hoeller
- * @author James Strachan
- * @since 2.0
- * @see JmsInvokerClientInterceptor
- * @see JmsInvokerProxyFactoryBean
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class JmsInvokerServiceExporter extends RemoteInvocationBasedExporter
- implements SessionAwareMessageListener, InitializingBean {
-
- private MessageConverter messageConverter = new SimpleMessageConverter();
-
- private boolean ignoreInvalidRequests = true;
-
- @Nullable
- private Object proxy;
-
-
- /**
- * Specify the MessageConverter to use for turning request messages into
- * {@link org.springframework.remoting.support.RemoteInvocation} objects,
- * as well as {@link org.springframework.remoting.support.RemoteInvocationResult}
- * objects into response messages.
- * Default is a {@link org.springframework.jms.support.converter.SimpleMessageConverter},
- * using a standard JMS {@link javax.jms.ObjectMessage} for each invocation /
- * invocation result object.
- *
Custom implementations may generally adapt Serializables into
- * special kinds of messages, or might be specifically tailored for
- * translating RemoteInvocation(Result)s into specific kinds of messages.
- */
- public void setMessageConverter(@Nullable MessageConverter messageConverter) {
- this.messageConverter = (messageConverter != null ? messageConverter : new SimpleMessageConverter());
- }
-
- /**
- * Set whether invalidly formatted messages should be discarded.
- * Default is "true".
- *
Switch this flag to "false" to throw an exception back to the
- * listener container. This will typically lead to redelivery of
- * the message, which is usually undesirable - since the message
- * content will be the same (that is, still invalid).
- */
- public void setIgnoreInvalidRequests(boolean ignoreInvalidRequests) {
- this.ignoreInvalidRequests = ignoreInvalidRequests;
- }
-
- @Override
- public void afterPropertiesSet() {
- this.proxy = getProxyForService();
- }
-
-
- @Override
- public void onMessage(Message requestMessage, Session session) throws JMSException {
- RemoteInvocation invocation = readRemoteInvocation(requestMessage);
- if (invocation != null) {
- RemoteInvocationResult result = invokeAndCreateResult(invocation, this.proxy);
- writeRemoteInvocationResult(requestMessage, session, result);
- }
- }
-
- /**
- * Read a RemoteInvocation from the given JMS message.
- * @param requestMessage current request message
- * @return the RemoteInvocation object (or {@code null}
- * in case of an invalid message that will simply be ignored)
- * @throws javax.jms.JMSException in case of message access failure
- */
- @Nullable
- protected RemoteInvocation readRemoteInvocation(Message requestMessage) throws JMSException {
- Object content = this.messageConverter.fromMessage(requestMessage);
- if (content instanceof RemoteInvocation) {
- return (RemoteInvocation) content;
- }
- return onInvalidRequest(requestMessage);
- }
-
-
- /**
- * Send the given RemoteInvocationResult as a JMS message to the originator.
- * @param requestMessage current request message
- * @param session the JMS Session to use
- * @param result the RemoteInvocationResult object
- * @throws javax.jms.JMSException if thrown by trying to send the message
- */
- protected void writeRemoteInvocationResult(
- Message requestMessage, Session session, RemoteInvocationResult result) throws JMSException {
-
- Message response = createResponseMessage(requestMessage, session, result);
- MessageProducer producer = session.createProducer(requestMessage.getJMSReplyTo());
- try {
- producer.send(response);
- }
- finally {
- JmsUtils.closeMessageProducer(producer);
- }
- }
-
- /**
- * Create the invocation result response message.
- *
The default implementation creates a JMS ObjectMessage for the given
- * RemoteInvocationResult object. It sets the response's correlation id
- * to the request message's correlation id, if any; otherwise to the
- * request message id.
- * @param request the original request message
- * @param session the JMS session to use
- * @param result the invocation result
- * @return the message response to send
- * @throws javax.jms.JMSException if creating the message failed
- */
- protected Message createResponseMessage(Message request, Session session, RemoteInvocationResult result)
- throws JMSException {
-
- Message response = this.messageConverter.toMessage(result, session);
- String correlation = request.getJMSCorrelationID();
- if (correlation == null) {
- correlation = request.getJMSMessageID();
- }
- response.setJMSCorrelationID(correlation);
- return response;
- }
-
- /**
- * Callback that is invoked by {@link #readRemoteInvocation}
- * when it encounters an invalid request message.
- *
The default implementation either discards the invalid message or
- * throws a MessageFormatException - according to the "ignoreInvalidRequests"
- * flag, which is set to "true" (that is, discard invalid messages) by default.
- * @param requestMessage the invalid request message
- * @return the RemoteInvocation to expose for the invalid request (typically
- * {@code null} in case of an invalid message that will simply be ignored)
- * @throws javax.jms.JMSException in case of the invalid request supposed
- * to lead to an exception (instead of ignoring it)
- * @see #readRemoteInvocation
- * @see #setIgnoreInvalidRequests
- */
- @Nullable
- protected RemoteInvocation onInvalidRequest(Message requestMessage) throws JMSException {
- if (this.ignoreInvalidRequests) {
- if (logger.isDebugEnabled()) {
- logger.debug("Invalid request message will be discarded: " + requestMessage);
- }
- return null;
- }
- else {
- throw new MessageFormatException("Invalid request message: " + requestMessage);
- }
- }
-
-}
diff --git a/spring-jms/src/main/java/org/springframework/jms/remoting/package-info.java b/spring-jms/src/main/java/org/springframework/jms/remoting/package-info.java
deleted file mode 100644
index 20e030430c..0000000000
--- a/spring-jms/src/main/java/org/springframework/jms/remoting/package-info.java
+++ /dev/null
@@ -1,13 +0,0 @@
-/**
- * Remoting classes for transparent Java-to-Java remoting via a JMS provider.
- *
- *
Allows the target service to be load-balanced across a number of queue
- * receivers, and provides a level of indirection between the client and the
- * service: They only need to agree on a queue name and a service interface.
- */
-@NonNullApi
-@NonNullFields
-package org.springframework.jms.remoting;
-
-import org.springframework.lang.NonNullApi;
-import org.springframework.lang.NonNullFields;
diff --git a/spring-jms/src/test/java/org/springframework/jms/remoting/JmsInvokerTests.java b/spring-jms/src/test/java/org/springframework/jms/remoting/JmsInvokerTests.java
deleted file mode 100644
index 299ee9321f..0000000000
--- a/spring-jms/src/test/java/org/springframework/jms/remoting/JmsInvokerTests.java
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Copyright 2002-2020 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.jms.remoting;
-
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.Enumeration;
-
-import javax.jms.CompletionListener;
-import javax.jms.Destination;
-import javax.jms.JMSException;
-import javax.jms.Message;
-import javax.jms.MessageProducer;
-import javax.jms.ObjectMessage;
-import javax.jms.Queue;
-import javax.jms.QueueConnection;
-import javax.jms.QueueConnectionFactory;
-import javax.jms.QueueSession;
-import javax.jms.Session;
-
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import org.springframework.beans.testfixture.beans.ITestBean;
-import org.springframework.beans.testfixture.beans.TestBean;
-import org.springframework.jms.support.converter.MessageConversionException;
-import org.springframework.jms.support.converter.SimpleMessageConverter;
-import org.springframework.remoting.RemoteTimeoutException;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.mock;
-
-/**
- * @author Juergen Hoeller
- * @author Stephane Nicoll
- */
-class JmsInvokerTests {
-
- private QueueConnectionFactory mockConnectionFactory = mock(QueueConnectionFactory.class);
-
- private QueueConnection mockConnection = mock(QueueConnection.class);
-
- private QueueSession mockSession = mock(QueueSession.class);
-
- private Queue mockQueue = mock(Queue.class);
-
-
- @BeforeEach
- void setUpMocks() throws Exception {
- given(mockConnectionFactory.createConnection()).willReturn(mockConnection);
- given(mockConnection.createSession(false, Session.AUTO_ACKNOWLEDGE)).willReturn(mockSession);
- }
-
-
- @Test
- void jmsInvokerProxyFactoryBeanAndServiceExporter() throws Throwable {
- doTestJmsInvokerProxyFactoryBeanAndServiceExporter(false);
- }
-
- @Test
- void jmsInvokerProxyFactoryBeanAndServiceExporterWithDynamicQueue() throws Throwable {
- given(mockSession.createQueue("myQueue")).willReturn(mockQueue);
- doTestJmsInvokerProxyFactoryBeanAndServiceExporter(true);
- }
-
- @Test
- @SuppressWarnings("deprecation")
- void receiveTimeoutExpired() {
- JmsInvokerProxyFactoryBean pfb = new JmsInvokerProxyFactoryBean() {
- @Override
- protected Message doExecuteRequest(Session session, Queue queue, Message requestMessage) throws JMSException {
- return null; // faking no message received
- }
- };
- pfb.setServiceInterface(ITestBean.class);
- pfb.setConnectionFactory(this.mockConnectionFactory);
- pfb.setQueue(this.mockQueue);
- pfb.setReceiveTimeout(1500);
- pfb.afterPropertiesSet();
- ITestBean proxy = (ITestBean) pfb.getObject();
-
- assertThatExceptionOfType(RemoteTimeoutException.class).isThrownBy(() ->
- proxy.getAge())
- .withMessageContaining("1500 ms")
- .withMessageContaining("getAge");
- }
-
- @SuppressWarnings("deprecation")
- private void doTestJmsInvokerProxyFactoryBeanAndServiceExporter(boolean dynamicQueue) throws Throwable {
- TestBean target = new TestBean("myname", 99);
-
- final JmsInvokerServiceExporter exporter = new JmsInvokerServiceExporter();
- exporter.setServiceInterface(ITestBean.class);
- exporter.setService(target);
- exporter.setMessageConverter(new MockSimpleMessageConverter());
- exporter.afterPropertiesSet();
-
- JmsInvokerProxyFactoryBean pfb = new JmsInvokerProxyFactoryBean() {
- @Override
- protected Message doExecuteRequest(Session session, Queue queue, Message requestMessage) throws JMSException {
- Session mockExporterSession = mock(Session.class);
- ResponseStoringProducer mockProducer = new ResponseStoringProducer();
- given(mockExporterSession.createProducer(requestMessage.getJMSReplyTo())).willReturn(mockProducer);
- exporter.onMessage(requestMessage, mockExporterSession);
- assertThat(mockProducer.closed).isTrue();
- return mockProducer.response;
- }
- };
- pfb.setServiceInterface(ITestBean.class);
- pfb.setConnectionFactory(this.mockConnectionFactory);
- if (dynamicQueue) {
- pfb.setQueueName("myQueue");
- }
- else {
- pfb.setQueue(this.mockQueue);
- }
- pfb.setMessageConverter(new MockSimpleMessageConverter());
-
- pfb.afterPropertiesSet();
- ITestBean proxy = (ITestBean) pfb.getObject();
-
- assertThat(proxy.getName()).isEqualTo("myname");
- assertThat(proxy.getAge()).isEqualTo(99);
- proxy.setAge(50);
- assertThat(proxy.getAge()).isEqualTo(50);
- proxy.setStringArray(new String[] {"str1", "str2"});
- assertThat(Arrays.equals(new String[] {"str1", "str2"}, proxy.getStringArray())).isTrue();
- assertThatIllegalStateException().isThrownBy(() ->
- proxy.exceptional(new IllegalStateException()));
- assertThatExceptionOfType(IllegalAccessException.class).isThrownBy(() ->
- proxy.exceptional(new IllegalAccessException()));
- }
-
-
- private static class ResponseStoringProducer implements MessageProducer {
-
- Message response;
-
- boolean closed = false;
-
- @Override
- public void setDisableMessageID(boolean b) throws JMSException {
- }
-
- @Override
- public boolean getDisableMessageID() throws JMSException {
- return false;
- }
-
- @Override
- public void setDisableMessageTimestamp(boolean b) throws JMSException {
- }
-
- @Override
- public boolean getDisableMessageTimestamp() throws JMSException {
- return false;
- }
-
- @Override
- public void setDeliveryMode(int i) throws JMSException {
- }
-
- @Override
- public int getDeliveryMode() throws JMSException {
- return 0;
- }
-
- @Override
- public void setPriority(int i) throws JMSException {
- }
-
- @Override
- public int getPriority() throws JMSException {
- return 0;
- }
-
- @Override
- public void setTimeToLive(long l) throws JMSException {
- }
-
- @Override
- public long getTimeToLive() throws JMSException {
- return 0;
- }
-
- @Override
- public void setDeliveryDelay(long deliveryDelay) throws JMSException {
- }
-
- @Override
- public long getDeliveryDelay() throws JMSException {
- return 0;
- }
-
- @Override
- public Destination getDestination() throws JMSException {
- return null;
- }
-
- @Override
- public void close() throws JMSException {
- this.closed = true;
- }
-
- @Override
- public void send(Message message) throws JMSException {
- this.response = message;
- }
-
- @Override
- public void send(Message message, int i, int i1, long l) throws JMSException {
- }
-
- @Override
- public void send(Destination destination, Message message) throws JMSException {
- }
-
- @Override
- public void send(Destination destination, Message message, int i, int i1, long l) throws JMSException {
- }
-
- @Override
- public void send(Message message, CompletionListener completionListener) throws JMSException {
- }
-
- @Override
- public void send(Message message, int deliveryMode, int priority, long timeToLive, CompletionListener completionListener) throws JMSException {
- }
-
- @Override
- public void send(Destination destination, Message message, CompletionListener completionListener) throws JMSException {
- }
-
- @Override
- public void send(Destination destination, Message message, int deliveryMode, int priority, long timeToLive, CompletionListener completionListener) throws JMSException {
- }
- }
-
-
- private static class MockObjectMessage implements ObjectMessage {
-
- private Serializable serializable;
-
- private Destination replyTo;
-
- public MockObjectMessage(Serializable serializable) {
- this.serializable = serializable;
- }
-
- @Override
- public void setObject(Serializable serializable) throws JMSException {
- this.serializable = serializable;
- }
-
- @Override
- public Serializable getObject() throws JMSException {
- return serializable;
- }
-
- @Override
- public String getJMSMessageID() throws JMSException {
- return null;
- }
-
- @Override
- public void setJMSMessageID(String string) throws JMSException {
- }
-
- @Override
- public long getJMSTimestamp() throws JMSException {
- return 0;
- }
-
- @Override
- public void setJMSTimestamp(long l) throws JMSException {
- }
-
- @Override
- public byte[] getJMSCorrelationIDAsBytes() throws JMSException {
- return new byte[0];
- }
-
- @Override
- public void setJMSCorrelationIDAsBytes(byte[] bytes) throws JMSException {
- }
-
- @Override
- public void setJMSCorrelationID(String string) throws JMSException {
- }
-
- @Override
- public String getJMSCorrelationID() throws JMSException {
- return null;
- }
-
- @Override
- public Destination getJMSReplyTo() throws JMSException {
- return replyTo;
- }
-
- @Override
- public void setJMSReplyTo(Destination destination) throws JMSException {
- this.replyTo = destination;
- }
-
- @Override
- public Destination getJMSDestination() throws JMSException {
- return null;
- }
-
- @Override
- public void setJMSDestination(Destination destination) throws JMSException {
- }
-
- @Override
- public int getJMSDeliveryMode() throws JMSException {
- return 0;
- }
-
- @Override
- public void setJMSDeliveryMode(int i) throws JMSException {
- }
-
- @Override
- public boolean getJMSRedelivered() throws JMSException {
- return false;
- }
-
- @Override
- public void setJMSRedelivered(boolean b) throws JMSException {
- }
-
- @Override
- public String getJMSType() throws JMSException {
- return null;
- }
-
- @Override
- public void setJMSType(String string) throws JMSException {
- }
-
- @Override
- public long getJMSExpiration() throws JMSException {
- return 0;
- }
-
- @Override
- public void setJMSExpiration(long l) throws JMSException {
- }
-
- @Override
- public int getJMSPriority() throws JMSException {
- return 0;
- }
-
- @Override
- public void setJMSPriority(int i) throws JMSException {
- }
-
- @Override
- public long getJMSDeliveryTime() throws JMSException {
- return 0;
- }
-
- @Override
- public void setJMSDeliveryTime(long deliveryTime) throws JMSException {
- }
-
- @Override
- public T getBody(Class c) throws JMSException {
- return null;
- }
-
- @Override
- @SuppressWarnings("rawtypes")
- public boolean isBodyAssignableTo(Class c) throws JMSException {
- return false;
- }
-
- @Override
- public void clearProperties() throws JMSException {
- }
-
- @Override
- public boolean propertyExists(String string) throws JMSException {
- return false;
- }
-
- @Override
- public boolean getBooleanProperty(String string) throws JMSException {
- return false;
- }
-
- @Override
- public byte getByteProperty(String string) throws JMSException {
- return 0;
- }
-
- @Override
- public short getShortProperty(String string) throws JMSException {
- return 0;
- }
-
- @Override
- public int getIntProperty(String string) throws JMSException {
- return 0;
- }
-
- @Override
- public long getLongProperty(String string) throws JMSException {
- return 0;
- }
-
- @Override
- public float getFloatProperty(String string) throws JMSException {
- return 0;
- }
-
- @Override
- public double getDoubleProperty(String string) throws JMSException {
- return 0;
- }
-
- @Override
- public String getStringProperty(String string) throws JMSException {
- return null;
- }
-
- @Override
- public Object getObjectProperty(String string) throws JMSException {
- return null;
- }
-
- @Override
- @SuppressWarnings("rawtypes")
- public Enumeration getPropertyNames() throws JMSException {
- return null;
- }
-
- @Override
- public void setBooleanProperty(String string, boolean b) throws JMSException {
- }
-
- @Override
- public void setByteProperty(String string, byte b) throws JMSException {
- }
-
- @Override
- public void setShortProperty(String string, short i) throws JMSException {
- }
-
- @Override
- public void setIntProperty(String string, int i) throws JMSException {
- }
-
- @Override
- public void setLongProperty(String string, long l) throws JMSException {
- }
-
- @Override
- public void setFloatProperty(String string, float v) throws JMSException {
- }
-
- @Override
- public void setDoubleProperty(String string, double v) throws JMSException {
- }
-
- @Override
- public void setStringProperty(String string, String string1) throws JMSException {
- }
-
- @Override
- public void setObjectProperty(String string, Object object) throws JMSException {
- }
-
- @Override
- public void acknowledge() throws JMSException {
- }
-
- @Override
- public void clearBody() throws JMSException {
- }
- }
-
-
- private static class MockSimpleMessageConverter extends SimpleMessageConverter {
-
- @Override
- public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
- return new MockObjectMessage((Serializable) object);
- }
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianClientInterceptor.java b/spring-web/src/main/java/org/springframework/remoting/caucho/HessianClientInterceptor.java
deleted file mode 100644
index 241a8580e1..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianClientInterceptor.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright 2002-2017 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.caucho;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.UndeclaredThrowableException;
-import java.net.ConnectException;
-import java.net.MalformedURLException;
-
-import com.caucho.hessian.HessianException;
-import com.caucho.hessian.client.HessianConnectionException;
-import com.caucho.hessian.client.HessianConnectionFactory;
-import com.caucho.hessian.client.HessianProxyFactory;
-import com.caucho.hessian.client.HessianRuntimeException;
-import com.caucho.hessian.io.SerializerFactory;
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-
-import org.springframework.lang.Nullable;
-import org.springframework.remoting.RemoteAccessException;
-import org.springframework.remoting.RemoteConnectFailureException;
-import org.springframework.remoting.RemoteLookupFailureException;
-import org.springframework.remoting.RemoteProxyFailureException;
-import org.springframework.remoting.support.UrlBasedRemoteAccessor;
-import org.springframework.util.Assert;
-
-/**
- * {@link org.aopalliance.intercept.MethodInterceptor} for accessing a Hessian service.
- * Supports authentication via username and password.
- * The service URL must be an HTTP URL exposing a Hessian service.
- *
- * Hessian is a slim, binary RPC protocol.
- * For information on Hessian, see the
- * Hessian website
- * Note: As of Spring 4.0, this client requires Hessian 4.0 or above.
- *
- *
Note: There is no requirement for services accessed with this proxy factory
- * to have been exported using Spring's {@link HessianServiceExporter}, as there is
- * no special handling involved. As a consequence, you can also access services that
- * have been exported using Caucho's {@link com.caucho.hessian.server.HessianServlet}.
- *
- * @author Juergen Hoeller
- * @since 29.09.2003
- * @see #setServiceInterface
- * @see #setServiceUrl
- * @see #setUsername
- * @see #setPassword
- * @see HessianServiceExporter
- * @see HessianProxyFactoryBean
- * @see com.caucho.hessian.client.HessianProxyFactory
- * @see com.caucho.hessian.server.HessianServlet
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class HessianClientInterceptor extends UrlBasedRemoteAccessor implements MethodInterceptor {
-
- private HessianProxyFactory proxyFactory = new HessianProxyFactory();
-
- @Nullable
- private Object hessianProxy;
-
-
- /**
- * Set the HessianProxyFactory instance to use.
- * If not specified, a default HessianProxyFactory will be created.
- *
Allows to use an externally configured factory instance,
- * in particular a custom HessianProxyFactory subclass.
- */
- public void setProxyFactory(@Nullable HessianProxyFactory proxyFactory) {
- this.proxyFactory = (proxyFactory != null ? proxyFactory : new HessianProxyFactory());
- }
-
- /**
- * Specify the Hessian SerializerFactory to use.
- *
This will typically be passed in as an inner bean definition
- * of type {@code com.caucho.hessian.io.SerializerFactory},
- * with custom bean property values applied.
- */
- public void setSerializerFactory(SerializerFactory serializerFactory) {
- this.proxyFactory.setSerializerFactory(serializerFactory);
- }
-
- /**
- * Set whether to send the Java collection type for each serialized
- * collection. Default is "true".
- */
- public void setSendCollectionType(boolean sendCollectionType) {
- this.proxyFactory.getSerializerFactory().setSendCollectionType(sendCollectionType);
- }
-
- /**
- * Set whether to allow non-serializable types as Hessian arguments
- * and return values. Default is "true".
- */
- public void setAllowNonSerializable(boolean allowNonSerializable) {
- this.proxyFactory.getSerializerFactory().setAllowNonSerializable(allowNonSerializable);
- }
-
- /**
- * Set whether overloaded methods should be enabled for remote invocations.
- * Default is "false".
- * @see com.caucho.hessian.client.HessianProxyFactory#setOverloadEnabled
- */
- public void setOverloadEnabled(boolean overloadEnabled) {
- this.proxyFactory.setOverloadEnabled(overloadEnabled);
- }
-
- /**
- * Set the username that this factory should use to access the remote service.
- * Default is none.
- *
The username will be sent by Hessian via HTTP Basic Authentication.
- * @see com.caucho.hessian.client.HessianProxyFactory#setUser
- */
- public void setUsername(String username) {
- this.proxyFactory.setUser(username);
- }
-
- /**
- * Set the password that this factory should use to access the remote service.
- * Default is none.
- *
The password will be sent by Hessian via HTTP Basic Authentication.
- * @see com.caucho.hessian.client.HessianProxyFactory#setPassword
- */
- public void setPassword(String password) {
- this.proxyFactory.setPassword(password);
- }
-
- /**
- * Set whether Hessian's debug mode should be enabled.
- * Default is "false".
- * @see com.caucho.hessian.client.HessianProxyFactory#setDebug
- */
- public void setDebug(boolean debug) {
- this.proxyFactory.setDebug(debug);
- }
-
- /**
- * Set whether to use a chunked post for sending a Hessian request.
- * @see com.caucho.hessian.client.HessianProxyFactory#setChunkedPost
- */
- public void setChunkedPost(boolean chunkedPost) {
- this.proxyFactory.setChunkedPost(chunkedPost);
- }
-
- /**
- * Specify a custom HessianConnectionFactory to use for the Hessian client.
- */
- public void setConnectionFactory(HessianConnectionFactory connectionFactory) {
- this.proxyFactory.setConnectionFactory(connectionFactory);
- }
-
- /**
- * Set the socket connect timeout to use for the Hessian client.
- * @see com.caucho.hessian.client.HessianProxyFactory#setConnectTimeout
- */
- public void setConnectTimeout(long timeout) {
- this.proxyFactory.setConnectTimeout(timeout);
- }
-
- /**
- * Set the timeout to use when waiting for a reply from the Hessian service.
- * @see com.caucho.hessian.client.HessianProxyFactory#setReadTimeout
- */
- public void setReadTimeout(long timeout) {
- this.proxyFactory.setReadTimeout(timeout);
- }
-
- /**
- * Set whether version 2 of the Hessian protocol should be used for
- * parsing requests and replies. Default is "false".
- * @see com.caucho.hessian.client.HessianProxyFactory#setHessian2Request
- */
- public void setHessian2(boolean hessian2) {
- this.proxyFactory.setHessian2Request(hessian2);
- this.proxyFactory.setHessian2Reply(hessian2);
- }
-
- /**
- * Set whether version 2 of the Hessian protocol should be used for
- * parsing requests. Default is "false".
- * @see com.caucho.hessian.client.HessianProxyFactory#setHessian2Request
- */
- public void setHessian2Request(boolean hessian2) {
- this.proxyFactory.setHessian2Request(hessian2);
- }
-
- /**
- * Set whether version 2 of the Hessian protocol should be used for
- * parsing replies. Default is "false".
- * @see com.caucho.hessian.client.HessianProxyFactory#setHessian2Reply
- */
- public void setHessian2Reply(boolean hessian2) {
- this.proxyFactory.setHessian2Reply(hessian2);
- }
-
-
- @Override
- public void afterPropertiesSet() {
- super.afterPropertiesSet();
- prepare();
- }
-
- /**
- * Initialize the Hessian proxy for this interceptor.
- * @throws RemoteLookupFailureException if the service URL is invalid
- */
- public void prepare() throws RemoteLookupFailureException {
- try {
- this.hessianProxy = createHessianProxy(this.proxyFactory);
- }
- catch (MalformedURLException ex) {
- throw new RemoteLookupFailureException("Service URL [" + getServiceUrl() + "] is invalid", ex);
- }
- }
-
- /**
- * Create the Hessian proxy that is wrapped by this interceptor.
- * @param proxyFactory the proxy factory to use
- * @return the Hessian proxy
- * @throws MalformedURLException if thrown by the proxy factory
- * @see com.caucho.hessian.client.HessianProxyFactory#create
- */
- protected Object createHessianProxy(HessianProxyFactory proxyFactory) throws MalformedURLException {
- Assert.notNull(getServiceInterface(), "'serviceInterface' is required");
- return proxyFactory.create(getServiceInterface(), getServiceUrl(), getBeanClassLoader());
- }
-
-
- @Override
- @Nullable
- public Object invoke(MethodInvocation invocation) throws Throwable {
- if (this.hessianProxy == null) {
- throw new IllegalStateException("HessianClientInterceptor is not properly initialized - " +
- "invoke 'prepare' before attempting any operations");
- }
-
- ClassLoader originalClassLoader = overrideThreadContextClassLoader();
- try {
- return invocation.getMethod().invoke(this.hessianProxy, invocation.getArguments());
- }
- catch (InvocationTargetException ex) {
- Throwable targetEx = ex.getTargetException();
- // Hessian 4.0 check: another layer of InvocationTargetException.
- if (targetEx instanceof InvocationTargetException) {
- targetEx = ((InvocationTargetException) targetEx).getTargetException();
- }
- if (targetEx instanceof HessianConnectionException) {
- throw convertHessianAccessException(targetEx);
- }
- else if (targetEx instanceof HessianException || targetEx instanceof HessianRuntimeException) {
- Throwable cause = targetEx.getCause();
- throw convertHessianAccessException(cause != null ? cause : targetEx);
- }
- else if (targetEx instanceof UndeclaredThrowableException) {
- UndeclaredThrowableException utex = (UndeclaredThrowableException) targetEx;
- throw convertHessianAccessException(utex.getUndeclaredThrowable());
- }
- else {
- throw targetEx;
- }
- }
- catch (Throwable ex) {
- throw new RemoteProxyFailureException(
- "Failed to invoke Hessian proxy for remote service [" + getServiceUrl() + "]", ex);
- }
- finally {
- resetThreadContextClassLoader(originalClassLoader);
- }
- }
-
- /**
- * Convert the given Hessian access exception to an appropriate
- * Spring RemoteAccessException.
- * @param ex the exception to convert
- * @return the RemoteAccessException to throw
- */
- protected RemoteAccessException convertHessianAccessException(Throwable ex) {
- if (ex instanceof HessianConnectionException || ex instanceof ConnectException) {
- return new RemoteConnectFailureException(
- "Cannot connect to Hessian remote service at [" + getServiceUrl() + "]", ex);
- }
- else {
- return new RemoteAccessException(
- "Cannot access Hessian remote service at [" + getServiceUrl() + "]", ex);
- }
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianExporter.java b/spring-web/src/main/java/org/springframework/remoting/caucho/HessianExporter.java
deleted file mode 100644
index b6c70e5fd7..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianExporter.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.caucho;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-
-import com.caucho.hessian.io.AbstractHessianInput;
-import com.caucho.hessian.io.AbstractHessianOutput;
-import com.caucho.hessian.io.Hessian2Input;
-import com.caucho.hessian.io.Hessian2Output;
-import com.caucho.hessian.io.HessianDebugInputStream;
-import com.caucho.hessian.io.HessianDebugOutputStream;
-import com.caucho.hessian.io.HessianInput;
-import com.caucho.hessian.io.HessianOutput;
-import com.caucho.hessian.io.HessianRemoteResolver;
-import com.caucho.hessian.io.SerializerFactory;
-import com.caucho.hessian.server.HessianSkeleton;
-import org.apache.commons.logging.Log;
-
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.lang.Nullable;
-import org.springframework.remoting.support.RemoteExporter;
-import org.springframework.util.Assert;
-import org.springframework.util.CommonsLogWriter;
-
-/**
- * General stream-based protocol exporter for a Hessian endpoint.
- *
- *
Hessian is a slim, binary RPC protocol.
- * For information on Hessian, see the
- * Hessian website .
- * Note: As of Spring 4.0, this exporter requires Hessian 4.0 or above.
- *
- * @author Juergen Hoeller
- * @since 2.5.1
- * @see #invoke(java.io.InputStream, java.io.OutputStream)
- * @see HessianServiceExporter
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class HessianExporter extends RemoteExporter implements InitializingBean {
-
- /**
- * The content type for hessian ({@code application/x-hessian}).
- */
- public static final String CONTENT_TYPE_HESSIAN = "application/x-hessian";
-
-
- private SerializerFactory serializerFactory = new SerializerFactory();
-
- @Nullable
- private HessianRemoteResolver remoteResolver;
-
- @Nullable
- private Log debugLogger;
-
- @Nullable
- private HessianSkeleton skeleton;
-
-
- /**
- * Specify the Hessian SerializerFactory to use.
- *
This will typically be passed in as an inner bean definition
- * of type {@code com.caucho.hessian.io.SerializerFactory},
- * with custom bean property values applied.
- */
- public void setSerializerFactory(@Nullable SerializerFactory serializerFactory) {
- this.serializerFactory = (serializerFactory != null ? serializerFactory : new SerializerFactory());
- }
-
- /**
- * Set whether to send the Java collection type for each serialized
- * collection. Default is "true".
- */
- public void setSendCollectionType(boolean sendCollectionType) {
- this.serializerFactory.setSendCollectionType(sendCollectionType);
- }
-
- /**
- * Set whether to allow non-serializable types as Hessian arguments
- * and return values. Default is "true".
- */
- public void setAllowNonSerializable(boolean allowNonSerializable) {
- this.serializerFactory.setAllowNonSerializable(allowNonSerializable);
- }
-
- /**
- * Specify a custom HessianRemoteResolver to use for resolving remote
- * object references.
- */
- public void setRemoteResolver(HessianRemoteResolver remoteResolver) {
- this.remoteResolver = remoteResolver;
- }
-
- /**
- * Set whether Hessian's debug mode should be enabled, logging to
- * this exporter's Commons Logging log. Default is "false".
- * @see com.caucho.hessian.client.HessianProxyFactory#setDebug
- */
- public void setDebug(boolean debug) {
- this.debugLogger = (debug ? logger : null);
- }
-
-
- @Override
- public void afterPropertiesSet() {
- prepare();
- }
-
- /**
- * Initialize this exporter.
- */
- public void prepare() {
- checkService();
- checkServiceInterface();
- this.skeleton = new HessianSkeleton(getProxyForService(), getServiceInterface());
- }
-
-
- /**
- * Perform an invocation on the exported object.
- * @param inputStream the request stream
- * @param outputStream the response stream
- * @throws Throwable if invocation failed
- */
- public void invoke(InputStream inputStream, OutputStream outputStream) throws Throwable {
- Assert.notNull(this.skeleton, "Hessian exporter has not been initialized");
- doInvoke(this.skeleton, inputStream, outputStream);
- }
-
- /**
- * Actually invoke the skeleton with the given streams.
- * @param skeleton the skeleton to invoke
- * @param inputStream the request stream
- * @param outputStream the response stream
- * @throws Throwable if invocation failed
- */
- protected void doInvoke(HessianSkeleton skeleton, InputStream inputStream, OutputStream outputStream)
- throws Throwable {
-
- ClassLoader originalClassLoader = overrideThreadContextClassLoader();
- try {
- InputStream isToUse = inputStream;
- OutputStream osToUse = outputStream;
-
- if (this.debugLogger != null && this.debugLogger.isDebugEnabled()) {
- try (PrintWriter debugWriter = new PrintWriter(new CommonsLogWriter(this.debugLogger))){
- @SuppressWarnings("resource")
- HessianDebugInputStream dis = new HessianDebugInputStream(inputStream, debugWriter);
- @SuppressWarnings("resource")
- HessianDebugOutputStream dos = new HessianDebugOutputStream(outputStream, debugWriter);
- dis.startTop2();
- dos.startTop2();
- isToUse = dis;
- osToUse = dos;
- }
- }
-
- if (!isToUse.markSupported()) {
- isToUse = new BufferedInputStream(isToUse);
- isToUse.mark(1);
- }
-
- int code = isToUse.read();
- int major;
- int minor;
-
- AbstractHessianInput in;
- AbstractHessianOutput out;
-
- if (code == 'H') {
- // Hessian 2.0 stream
- major = isToUse.read();
- minor = isToUse.read();
- if (major != 0x02) {
- throw new IOException("Version " + major + '.' + minor + " is not understood");
- }
- in = new Hessian2Input(isToUse);
- out = new Hessian2Output(osToUse);
- in.readCall();
- }
- else if (code == 'C') {
- // Hessian 2.0 call... for some reason not handled in HessianServlet!
- isToUse.reset();
- in = new Hessian2Input(isToUse);
- out = new Hessian2Output(osToUse);
- in.readCall();
- }
- else if (code == 'c') {
- // Hessian 1.0 call
- major = isToUse.read();
- minor = isToUse.read();
- in = new HessianInput(isToUse);
- if (major >= 2) {
- out = new Hessian2Output(osToUse);
- }
- else {
- out = new HessianOutput(osToUse);
- }
- }
- else {
- throw new IOException("Expected 'H'/'C' (Hessian 2.0) or 'c' (Hessian 1.0) in hessian input at " + code);
- }
-
- in.setSerializerFactory(this.serializerFactory);
- out.setSerializerFactory(this.serializerFactory);
- if (this.remoteResolver != null) {
- in.setRemoteResolver(this.remoteResolver);
- }
-
- try {
- skeleton.invoke(in, out);
- }
- finally {
- try {
- in.close();
- isToUse.close();
- }
- catch (IOException ex) {
- // ignore
- }
- try {
- out.close();
- osToUse.close();
- }
- catch (IOException ex) {
- // ignore
- }
- }
- }
- finally {
- resetThreadContextClassLoader(originalClassLoader);
- }
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianProxyFactoryBean.java b/spring-web/src/main/java/org/springframework/remoting/caucho/HessianProxyFactoryBean.java
deleted file mode 100644
index 45a66eacf5..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianProxyFactoryBean.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2002-2017 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.caucho;
-
-import org.springframework.aop.framework.ProxyFactory;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.lang.Nullable;
-
-/**
- * {@link FactoryBean} for Hessian proxies. Exposes the proxied service
- * for use as a bean reference, using the specified service interface.
- *
- *
Hessian is a slim, binary RPC protocol.
- * For information on Hessian, see the
- * Hessian website
- * Note: As of Spring 4.0, this proxy factory requires Hessian 4.0 or above.
- *
- *
The service URL must be an HTTP URL exposing a Hessian service.
- * For details, see the {@link HessianClientInterceptor} javadoc.
- *
- * @author Juergen Hoeller
- * @since 13.05.2003
- * @see #setServiceInterface
- * @see #setServiceUrl
- * @see HessianClientInterceptor
- * @see HessianServiceExporter
- * @see org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean
- * @see org.springframework.remoting.rmi.RmiProxyFactoryBean
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class HessianProxyFactoryBean extends HessianClientInterceptor implements FactoryBean {
-
- @Nullable
- private Object serviceProxy;
-
-
- @Override
- public void afterPropertiesSet() {
- super.afterPropertiesSet();
- this.serviceProxy = new ProxyFactory(getServiceInterface(), this).getProxy(getBeanClassLoader());
- }
-
-
- @Override
- @Nullable
- public Object getObject() {
- return this.serviceProxy;
- }
-
- @Override
- public Class> getObjectType() {
- return getServiceInterface();
- }
-
- @Override
- public boolean isSingleton() {
- return true;
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/caucho/HessianServiceExporter.java
deleted file mode 100644
index f25139ccf2..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianServiceExporter.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.caucho;
-
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.web.HttpRequestHandler;
-import org.springframework.web.HttpRequestMethodNotSupportedException;
-import org.springframework.web.util.NestedServletException;
-
-/**
- * Servlet-API-based HTTP request handler that exports the specified service bean
- * as Hessian service endpoint, accessible via a Hessian proxy.
- *
- * Hessian is a slim, binary RPC protocol.
- * For information on Hessian, see the
- * Hessian website .
- * Note: As of Spring 4.0, this exporter requires Hessian 4.0 or above.
- *
- *
Hessian services exported with this class can be accessed by
- * any Hessian client, as there isn't any special handling involved.
- *
- * @author Juergen Hoeller
- * @since 13.05.2003
- * @see HessianClientInterceptor
- * @see HessianProxyFactoryBean
- * @see org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter
- * @see org.springframework.remoting.rmi.RmiServiceExporter
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class HessianServiceExporter extends HessianExporter implements HttpRequestHandler {
-
- /**
- * Processes the incoming Hessian request and creates a Hessian response.
- */
- @Override
- public void handleRequest(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
-
- if (!"POST".equals(request.getMethod())) {
- throw new HttpRequestMethodNotSupportedException(request.getMethod(),
- new String[] {"POST"}, "HessianServiceExporter only supports POST requests");
- }
-
- response.setContentType(CONTENT_TYPE_HESSIAN);
- try {
- invoke(request.getInputStream(), response.getOutputStream());
- }
- catch (Throwable ex) {
- throw new NestedServletException("Hessian skeleton invocation failed", ex);
- }
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/caucho/SimpleHessianServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/caucho/SimpleHessianServiceExporter.java
deleted file mode 100644
index cc96b28bfa..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/caucho/SimpleHessianServiceExporter.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.caucho;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-import com.sun.net.httpserver.HttpExchange;
-import com.sun.net.httpserver.HttpHandler;
-
-import org.springframework.util.FileCopyUtils;
-
-/**
- * HTTP request handler that exports the specified service bean as
- * Hessian service endpoint, accessible via a Hessian proxy.
- * Designed for Sun's JRE 1.6 HTTP server, implementing the
- * {@link com.sun.net.httpserver.HttpHandler} interface.
- *
- *
Hessian is a slim, binary RPC protocol.
- * For information on Hessian, see the
- * Hessian website .
- * Note: As of Spring 4.0, this exporter requires Hessian 4.0 or above.
- *
- *
Hessian services exported with this class can be accessed by
- * any Hessian client, as there isn't any special handling involved.
- *
- * @author Juergen Hoeller
- * @since 2.5.1
- * @see org.springframework.remoting.caucho.HessianClientInterceptor
- * @see org.springframework.remoting.caucho.HessianProxyFactoryBean
- * @deprecated as of Spring Framework 5.1, in favor of {@link HessianServiceExporter}
- */
-@Deprecated
-@org.springframework.lang.UsesSunHttpServer
-public class SimpleHessianServiceExporter extends HessianExporter implements HttpHandler {
-
- /**
- * Processes the incoming Hessian request and creates a Hessian response.
- */
- @Override
- public void handle(HttpExchange exchange) throws IOException {
- if (!"POST".equals(exchange.getRequestMethod())) {
- exchange.getResponseHeaders().set("Allow", "POST");
- exchange.sendResponseHeaders(405, -1);
- return;
- }
-
- ByteArrayOutputStream output = new ByteArrayOutputStream(1024);
- try {
- invoke(exchange.getRequestBody(), output);
- }
- catch (Throwable ex) {
- exchange.sendResponseHeaders(500, -1);
- logger.error("Hessian skeleton invocation failed", ex);
- return;
- }
-
- exchange.getResponseHeaders().set("Content-Type", CONTENT_TYPE_HESSIAN);
- exchange.sendResponseHeaders(200, output.size());
- FileCopyUtils.copy(output.toByteArray(), exchange.getResponseBody());
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/caucho/package-info.java b/spring-web/src/main/java/org/springframework/remoting/caucho/package-info.java
deleted file mode 100644
index 30d03c5176..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/caucho/package-info.java
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
- * This package provides remoting classes for Caucho's Hessian protocol:
- * a proxy factory for accessing Hessian services, and an exporter for
- * making beans available to Hessian clients.
- *
- *
Hessian is a slim, binary RPC protocol over HTTP.
- * For information on Hessian, see the
- * Hessian website
- */
-@NonNullApi
-@NonNullFields
-package org.springframework.remoting.caucho;
-
-import org.springframework.lang.NonNullApi;
-import org.springframework.lang.NonNullFields;
diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java
deleted file mode 100644
index b1a34258ad..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright 2002-2020 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.httpinvoker;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.rmi.RemoteException;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.beans.factory.BeanClassLoaderAware;
-import org.springframework.lang.Nullable;
-import org.springframework.remoting.support.RemoteInvocation;
-import org.springframework.remoting.support.RemoteInvocationResult;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-
-/**
- * Abstract base implementation of the HttpInvokerRequestExecutor interface.
- *
- *
Pre-implements serialization of RemoteInvocation objects and
- * deserialization of RemoteInvocationResults objects.
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @see #doExecuteRequest
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public abstract class AbstractHttpInvokerRequestExecutor implements HttpInvokerRequestExecutor, BeanClassLoaderAware {
-
- /**
- * Default content type: "application/x-java-serialized-object".
- */
- public static final String CONTENT_TYPE_SERIALIZED_OBJECT = "application/x-java-serialized-object";
-
- private static final int SERIALIZED_INVOCATION_BYTE_ARRAY_INITIAL_SIZE = 1024;
-
-
- protected static final String HTTP_METHOD_POST = "POST";
-
- protected static final String HTTP_HEADER_ACCEPT_LANGUAGE = "Accept-Language";
-
- protected static final String HTTP_HEADER_ACCEPT_ENCODING = "Accept-Encoding";
-
- protected static final String HTTP_HEADER_CONTENT_ENCODING = "Content-Encoding";
-
- protected static final String HTTP_HEADER_CONTENT_TYPE = "Content-Type";
-
- protected static final String HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
-
- protected static final String ENCODING_GZIP = "gzip";
-
-
- protected final Log logger = LogFactory.getLog(getClass());
-
- private String contentType = CONTENT_TYPE_SERIALIZED_OBJECT;
-
- private boolean acceptGzipEncoding = true;
-
- @Nullable
- private ClassLoader beanClassLoader;
-
-
- /**
- * Specify the content type to use for sending HTTP invoker requests.
- *
Default is "application/x-java-serialized-object".
- */
- public void setContentType(String contentType) {
- Assert.notNull(contentType, "'contentType' must not be null");
- this.contentType = contentType;
- }
-
- /**
- * Return the content type to use for sending HTTP invoker requests.
- */
- public String getContentType() {
- return this.contentType;
- }
-
- /**
- * Set whether to accept GZIP encoding, that is, whether to
- * send the HTTP "Accept-Encoding" header with "gzip" as value.
- *
Default is "true". Turn this flag off if you do not want
- * GZIP response compression even if enabled on the HTTP server.
- */
- public void setAcceptGzipEncoding(boolean acceptGzipEncoding) {
- this.acceptGzipEncoding = acceptGzipEncoding;
- }
-
- /**
- * Return whether to accept GZIP encoding, that is, whether to
- * send the HTTP "Accept-Encoding" header with "gzip" as value.
- */
- public boolean isAcceptGzipEncoding() {
- return this.acceptGzipEncoding;
- }
-
- @Override
- public void setBeanClassLoader(ClassLoader classLoader) {
- this.beanClassLoader = classLoader;
- }
-
- /**
- * Return the bean ClassLoader that this executor is supposed to use.
- */
- @Nullable
- protected ClassLoader getBeanClassLoader() {
- return this.beanClassLoader;
- }
-
-
- @Override
- public final RemoteInvocationResult executeRequest(
- HttpInvokerClientConfiguration config, RemoteInvocation invocation) throws Exception {
-
- ByteArrayOutputStream baos = getByteArrayOutputStream(invocation);
- if (logger.isDebugEnabled()) {
- logger.debug("Sending HTTP invoker request for service at [" + config.getServiceUrl() +
- "], with size " + baos.size());
- }
- return doExecuteRequest(config, baos);
- }
-
- /**
- * Serialize the given RemoteInvocation into a ByteArrayOutputStream.
- * @param invocation the RemoteInvocation object
- * @return a ByteArrayOutputStream with the serialized RemoteInvocation
- * @throws IOException if thrown by I/O methods
- */
- protected ByteArrayOutputStream getByteArrayOutputStream(RemoteInvocation invocation) throws IOException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream(SERIALIZED_INVOCATION_BYTE_ARRAY_INITIAL_SIZE);
- writeRemoteInvocation(invocation, baos);
- return baos;
- }
-
- /**
- * Serialize the given RemoteInvocation to the given OutputStream.
- *
The default implementation gives {@code decorateOutputStream} a chance
- * to decorate the stream first (for example, for custom encryption or compression).
- * Creates an {@code ObjectOutputStream} for the final stream and calls
- * {@code doWriteRemoteInvocation} to actually write the object.
- *
Can be overridden for custom serialization of the invocation.
- * @param invocation the RemoteInvocation object
- * @param os the OutputStream to write to
- * @throws IOException if thrown by I/O methods
- * @see #decorateOutputStream
- * @see #doWriteRemoteInvocation
- */
- protected void writeRemoteInvocation(RemoteInvocation invocation, OutputStream os) throws IOException {
- try (ObjectOutputStream oos = new ObjectOutputStream(decorateOutputStream(os))) {
- doWriteRemoteInvocation(invocation, oos);
- }
- }
-
- /**
- * Return the OutputStream to use for writing remote invocations,
- * potentially decorating the given original OutputStream.
- *
The default implementation returns the given stream as-is.
- * Can be overridden, for example, for custom encryption or compression.
- * @param os the original OutputStream
- * @return the potentially decorated OutputStream
- */
- protected OutputStream decorateOutputStream(OutputStream os) throws IOException {
- return os;
- }
-
- /**
- * Perform the actual writing of the given invocation object to the
- * given ObjectOutputStream.
- *
The default implementation simply calls {@code writeObject}.
- * Can be overridden for serialization of a custom wrapper object rather
- * than the plain invocation, for example an encryption-aware holder.
- * @param invocation the RemoteInvocation object
- * @param oos the ObjectOutputStream to write to
- * @throws IOException if thrown by I/O methods
- * @see java.io.ObjectOutputStream#writeObject
- */
- protected void doWriteRemoteInvocation(RemoteInvocation invocation, ObjectOutputStream oos) throws IOException {
- oos.writeObject(invocation);
- }
-
-
- /**
- * Execute a request to send the given serialized remote invocation.
- *
Implementations will usually call {@code readRemoteInvocationResult}
- * to deserialize a returned RemoteInvocationResult object.
- * @param config the HTTP invoker configuration that specifies the
- * target service
- * @param baos the ByteArrayOutputStream that contains the serialized
- * RemoteInvocation object
- * @return the RemoteInvocationResult object
- * @throws IOException if thrown by I/O operations
- * @throws ClassNotFoundException if thrown during deserialization
- * @throws Exception in case of general errors
- * @see #readRemoteInvocationResult(java.io.InputStream, String)
- */
- protected abstract RemoteInvocationResult doExecuteRequest(
- HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)
- throws Exception;
-
- /**
- * Deserialize a RemoteInvocationResult object from the given InputStream.
- *
Gives {@code decorateInputStream} a chance to decorate the stream
- * first (for example, for custom encryption or compression). Creates an
- * {@code ObjectInputStream} via {@code createObjectInputStream} and
- * calls {@code doReadRemoteInvocationResult} to actually read the object.
- *
Can be overridden for custom serialization of the invocation.
- * @param is the InputStream to read from
- * @param codebaseUrl the codebase URL to load classes from if not found locally
- * @return the RemoteInvocationResult object
- * @throws IOException if thrown by I/O methods
- * @throws ClassNotFoundException if thrown during deserialization
- * @see #decorateInputStream
- * @see #createObjectInputStream
- * @see #doReadRemoteInvocationResult
- */
- protected RemoteInvocationResult readRemoteInvocationResult(InputStream is, @Nullable String codebaseUrl)
- throws IOException, ClassNotFoundException {
-
- try (ObjectInputStream ois = createObjectInputStream(decorateInputStream(is), codebaseUrl)) {
- return doReadRemoteInvocationResult(ois);
- }
- }
-
- /**
- * Return the InputStream to use for reading remote invocation results,
- * potentially decorating the given original InputStream.
- *
The default implementation returns the given stream as-is.
- * Can be overridden, for example, for custom encryption or compression.
- * @param is the original InputStream
- * @return the potentially decorated InputStream
- */
- protected InputStream decorateInputStream(InputStream is) throws IOException {
- return is;
- }
-
- /**
- * Create an ObjectInputStream for the given InputStream and codebase.
- * The default implementation creates a CodebaseAwareObjectInputStream.
- * @param is the InputStream to read from
- * @param codebaseUrl the codebase URL to load classes from if not found locally
- * (can be {@code null})
- * @return the new ObjectInputStream instance to use
- * @throws IOException if creation of the ObjectInputStream failed
- * @see org.springframework.remoting.rmi.CodebaseAwareObjectInputStream
- */
- protected ObjectInputStream createObjectInputStream(InputStream is, @Nullable String codebaseUrl) throws IOException {
- return new org.springframework.remoting.rmi.CodebaseAwareObjectInputStream(is, getBeanClassLoader(), codebaseUrl);
- }
-
- /**
- * Perform the actual reading of an invocation object from the
- * given ObjectInputStream.
- *
The default implementation simply calls {@code readObject}.
- * Can be overridden for deserialization of a custom wrapper object rather
- * than the plain invocation, for example an encryption-aware holder.
- * @param ois the ObjectInputStream to read from
- * @return the RemoteInvocationResult object
- * @throws IOException if thrown by I/O methods
- * @throws ClassNotFoundException if the class name of a serialized object
- * couldn't get resolved
- * @see java.io.ObjectOutputStream#writeObject
- */
- protected RemoteInvocationResult doReadRemoteInvocationResult(ObjectInputStream ois)
- throws IOException, ClassNotFoundException {
-
- Object obj = ois.readObject();
- if (!(obj instanceof RemoteInvocationResult)) {
- throw new RemoteException("Deserialized object needs to be assignable to type [" +
- RemoteInvocationResult.class.getName() + "]: " + ClassUtils.getDescriptiveType(obj));
- }
- return (RemoteInvocationResult) obj;
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutor.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutor.java
deleted file mode 100644
index c8a278fec4..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutor.java
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.httpinvoker;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Locale;
-import java.util.zip.GZIPInputStream;
-
-import org.apache.http.Header;
-import org.apache.http.HttpResponse;
-import org.apache.http.NoHttpResponseException;
-import org.apache.http.StatusLine;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.Configurable;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.config.Registry;
-import org.apache.http.config.RegistryBuilder;
-import org.apache.http.conn.socket.ConnectionSocketFactory;
-import org.apache.http.conn.socket.PlainConnectionSocketFactory;
-import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
-
-import org.springframework.context.i18n.LocaleContext;
-import org.springframework.context.i18n.LocaleContextHolder;
-import org.springframework.lang.Nullable;
-import org.springframework.remoting.support.RemoteInvocationResult;
-import org.springframework.util.Assert;
-
-/**
- * {@link org.springframework.remoting.httpinvoker.HttpInvokerRequestExecutor} implementation that uses
- * Apache HttpComponents HttpClient
- * to execute POST requests.
- *
- *
Allows to use a pre-configured {@link org.apache.http.client.HttpClient}
- * instance, potentially with authentication, HTTP connection pooling, etc.
- * Also designed for easy subclassing, providing specific template methods.
- *
- *
As of Spring 4.1, this request executor requires Apache HttpComponents 4.3 or higher.
- *
- * @author Juergen Hoeller
- * @author Stephane Nicoll
- * @since 3.1
- * @see org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class HttpComponentsHttpInvokerRequestExecutor extends AbstractHttpInvokerRequestExecutor {
-
- private static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 100;
-
- private static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 5;
-
- private static final int DEFAULT_READ_TIMEOUT_MILLISECONDS = (60 * 1000);
-
-
- private HttpClient httpClient;
-
- @Nullable
- private RequestConfig requestConfig;
-
-
- /**
- * Create a new instance of the HttpComponentsHttpInvokerRequestExecutor with a default
- * {@link HttpClient} that uses a default {@code org.apache.http.impl.conn.PoolingClientConnectionManager}.
- */
- public HttpComponentsHttpInvokerRequestExecutor() {
- this(createDefaultHttpClient(), RequestConfig.custom()
- .setSocketTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS).build());
- }
-
- /**
- * Create a new instance of the HttpComponentsClientHttpRequestFactory
- * with the given {@link HttpClient} instance.
- * @param httpClient the HttpClient instance to use for this request executor
- */
- public HttpComponentsHttpInvokerRequestExecutor(HttpClient httpClient) {
- this(httpClient, null);
- }
-
- private HttpComponentsHttpInvokerRequestExecutor(HttpClient httpClient, @Nullable RequestConfig requestConfig) {
- this.httpClient = httpClient;
- this.requestConfig = requestConfig;
- }
-
-
- private static HttpClient createDefaultHttpClient() {
- Registry schemeRegistry = RegistryBuilder.create()
- .register("http", PlainConnectionSocketFactory.getSocketFactory())
- .register("https", SSLConnectionSocketFactory.getSocketFactory())
- .build();
-
- PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(schemeRegistry);
- connectionManager.setMaxTotal(DEFAULT_MAX_TOTAL_CONNECTIONS);
- connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_CONNECTIONS_PER_ROUTE);
-
- return HttpClientBuilder.create().setConnectionManager(connectionManager).build();
- }
-
-
- /**
- * Set the {@link HttpClient} instance to use for this request executor.
- */
- public void setHttpClient(HttpClient httpClient) {
- this.httpClient = httpClient;
- }
-
- /**
- * Return the {@link HttpClient} instance that this request executor uses.
- */
- public HttpClient getHttpClient() {
- return this.httpClient;
- }
-
- /**
- * Set the connection timeout for the underlying HttpClient.
- * A timeout value of 0 specifies an infinite timeout.
- * Additional properties can be configured by specifying a
- * {@link RequestConfig} instance on a custom {@link HttpClient}.
- * @param timeout the timeout value in milliseconds
- * @see RequestConfig#getConnectTimeout()
- */
- public void setConnectTimeout(int timeout) {
- Assert.isTrue(timeout >= 0, "Timeout must be a non-negative value");
- this.requestConfig = cloneRequestConfig().setConnectTimeout(timeout).build();
- }
-
- /**
- * Set the timeout in milliseconds used when requesting a connection from the connection
- * manager using the underlying HttpClient.
- * A timeout value of 0 specifies an infinite timeout.
- *
Additional properties can be configured by specifying a
- * {@link RequestConfig} instance on a custom {@link HttpClient}.
- * @param connectionRequestTimeout the timeout value to request a connection in milliseconds
- * @see RequestConfig#getConnectionRequestTimeout()
- */
- public void setConnectionRequestTimeout(int connectionRequestTimeout) {
- this.requestConfig = cloneRequestConfig().setConnectionRequestTimeout(connectionRequestTimeout).build();
- }
-
- /**
- * Set the socket read timeout for the underlying HttpClient.
- * A timeout value of 0 specifies an infinite timeout.
- *
Additional properties can be configured by specifying a
- * {@link RequestConfig} instance on a custom {@link HttpClient}.
- * @param timeout the timeout value in milliseconds
- * @see #DEFAULT_READ_TIMEOUT_MILLISECONDS
- * @see RequestConfig#getSocketTimeout()
- */
- public void setReadTimeout(int timeout) {
- Assert.isTrue(timeout >= 0, "Timeout must be a non-negative value");
- this.requestConfig = cloneRequestConfig().setSocketTimeout(timeout).build();
- }
-
- private RequestConfig.Builder cloneRequestConfig() {
- return (this.requestConfig != null ? RequestConfig.copy(this.requestConfig) : RequestConfig.custom());
- }
-
-
- /**
- * Execute the given request through the HttpClient.
- *
This method implements the basic processing workflow:
- * The actual work happens in this class's template methods.
- * @see #createHttpPost
- * @see #setRequestBody
- * @see #executeHttpPost
- * @see #validateResponse
- * @see #getResponseBody
- */
- @Override
- protected RemoteInvocationResult doExecuteRequest(
- HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)
- throws IOException, ClassNotFoundException {
-
- HttpPost postMethod = createHttpPost(config);
- setRequestBody(config, postMethod, baos);
- try {
- HttpResponse response = executeHttpPost(config, getHttpClient(), postMethod);
- validateResponse(config, response);
- InputStream responseBody = getResponseBody(config, response);
- return readRemoteInvocationResult(responseBody, config.getCodebaseUrl());
- }
- finally {
- postMethod.releaseConnection();
- }
- }
-
- /**
- * Create an HttpPost for the given configuration.
- *
The default implementation creates a standard HttpPost with
- * "application/x-java-serialized-object" as "Content-Type" header.
- * @param config the HTTP invoker configuration that specifies the
- * target service
- * @return the HttpPost instance
- * @throws java.io.IOException if thrown by I/O methods
- */
- protected HttpPost createHttpPost(HttpInvokerClientConfiguration config) throws IOException {
- HttpPost httpPost = new HttpPost(config.getServiceUrl());
-
- RequestConfig requestConfig = createRequestConfig(config);
- if (requestConfig != null) {
- httpPost.setConfig(requestConfig);
- }
-
- LocaleContext localeContext = LocaleContextHolder.getLocaleContext();
- if (localeContext != null) {
- Locale locale = localeContext.getLocale();
- if (locale != null) {
- httpPost.addHeader(HTTP_HEADER_ACCEPT_LANGUAGE, locale.toLanguageTag());
- }
- }
-
- if (isAcceptGzipEncoding()) {
- httpPost.addHeader(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
- }
-
- return httpPost;
- }
-
- /**
- * Create a {@link RequestConfig} for the given configuration. Can return {@code null}
- * to indicate that no custom request config should be set and the defaults of the
- * {@link HttpClient} should be used.
- *
The default implementation tries to merge the defaults of the client with the
- * local customizations of the instance, if any.
- * @param config the HTTP invoker configuration that specifies the
- * target service
- * @return the RequestConfig to use
- */
- @Nullable
- protected RequestConfig createRequestConfig(HttpInvokerClientConfiguration config) {
- HttpClient client = getHttpClient();
- if (client instanceof Configurable) {
- RequestConfig clientRequestConfig = ((Configurable) client).getConfig();
- return mergeRequestConfig(clientRequestConfig);
- }
- return this.requestConfig;
- }
-
- private RequestConfig mergeRequestConfig(RequestConfig defaultRequestConfig) {
- if (this.requestConfig == null) { // nothing to merge
- return defaultRequestConfig;
- }
-
- RequestConfig.Builder builder = RequestConfig.copy(defaultRequestConfig);
- int connectTimeout = this.requestConfig.getConnectTimeout();
- if (connectTimeout >= 0) {
- builder.setConnectTimeout(connectTimeout);
- }
- int connectionRequestTimeout = this.requestConfig.getConnectionRequestTimeout();
- if (connectionRequestTimeout >= 0) {
- builder.setConnectionRequestTimeout(connectionRequestTimeout);
- }
- int socketTimeout = this.requestConfig.getSocketTimeout();
- if (socketTimeout >= 0) {
- builder.setSocketTimeout(socketTimeout);
- }
- return builder.build();
- }
-
- /**
- * Set the given serialized remote invocation as request body.
- *
The default implementation simply sets the serialized invocation as the
- * HttpPost's request body. This can be overridden, for example, to write a
- * specific encoding and to potentially set appropriate HTTP request headers.
- * @param config the HTTP invoker configuration that specifies the target service
- * @param httpPost the HttpPost to set the request body on
- * @param baos the ByteArrayOutputStream that contains the serialized
- * RemoteInvocation object
- * @throws java.io.IOException if thrown by I/O methods
- */
- protected void setRequestBody(
- HttpInvokerClientConfiguration config, HttpPost httpPost, ByteArrayOutputStream baos)
- throws IOException {
-
- ByteArrayEntity entity = new ByteArrayEntity(baos.toByteArray());
- entity.setContentType(getContentType());
- httpPost.setEntity(entity);
- }
-
- /**
- * Execute the given HttpPost instance.
- * @param config the HTTP invoker configuration that specifies the target service
- * @param httpClient the HttpClient to execute on
- * @param httpPost the HttpPost to execute
- * @return the resulting HttpResponse
- * @throws java.io.IOException if thrown by I/O methods
- */
- protected HttpResponse executeHttpPost(
- HttpInvokerClientConfiguration config, HttpClient httpClient, HttpPost httpPost)
- throws IOException {
-
- return httpClient.execute(httpPost);
- }
-
- /**
- * Validate the given response as contained in the HttpPost object,
- * throwing an exception if it does not correspond to a successful HTTP response.
- *
Default implementation rejects any HTTP status code beyond 2xx, to avoid
- * parsing the response body and trying to deserialize from a corrupted stream.
- * @param config the HTTP invoker configuration that specifies the target service
- * @param response the resulting HttpResponse to validate
- * @throws java.io.IOException if validation failed
- */
- protected void validateResponse(HttpInvokerClientConfiguration config, HttpResponse response)
- throws IOException {
-
- StatusLine status = response.getStatusLine();
- if (status.getStatusCode() >= 300) {
- throw new NoHttpResponseException(
- "Did not receive successful HTTP response: status code = " + status.getStatusCode() +
- ", status message = [" + status.getReasonPhrase() + "]");
- }
- }
-
- /**
- * Extract the response body from the given executed remote invocation request.
- *
The default implementation simply fetches the HttpPost's response body stream.
- * If the response is recognized as GZIP response, the InputStream will get wrapped
- * in a GZIPInputStream.
- * @param config the HTTP invoker configuration that specifies the target service
- * @param httpResponse the resulting HttpResponse to read the response body from
- * @return an InputStream for the response body
- * @throws java.io.IOException if thrown by I/O methods
- * @see #isGzipResponse
- * @see java.util.zip.GZIPInputStream
- */
- protected InputStream getResponseBody(HttpInvokerClientConfiguration config, HttpResponse httpResponse)
- throws IOException {
-
- if (isGzipResponse(httpResponse)) {
- return new GZIPInputStream(httpResponse.getEntity().getContent());
- }
- else {
- return httpResponse.getEntity().getContent();
- }
- }
-
- /**
- * Determine whether the given response indicates a GZIP response.
- *
The default implementation checks whether the HTTP "Content-Encoding"
- * header contains "gzip" (in any casing).
- * @param httpResponse the resulting HttpResponse to check
- * @return whether the given response indicates a GZIP response
- */
- protected boolean isGzipResponse(HttpResponse httpResponse) {
- Header encodingHeader = httpResponse.getFirstHeader(HTTP_HEADER_CONTENT_ENCODING);
- return (encodingHeader != null && encodingHeader.getValue() != null &&
- encodingHeader.getValue().toLowerCase().contains(ENCODING_GZIP));
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientConfiguration.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientConfiguration.java
deleted file mode 100644
index 9e81e1d289..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientConfiguration.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.httpinvoker;
-
-import org.springframework.lang.Nullable;
-
-/**
- * Configuration interface for executing HTTP invoker requests.
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @see HttpInvokerRequestExecutor
- * @see HttpInvokerClientInterceptor
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public interface HttpInvokerClientConfiguration {
-
- /**
- * Return the HTTP URL of the target service.
- */
- String getServiceUrl();
-
- /**
- * Return the codebase URL to download classes from if not found locally.
- * Can consist of multiple URLs, separated by spaces.
- * @return the codebase URL, or {@code null} if none
- * @see java.rmi.server.RMIClassLoader
- */
- @Nullable
- String getCodebaseUrl();
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientInterceptor.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientInterceptor.java
deleted file mode 100644
index 361101475e..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerClientInterceptor.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright 2002-2020 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.httpinvoker;
-
-import java.io.IOException;
-import java.io.InvalidClassException;
-import java.net.ConnectException;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-
-import org.springframework.aop.support.AopUtils;
-import org.springframework.lang.Nullable;
-import org.springframework.remoting.RemoteAccessException;
-import org.springframework.remoting.RemoteConnectFailureException;
-import org.springframework.remoting.RemoteInvocationFailureException;
-import org.springframework.remoting.support.RemoteInvocation;
-import org.springframework.remoting.support.RemoteInvocationBasedAccessor;
-import org.springframework.remoting.support.RemoteInvocationResult;
-
-/**
- * {@link org.aopalliance.intercept.MethodInterceptor} for accessing an
- * HTTP invoker service. The service URL must be an HTTP URL exposing
- * an HTTP invoker service.
- *
- *
Serializes remote invocation objects and deserializes remote invocation
- * result objects. Uses Java serialization just like RMI, but provides the
- * same ease of setup as Caucho's HTTP-based Hessian protocol.
- *
- *
HTTP invoker is a very extensible and customizable protocol.
- * It supports the RemoteInvocationFactory mechanism, like RMI invoker,
- * allowing to include additional invocation attributes (for example,
- * a security context). Furthermore, it allows to customize request
- * execution via the {@link HttpInvokerRequestExecutor} strategy.
- *
- *
Can use the JDK's {@link java.rmi.server.RMIClassLoader} to load classes
- * from a given {@link #setCodebaseUrl codebase}, performing on-demand dynamic
- * code download from a remote location. The codebase can consist of multiple
- * URLs, separated by spaces. Note that RMIClassLoader requires a SecurityManager
- * to be set, analogous to when using dynamic class download with standard RMI!
- * (See the RMI documentation for details.)
- *
- *
WARNING: Be aware of vulnerabilities due to unsafe Java deserialization:
- * Manipulated input streams could lead to unwanted code execution on the server
- * during the deserialization step. As a consequence, do not expose HTTP invoker
- * endpoints to untrusted clients but rather just between your own services.
- * In general, we strongly recommend any other message format (e.g. JSON) instead.
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @see #setServiceUrl
- * @see #setCodebaseUrl
- * @see #setRemoteInvocationFactory
- * @see #setHttpInvokerRequestExecutor
- * @see HttpInvokerServiceExporter
- * @see HttpInvokerProxyFactoryBean
- * @see java.rmi.server.RMIClassLoader
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class HttpInvokerClientInterceptor extends RemoteInvocationBasedAccessor
- implements MethodInterceptor, HttpInvokerClientConfiguration {
-
- @Nullable
- private String codebaseUrl;
-
- @Nullable
- private HttpInvokerRequestExecutor httpInvokerRequestExecutor;
-
-
- /**
- * Set the codebase URL to download classes from if not found locally.
- * Can consists of multiple URLs, separated by spaces.
- *
Follows RMI's codebase conventions for dynamic class download.
- * In contrast to RMI, where the server determines the URL for class download
- * (via the "java.rmi.server.codebase" system property), it's the client
- * that determines the codebase URL here. The server will usually be the
- * same as for the service URL, just pointing to a different path there.
- * @see #setServiceUrl
- * @see org.springframework.remoting.rmi.CodebaseAwareObjectInputStream
- * @see java.rmi.server.RMIClassLoader
- */
- public void setCodebaseUrl(@Nullable String codebaseUrl) {
- this.codebaseUrl = codebaseUrl;
- }
-
- /**
- * Return the codebase URL to download classes from if not found locally.
- */
- @Override
- @Nullable
- public String getCodebaseUrl() {
- return this.codebaseUrl;
- }
-
- /**
- * Set the HttpInvokerRequestExecutor implementation to use for executing
- * remote invocations.
- *
Default is {@link SimpleHttpInvokerRequestExecutor}. Alternatively,
- * consider using {@link HttpComponentsHttpInvokerRequestExecutor} for more
- * sophisticated needs.
- * @see SimpleHttpInvokerRequestExecutor
- * @see HttpComponentsHttpInvokerRequestExecutor
- */
- public void setHttpInvokerRequestExecutor(HttpInvokerRequestExecutor httpInvokerRequestExecutor) {
- this.httpInvokerRequestExecutor = httpInvokerRequestExecutor;
- }
-
- /**
- * Return the HttpInvokerRequestExecutor used by this remote accessor.
- *
Creates a default SimpleHttpInvokerRequestExecutor if no executor
- * has been initialized already.
- */
- public HttpInvokerRequestExecutor getHttpInvokerRequestExecutor() {
- if (this.httpInvokerRequestExecutor == null) {
- SimpleHttpInvokerRequestExecutor executor = new SimpleHttpInvokerRequestExecutor();
- executor.setBeanClassLoader(getBeanClassLoader());
- this.httpInvokerRequestExecutor = executor;
- }
- return this.httpInvokerRequestExecutor;
- }
-
- @Override
- public void afterPropertiesSet() {
- super.afterPropertiesSet();
-
- // Eagerly initialize the default HttpInvokerRequestExecutor, if needed.
- getHttpInvokerRequestExecutor();
- }
-
-
- @Override
- @Nullable
- public Object invoke(MethodInvocation methodInvocation) throws Throwable {
- if (AopUtils.isToStringMethod(methodInvocation.getMethod())) {
- return "HTTP invoker proxy for service URL [" + getServiceUrl() + "]";
- }
-
- RemoteInvocation invocation = createRemoteInvocation(methodInvocation);
- RemoteInvocationResult result;
-
- try {
- result = executeRequest(invocation, methodInvocation);
- }
- catch (Throwable ex) {
- RemoteAccessException rae = convertHttpInvokerAccessException(ex);
- throw (rae != null ? rae : ex);
- }
-
- try {
- return recreateRemoteInvocationResult(result);
- }
- catch (Throwable ex) {
- if (result.hasInvocationTargetException()) {
- throw ex;
- }
- else {
- throw new RemoteInvocationFailureException("Invocation of method [" + methodInvocation.getMethod() +
- "] failed in HTTP invoker remote service at [" + getServiceUrl() + "]", ex);
- }
- }
- }
-
- /**
- * Execute the given remote invocation via the {@link HttpInvokerRequestExecutor}.
- *
This implementation delegates to {@link #executeRequest(RemoteInvocation)}.
- * Can be overridden to react to the specific original MethodInvocation.
- * @param invocation the RemoteInvocation to execute
- * @param originalInvocation the original MethodInvocation (can e.g. be cast
- * to the ProxyMethodInvocation interface for accessing user attributes)
- * @return the RemoteInvocationResult object
- * @throws Exception in case of errors
- */
- protected RemoteInvocationResult executeRequest(
- RemoteInvocation invocation, MethodInvocation originalInvocation) throws Exception {
-
- return executeRequest(invocation);
- }
-
- /**
- * Execute the given remote invocation via the {@link HttpInvokerRequestExecutor}.
- *
Can be overridden in subclasses to pass a different configuration object
- * to the executor. Alternatively, add further configuration properties in a
- * subclass of this accessor: By default, the accessor passed itself as
- * configuration object to the executor.
- * @param invocation the RemoteInvocation to execute
- * @return the RemoteInvocationResult object
- * @throws IOException if thrown by I/O operations
- * @throws ClassNotFoundException if thrown during deserialization
- * @throws Exception in case of general errors
- * @see #getHttpInvokerRequestExecutor
- * @see HttpInvokerClientConfiguration
- */
- protected RemoteInvocationResult executeRequest(RemoteInvocation invocation) throws Exception {
- return getHttpInvokerRequestExecutor().executeRequest(this, invocation);
- }
-
- /**
- * Convert the given HTTP invoker access exception to an appropriate
- * Spring {@link RemoteAccessException}.
- * @param ex the exception to convert
- * @return the RemoteAccessException to throw, or {@code null} to have the
- * original exception propagated to the caller
- */
- @Nullable
- protected RemoteAccessException convertHttpInvokerAccessException(Throwable ex) {
- if (ex instanceof ConnectException) {
- return new RemoteConnectFailureException(
- "Could not connect to HTTP invoker remote service at [" + getServiceUrl() + "]", ex);
- }
-
- if (ex instanceof ClassNotFoundException || ex instanceof NoClassDefFoundError ||
- ex instanceof InvalidClassException) {
- return new RemoteAccessException(
- "Could not deserialize result from HTTP invoker remote service [" + getServiceUrl() + "]", ex);
- }
-
- if (ex instanceof Exception) {
- return new RemoteAccessException(
- "Could not access HTTP invoker remote service at [" + getServiceUrl() + "]", ex);
- }
-
- // For any other Throwable, e.g. OutOfMemoryError: let it get propagated as-is.
- return null;
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java
deleted file mode 100644
index ae483e45ff..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright 2002-2017 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.httpinvoker;
-
-import org.springframework.aop.framework.ProxyFactory;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.lang.Nullable;
-import org.springframework.util.Assert;
-
-/**
- * {@link FactoryBean} for HTTP invoker proxies. Exposes the proxied service
- * for use as a bean reference, using the specified service interface.
- *
- *
The service URL must be an HTTP URL exposing an HTTP invoker service.
- * Optionally, a codebase URL can be specified for on-demand dynamic code download
- * from a remote location. For details, see HttpInvokerClientInterceptor docs.
- *
- *
Serializes remote invocation objects and deserializes remote invocation
- * result objects. Uses Java serialization just like RMI, but provides the
- * same ease of setup as Caucho's HTTP-based Hessian protocol.
- *
- *
HTTP invoker is the recommended protocol for Java-to-Java remoting.
- * It is more powerful and more extensible than Hessian, at the expense of
- * being tied to Java. Nevertheless, it is as easy to set up as Hessian,
- * which is its main advantage compared to RMI.
- *
- *
WARNING: Be aware of vulnerabilities due to unsafe Java deserialization:
- * Manipulated input streams could lead to unwanted code execution on the server
- * during the deserialization step. As a consequence, do not expose HTTP invoker
- * endpoints to untrusted clients but rather just between your own services.
- * In general, we strongly recommend any other message format (e.g. JSON) instead.
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @see #setServiceInterface
- * @see #setServiceUrl
- * @see #setCodebaseUrl
- * @see HttpInvokerClientInterceptor
- * @see HttpInvokerServiceExporter
- * @see org.springframework.remoting.rmi.RmiProxyFactoryBean
- * @see org.springframework.remoting.caucho.HessianProxyFactoryBean
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class HttpInvokerProxyFactoryBean extends HttpInvokerClientInterceptor implements FactoryBean {
-
- @Nullable
- private Object serviceProxy;
-
-
- @Override
- public void afterPropertiesSet() {
- super.afterPropertiesSet();
- Class> ifc = getServiceInterface();
- Assert.notNull(ifc, "Property 'serviceInterface' is required");
- this.serviceProxy = new ProxyFactory(ifc, this).getProxy(getBeanClassLoader());
- }
-
-
- @Override
- @Nullable
- public Object getObject() {
- return this.serviceProxy;
- }
-
- @Override
- public Class> getObjectType() {
- return getServiceInterface();
- }
-
- @Override
- public boolean isSingleton() {
- return true;
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerRequestExecutor.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerRequestExecutor.java
deleted file mode 100644
index d5236e5179..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerRequestExecutor.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2002-2016 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.httpinvoker;
-
-import java.io.IOException;
-
-import org.springframework.remoting.support.RemoteInvocation;
-import org.springframework.remoting.support.RemoteInvocationResult;
-
-/**
- * Strategy interface for actual execution of an HTTP invoker request.
- * Used by HttpInvokerClientInterceptor and its subclass
- * HttpInvokerProxyFactoryBean.
- *
- * Two implementations are provided out of the box:
- *
- * {@code SimpleHttpInvokerRequestExecutor}:
- * Uses JDK facilities to execute POST requests, without support
- * for HTTP authentication or advanced configuration options.
- * {@code HttpComponentsHttpInvokerRequestExecutor}:
- * Uses Apache's Commons HttpClient to execute POST requests,
- * allowing to use a preconfigured HttpClient instance
- * (potentially with authentication, HTTP connection pooling, etc).
- *
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @see HttpInvokerClientInterceptor#setHttpInvokerRequestExecutor
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-@FunctionalInterface
-public interface HttpInvokerRequestExecutor {
-
- /**
- * Execute a request to send the given remote invocation.
- * @param config the HTTP invoker configuration that specifies the
- * target service
- * @param invocation the RemoteInvocation to execute
- * @return the RemoteInvocationResult object
- * @throws IOException if thrown by I/O operations
- * @throws ClassNotFoundException if thrown during deserialization
- * @throws Exception in case of general errors
- */
- RemoteInvocationResult executeRequest(HttpInvokerClientConfiguration config, RemoteInvocation invocation)
- throws Exception;
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.java
deleted file mode 100644
index dc1a0ac746..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerServiceExporter.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright 2002-2020 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.httpinvoker;
-
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.springframework.remoting.support.RemoteInvocation;
-import org.springframework.remoting.support.RemoteInvocationResult;
-import org.springframework.web.HttpRequestHandler;
-import org.springframework.web.util.NestedServletException;
-
-/**
- * Servlet-API-based HTTP request handler that exports the specified service bean
- * as HTTP invoker service endpoint, accessible via an HTTP invoker proxy.
- *
- * Deserializes remote invocation objects and serializes remote invocation
- * result objects. Uses Java serialization just like RMI, but provides the
- * same ease of setup as Caucho's HTTP-based Hessian protocol.
- *
- *
HTTP invoker is the recommended protocol for Java-to-Java remoting.
- * It is more powerful and more extensible than Hessian, at the expense of
- * being tied to Java. Nevertheless, it is as easy to set up as Hessian,
- * which is its main advantage compared to RMI.
- *
- *
WARNING: Be aware of vulnerabilities due to unsafe Java deserialization:
- * Manipulated input streams could lead to unwanted code execution on the server
- * during the deserialization step. As a consequence, do not expose HTTP invoker
- * endpoints to untrusted clients but rather just between your own services.
- * In general, we strongly recommend any other message format (e.g. JSON) instead.
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @see HttpInvokerClientInterceptor
- * @see HttpInvokerProxyFactoryBean
- * @see org.springframework.remoting.rmi.RmiServiceExporter
- * @see org.springframework.remoting.caucho.HessianServiceExporter
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class HttpInvokerServiceExporter extends org.springframework.remoting.rmi.RemoteInvocationSerializingExporter implements HttpRequestHandler {
-
- /**
- * Reads a remote invocation from the request, executes it,
- * and writes the remote invocation result to the response.
- * @see #readRemoteInvocation(HttpServletRequest)
- * @see #invokeAndCreateResult(org.springframework.remoting.support.RemoteInvocation, Object)
- * @see #writeRemoteInvocationResult(HttpServletRequest, HttpServletResponse, RemoteInvocationResult)
- */
- @Override
- public void handleRequest(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
-
- try {
- RemoteInvocation invocation = readRemoteInvocation(request);
- RemoteInvocationResult result = invokeAndCreateResult(invocation, getProxy());
- writeRemoteInvocationResult(request, response, result);
- }
- catch (ClassNotFoundException ex) {
- throw new NestedServletException("Class not found during deserialization", ex);
- }
- }
-
- /**
- * Read a RemoteInvocation from the given HTTP request.
- *
Delegates to {@link #readRemoteInvocation(HttpServletRequest, InputStream)} with
- * the {@link HttpServletRequest#getInputStream() servlet request's input stream}.
- * @param request current HTTP request
- * @return the RemoteInvocation object
- * @throws IOException in case of I/O failure
- * @throws ClassNotFoundException if thrown by deserialization
- */
- protected RemoteInvocation readRemoteInvocation(HttpServletRequest request)
- throws IOException, ClassNotFoundException {
-
- return readRemoteInvocation(request, request.getInputStream());
- }
-
- /**
- * Deserialize a RemoteInvocation object from the given InputStream.
- *
Gives {@link #decorateInputStream} a chance to decorate the stream
- * first (for example, for custom encryption or compression). Creates a
- * {@link org.springframework.remoting.rmi.CodebaseAwareObjectInputStream}
- * and calls {@link #doReadRemoteInvocation} to actually read the object.
- *
Can be overridden for custom serialization of the invocation.
- * @param request current HTTP request
- * @param is the InputStream to read from
- * @return the RemoteInvocation object
- * @throws IOException in case of I/O failure
- * @throws ClassNotFoundException if thrown during deserialization
- */
- protected RemoteInvocation readRemoteInvocation(HttpServletRequest request, InputStream is)
- throws IOException, ClassNotFoundException {
-
- try (ObjectInputStream ois = createObjectInputStream(decorateInputStream(request, is))) {
- return doReadRemoteInvocation(ois);
- }
- }
-
- /**
- * Return the InputStream to use for reading remote invocations,
- * potentially decorating the given original InputStream.
- *
The default implementation returns the given stream as-is.
- * Can be overridden, for example, for custom encryption or compression.
- * @param request current HTTP request
- * @param is the original InputStream
- * @return the potentially decorated InputStream
- * @throws IOException in case of I/O failure
- */
- protected InputStream decorateInputStream(HttpServletRequest request, InputStream is) throws IOException {
- return is;
- }
-
- /**
- * Write the given RemoteInvocationResult to the given HTTP response.
- * @param request current HTTP request
- * @param response current HTTP response
- * @param result the RemoteInvocationResult object
- * @throws IOException in case of I/O failure
- */
- protected void writeRemoteInvocationResult(
- HttpServletRequest request, HttpServletResponse response, RemoteInvocationResult result)
- throws IOException {
-
- response.setContentType(getContentType());
- writeRemoteInvocationResult(request, response, result, response.getOutputStream());
- }
-
- /**
- * Serialize the given RemoteInvocation to the given OutputStream.
- *
The default implementation gives {@link #decorateOutputStream} a chance
- * to decorate the stream first (for example, for custom encryption or compression).
- * Creates an {@link java.io.ObjectOutputStream} for the final stream and calls
- * {@link #doWriteRemoteInvocationResult} to actually write the object.
- *
Can be overridden for custom serialization of the invocation.
- * @param request current HTTP request
- * @param response current HTTP response
- * @param result the RemoteInvocationResult object
- * @param os the OutputStream to write to
- * @throws IOException in case of I/O failure
- * @see #decorateOutputStream
- * @see #doWriteRemoteInvocationResult
- */
- protected void writeRemoteInvocationResult(
- HttpServletRequest request, HttpServletResponse response, RemoteInvocationResult result, OutputStream os)
- throws IOException {
-
- try (ObjectOutputStream oos =
- createObjectOutputStream(new FlushGuardedOutputStream(decorateOutputStream(request, response, os)))) {
- doWriteRemoteInvocationResult(result, oos);
- }
- }
-
- /**
- * Return the OutputStream to use for writing remote invocation results,
- * potentially decorating the given original OutputStream.
- *
The default implementation returns the given stream as-is.
- * Can be overridden, for example, for custom encryption or compression.
- * @param request current HTTP request
- * @param response current HTTP response
- * @param os the original OutputStream
- * @return the potentially decorated OutputStream
- * @throws IOException in case of I/O failure
- */
- protected OutputStream decorateOutputStream(
- HttpServletRequest request, HttpServletResponse response, OutputStream os) throws IOException {
-
- return os;
- }
-
-
- /**
- * Decorate an {@code OutputStream} to guard against {@code flush()} calls,
- * which are turned into no-ops.
- *
Because {@link ObjectOutputStream#close()} will in fact flush/drain
- * the underlying stream twice, this {@link FilterOutputStream} will
- * guard against individual flush calls. Multiple flush calls can lead
- * to performance issues, since writes aren't gathered as they should be.
- * @see SPR-14040
- */
- private static class FlushGuardedOutputStream extends FilterOutputStream {
-
- public FlushGuardedOutputStream(OutputStream out) {
- super(out);
- }
-
- @Override
- public void flush() throws IOException {
- // Do nothing on flush
- }
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerRequestExecutor.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerRequestExecutor.java
deleted file mode 100644
index b4c8f31c36..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerRequestExecutor.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.httpinvoker;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.Locale;
-import java.util.zip.GZIPInputStream;
-
-import org.springframework.context.i18n.LocaleContext;
-import org.springframework.context.i18n.LocaleContextHolder;
-import org.springframework.remoting.support.RemoteInvocationResult;
-
-/**
- * {@link org.springframework.remoting.httpinvoker.HttpInvokerRequestExecutor} implementation
- * that uses standard Java facilities to execute POST requests, without support for HTTP
- * authentication or advanced configuration options.
- *
- *
Designed for easy subclassing, customizing specific template methods. However,
- * consider {@code HttpComponentsHttpInvokerRequestExecutor} for more sophisticated needs:
- * The standard {@link HttpURLConnection} class is rather limited in its capabilities.
- *
- * @author Juergen Hoeller
- * @since 1.1
- * @see java.net.HttpURLConnection
- * @deprecated as of 5.3 (phasing out serialization-based remoting)
- */
-@Deprecated
-public class SimpleHttpInvokerRequestExecutor extends AbstractHttpInvokerRequestExecutor {
-
- private int connectTimeout = -1;
-
- private int readTimeout = -1;
-
-
- /**
- * Set the underlying URLConnection's connect timeout (in milliseconds).
- * A timeout value of 0 specifies an infinite timeout.
- *
Default is the system's default timeout.
- * @see URLConnection#setConnectTimeout(int)
- */
- public void setConnectTimeout(int connectTimeout) {
- this.connectTimeout = connectTimeout;
- }
-
- /**
- * Set the underlying URLConnection's read timeout (in milliseconds).
- * A timeout value of 0 specifies an infinite timeout.
- *
Default is the system's default timeout.
- * @see URLConnection#setReadTimeout(int)
- */
- public void setReadTimeout(int readTimeout) {
- this.readTimeout = readTimeout;
- }
-
-
- /**
- * Execute the given request through a standard {@link HttpURLConnection}.
- *
This method implements the basic processing workflow:
- * The actual work happens in this class's template methods.
- * @see #openConnection
- * @see #prepareConnection
- * @see #writeRequestBody
- * @see #validateResponse
- * @see #readResponseBody
- */
- @Override
- protected RemoteInvocationResult doExecuteRequest(
- HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)
- throws IOException, ClassNotFoundException {
-
- HttpURLConnection con = openConnection(config);
- prepareConnection(con, baos.size());
- writeRequestBody(config, con, baos);
- validateResponse(config, con);
- InputStream responseBody = readResponseBody(config, con);
-
- return readRemoteInvocationResult(responseBody, config.getCodebaseUrl());
- }
-
- /**
- * Open an {@link HttpURLConnection} for the given remote invocation request.
- * @param config the HTTP invoker configuration that specifies the
- * target service
- * @return the HttpURLConnection for the given request
- * @throws IOException if thrown by I/O methods
- * @see java.net.URL#openConnection()
- */
- protected HttpURLConnection openConnection(HttpInvokerClientConfiguration config) throws IOException {
- URLConnection con = new URL(config.getServiceUrl()).openConnection();
- if (!(con instanceof HttpURLConnection)) {
- throw new IOException(
- "Service URL [" + config.getServiceUrl() + "] does not resolve to an HTTP connection");
- }
- return (HttpURLConnection) con;
- }
-
- /**
- * Prepare the given HTTP connection.
- *
The default implementation specifies POST as method,
- * "application/x-java-serialized-object" as "Content-Type" header,
- * and the given content length as "Content-Length" header.
- * @param connection the HTTP connection to prepare
- * @param contentLength the length of the content to send
- * @throws IOException if thrown by HttpURLConnection methods
- * @see java.net.HttpURLConnection#setRequestMethod
- * @see java.net.HttpURLConnection#setRequestProperty
- */
- protected void prepareConnection(HttpURLConnection connection, int contentLength) throws IOException {
- if (this.connectTimeout >= 0) {
- connection.setConnectTimeout(this.connectTimeout);
- }
- if (this.readTimeout >= 0) {
- connection.setReadTimeout(this.readTimeout);
- }
-
- connection.setDoOutput(true);
- connection.setRequestMethod(HTTP_METHOD_POST);
- connection.setRequestProperty(HTTP_HEADER_CONTENT_TYPE, getContentType());
- connection.setRequestProperty(HTTP_HEADER_CONTENT_LENGTH, Integer.toString(contentLength));
-
- LocaleContext localeContext = LocaleContextHolder.getLocaleContext();
- if (localeContext != null) {
- Locale locale = localeContext.getLocale();
- if (locale != null) {
- connection.setRequestProperty(HTTP_HEADER_ACCEPT_LANGUAGE, locale.toLanguageTag());
- }
- }
-
- if (isAcceptGzipEncoding()) {
- connection.setRequestProperty(HTTP_HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
- }
- }
-
- /**
- * Set the given serialized remote invocation as request body.
- *
The default implementation simply write the serialized invocation to the
- * HttpURLConnection's OutputStream. This can be overridden, for example, to write
- * a specific encoding and potentially set appropriate HTTP request headers.
- * @param config the HTTP invoker configuration that specifies the target service
- * @param con the HttpURLConnection to write the request body to
- * @param baos the ByteArrayOutputStream that contains the serialized
- * RemoteInvocation object
- * @throws IOException if thrown by I/O methods
- * @see java.net.HttpURLConnection#getOutputStream()
- * @see java.net.HttpURLConnection#setRequestProperty
- */
- protected void writeRequestBody(
- HttpInvokerClientConfiguration config, HttpURLConnection con, ByteArrayOutputStream baos)
- throws IOException {
-
- baos.writeTo(con.getOutputStream());
- }
-
- /**
- * Validate the given response as contained in the {@link HttpURLConnection} object,
- * throwing an exception if it does not correspond to a successful HTTP response.
- *
Default implementation rejects any HTTP status code beyond 2xx, to avoid
- * parsing the response body and trying to deserialize from a corrupted stream.
- * @param config the HTTP invoker configuration that specifies the target service
- * @param con the HttpURLConnection to validate
- * @throws IOException if validation failed
- * @see java.net.HttpURLConnection#getResponseCode()
- */
- protected void validateResponse(HttpInvokerClientConfiguration config, HttpURLConnection con)
- throws IOException {
-
- if (con.getResponseCode() >= 300) {
- throw new IOException(
- "Did not receive successful HTTP response: status code = " + con.getResponseCode() +
- ", status message = [" + con.getResponseMessage() + "]");
- }
- }
-
- /**
- * Extract the response body from the given executed remote invocation
- * request.
- *
The default implementation simply reads the serialized invocation
- * from the HttpURLConnection's InputStream. If the response is recognized
- * as GZIP response, the InputStream will get wrapped in a GZIPInputStream.
- * @param config the HTTP invoker configuration that specifies the target service
- * @param con the HttpURLConnection to read the response body from
- * @return an InputStream for the response body
- * @throws IOException if thrown by I/O methods
- * @see #isGzipResponse
- * @see java.util.zip.GZIPInputStream
- * @see java.net.HttpURLConnection#getInputStream()
- * @see java.net.HttpURLConnection#getHeaderField(int)
- * @see java.net.HttpURLConnection#getHeaderFieldKey(int)
- */
- protected InputStream readResponseBody(HttpInvokerClientConfiguration config, HttpURLConnection con)
- throws IOException {
-
- if (isGzipResponse(con)) {
- // GZIP response found - need to unzip.
- return new GZIPInputStream(con.getInputStream());
- }
- else {
- // Plain response found.
- return con.getInputStream();
- }
- }
-
- /**
- * Determine whether the given response is a GZIP response.
- *
Default implementation checks whether the HTTP "Content-Encoding"
- * header contains "gzip" (in any casing).
- * @param con the HttpURLConnection to check
- */
- protected boolean isGzipResponse(HttpURLConnection con) {
- String encodingHeader = con.getHeaderField(HTTP_HEADER_CONTENT_ENCODING);
- return (encodingHeader != null && encodingHeader.toLowerCase().contains(ENCODING_GZIP));
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerServiceExporter.java
deleted file mode 100644
index 5c8e431fba..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/SimpleHttpInvokerServiceExporter.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.httpinvoker;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-
-import com.sun.net.httpserver.HttpExchange;
-import com.sun.net.httpserver.HttpHandler;
-
-import org.springframework.remoting.support.RemoteInvocation;
-import org.springframework.remoting.support.RemoteInvocationResult;
-
-/**
- * HTTP request handler that exports the specified service bean as
- * HTTP invoker service endpoint, accessible via an HTTP invoker proxy.
- * Designed for Sun's JRE 1.6 HTTP server, implementing the
- * {@link com.sun.net.httpserver.HttpHandler} interface.
- *
- *
Deserializes remote invocation objects and serializes remote invocation
- * result objects. Uses Java serialization just like RMI, but provides the
- * same ease of setup as Caucho's HTTP-based Hessian protocol.
- *
- *
HTTP invoker is the recommended protocol for Java-to-Java remoting.
- * It is more powerful and more extensible than Hessian, at the expense of
- * being tied to Java. Nevertheless, it is as easy to set up as Hessian,
- * which is its main advantage compared to RMI.
- *
- *
WARNING: Be aware of vulnerabilities due to unsafe Java deserialization:
- * Manipulated input streams could lead to unwanted code execution on the server
- * during the deserialization step. As a consequence, do not expose HTTP invoker
- * endpoints to untrusted clients but rather just between your own services.
- * In general, we strongly recommend any other message format (e.g. JSON) instead.
- *
- * @author Juergen Hoeller
- * @since 2.5.1
- * @see org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor
- * @see org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean
- * @deprecated as of Spring Framework 5.1, in favor of {@link HttpInvokerServiceExporter}
- */
-@Deprecated
-@org.springframework.lang.UsesSunHttpServer
-public class SimpleHttpInvokerServiceExporter extends org.springframework.remoting.rmi.RemoteInvocationSerializingExporter implements HttpHandler {
-
- /**
- * Reads a remote invocation from the request, executes it,
- * and writes the remote invocation result to the response.
- * @see #readRemoteInvocation(HttpExchange)
- * @see #invokeAndCreateResult(RemoteInvocation, Object)
- * @see #writeRemoteInvocationResult(HttpExchange, RemoteInvocationResult)
- */
- @Override
- public void handle(HttpExchange exchange) throws IOException {
- try {
- RemoteInvocation invocation = readRemoteInvocation(exchange);
- RemoteInvocationResult result = invokeAndCreateResult(invocation, getProxy());
- writeRemoteInvocationResult(exchange, result);
- exchange.close();
- }
- catch (ClassNotFoundException ex) {
- exchange.sendResponseHeaders(500, -1);
- logger.error("Class not found during deserialization", ex);
- }
- }
-
- /**
- * Read a RemoteInvocation from the given HTTP request.
- *
Delegates to {@link #readRemoteInvocation(HttpExchange, InputStream)}
- * with the {@link HttpExchange#getRequestBody()} request's input stream}.
- * @param exchange current HTTP request/response
- * @return the RemoteInvocation object
- * @throws java.io.IOException in case of I/O failure
- * @throws ClassNotFoundException if thrown by deserialization
- */
- protected RemoteInvocation readRemoteInvocation(HttpExchange exchange)
- throws IOException, ClassNotFoundException {
-
- return readRemoteInvocation(exchange, exchange.getRequestBody());
- }
-
- /**
- * Deserialize a RemoteInvocation object from the given InputStream.
- *
Gives {@link #decorateInputStream} a chance to decorate the stream
- * first (for example, for custom encryption or compression). Creates a
- * {@link org.springframework.remoting.rmi.CodebaseAwareObjectInputStream}
- * and calls {@link #doReadRemoteInvocation} to actually read the object.
- *
Can be overridden for custom serialization of the invocation.
- * @param exchange current HTTP request/response
- * @param is the InputStream to read from
- * @return the RemoteInvocation object
- * @throws java.io.IOException in case of I/O failure
- * @throws ClassNotFoundException if thrown during deserialization
- */
- protected RemoteInvocation readRemoteInvocation(HttpExchange exchange, InputStream is)
- throws IOException, ClassNotFoundException {
-
- ObjectInputStream ois = createObjectInputStream(decorateInputStream(exchange, is));
- return doReadRemoteInvocation(ois);
- }
-
- /**
- * Return the InputStream to use for reading remote invocations,
- * potentially decorating the given original InputStream.
- *
The default implementation returns the given stream as-is.
- * Can be overridden, for example, for custom encryption or compression.
- * @param exchange current HTTP request/response
- * @param is the original InputStream
- * @return the potentially decorated InputStream
- * @throws java.io.IOException in case of I/O failure
- */
- protected InputStream decorateInputStream(HttpExchange exchange, InputStream is) throws IOException {
- return is;
- }
-
- /**
- * Write the given RemoteInvocationResult to the given HTTP response.
- * @param exchange current HTTP request/response
- * @param result the RemoteInvocationResult object
- * @throws java.io.IOException in case of I/O failure
- */
- protected void writeRemoteInvocationResult(HttpExchange exchange, RemoteInvocationResult result)
- throws IOException {
-
- exchange.getResponseHeaders().set("Content-Type", getContentType());
- exchange.sendResponseHeaders(200, 0);
- writeRemoteInvocationResult(exchange, result, exchange.getResponseBody());
- }
-
- /**
- * Serialize the given RemoteInvocation to the given OutputStream.
- *
The default implementation gives {@link #decorateOutputStream} a chance
- * to decorate the stream first (for example, for custom encryption or compression).
- * Creates an {@link java.io.ObjectOutputStream} for the final stream and calls
- * {@link #doWriteRemoteInvocationResult} to actually write the object.
- *
Can be overridden for custom serialization of the invocation.
- * @param exchange current HTTP request/response
- * @param result the RemoteInvocationResult object
- * @param os the OutputStream to write to
- * @throws java.io.IOException in case of I/O failure
- * @see #decorateOutputStream
- * @see #doWriteRemoteInvocationResult
- */
- protected void writeRemoteInvocationResult(
- HttpExchange exchange, RemoteInvocationResult result, OutputStream os) throws IOException {
-
- ObjectOutputStream oos = createObjectOutputStream(decorateOutputStream(exchange, os));
- doWriteRemoteInvocationResult(result, oos);
- oos.flush();
- }
-
- /**
- * Return the OutputStream to use for writing remote invocation results,
- * potentially decorating the given original OutputStream.
- *
The default implementation returns the given stream as-is.
- * Can be overridden, for example, for custom encryption or compression.
- * @param exchange current HTTP request/response
- * @param os the original OutputStream
- * @return the potentially decorated OutputStream
- * @throws java.io.IOException in case of I/O failure
- */
- protected OutputStream decorateOutputStream(HttpExchange exchange, OutputStream os) throws IOException {
- return os;
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/package-info.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/package-info.java
deleted file mode 100644
index e0dfd03aa6..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/package-info.java
+++ /dev/null
@@ -1,16 +0,0 @@
-/**
- * Remoting classes for transparent Java-to-Java remoting via HTTP invokers.
- * Uses Java serialization just like RMI, but provides the same ease of setup
- * as Caucho's HTTP-based Hessian protocol.
- *
- *
HTTP invoker is the recommended protocol for Java-to-Java remoting.
- * It is more powerful and more extensible than Hessian, at the expense of
- * being tied to Java. Nevertheless, it is as easy to set up as Hessian,
- * which is its main advantage compared to RMI.
- */
-@NonNullApi
-@NonNullFields
-package org.springframework.remoting.httpinvoker;
-
-import org.springframework.lang.NonNullApi;
-import org.springframework.lang.NonNullFields;
diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/AbstractJaxWsServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/AbstractJaxWsServiceExporter.java
deleted file mode 100644
index 610651bef2..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/jaxws/AbstractJaxWsServiceExporter.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.jaxws;
-
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Executor;
-
-import javax.jws.WebService;
-import javax.xml.ws.Endpoint;
-import javax.xml.ws.WebServiceFeature;
-import javax.xml.ws.WebServiceProvider;
-
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.beans.factory.CannotLoadBeanClassException;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.ListableBeanFactory;
-import org.springframework.beans.factory.config.ConfigurableBeanFactory;
-import org.springframework.lang.Nullable;
-import org.springframework.util.Assert;
-
-/**
- * Abstract exporter for JAX-WS services, autodetecting annotated service beans
- * (through the JAX-WS {@link javax.jws.WebService} annotation).
- *
- *
Subclasses need to implement the {@link #publishEndpoint} template methods
- * for actual endpoint exposure.
- *
- * @author Juergen Hoeller
- * @since 2.5.5
- * @see javax.jws.WebService
- * @see javax.xml.ws.Endpoint
- * @see SimpleJaxWsServiceExporter
- */
-public abstract class AbstractJaxWsServiceExporter implements BeanFactoryAware, InitializingBean, DisposableBean {
-
- @Nullable
- private Map endpointProperties;
-
- @Nullable
- private Executor executor;
-
- @Nullable
- private String bindingType;
-
- @Nullable
- private WebServiceFeature[] endpointFeatures;
-
- @Nullable
- private ListableBeanFactory beanFactory;
-
- private final Set publishedEndpoints = new LinkedHashSet<>();
-
-
- /**
- * Set the property bag for the endpoint, including properties such as
- * "javax.xml.ws.wsdl.service" or "javax.xml.ws.wsdl.port".
- * @see javax.xml.ws.Endpoint#setProperties
- * @see javax.xml.ws.Endpoint#WSDL_SERVICE
- * @see javax.xml.ws.Endpoint#WSDL_PORT
- */
- public void setEndpointProperties(Map endpointProperties) {
- this.endpointProperties = endpointProperties;
- }
-
- /**
- * Set the JDK concurrent executor to use for dispatching incoming requests
- * to exported service instances.
- * @see javax.xml.ws.Endpoint#setExecutor
- */
- public void setExecutor(Executor executor) {
- this.executor = executor;
- }
-
- /**
- * Specify the binding type to use, overriding the value of
- * the JAX-WS {@link javax.xml.ws.BindingType} annotation.
- */
- public void setBindingType(String bindingType) {
- this.bindingType = bindingType;
- }
-
- /**
- * Specify WebServiceFeature objects (e.g. as inner bean definitions)
- * to apply to JAX-WS endpoint creation.
- * @since 4.0
- */
- public void setEndpointFeatures(WebServiceFeature... endpointFeatures) {
- this.endpointFeatures = endpointFeatures;
- }
-
- /**
- * Obtains all web service beans and publishes them as JAX-WS endpoints.
- */
- @Override
- public void setBeanFactory(BeanFactory beanFactory) {
- if (!(beanFactory instanceof ListableBeanFactory)) {
- throw new IllegalStateException(getClass().getSimpleName() + " requires a ListableBeanFactory");
- }
- this.beanFactory = (ListableBeanFactory) beanFactory;
- }
-
-
- /**
- * Immediately publish all endpoints when fully configured.
- * @see #publishEndpoints()
- */
- @Override
- public void afterPropertiesSet() throws Exception {
- publishEndpoints();
- }
-
- /**
- * Publish all {@link javax.jws.WebService} annotated beans in the
- * containing BeanFactory.
- * @see #publishEndpoint
- */
- public void publishEndpoints() {
- Assert.state(this.beanFactory != null, "No BeanFactory set");
-
- Set beanNames = new LinkedHashSet<>(this.beanFactory.getBeanDefinitionCount());
- Collections.addAll(beanNames, this.beanFactory.getBeanDefinitionNames());
- if (this.beanFactory instanceof ConfigurableBeanFactory) {
- Collections.addAll(beanNames, ((ConfigurableBeanFactory) this.beanFactory).getSingletonNames());
- }
-
- for (String beanName : beanNames) {
- try {
- Class> type = this.beanFactory.getType(beanName);
- if (type != null && !type.isInterface()) {
- WebService wsAnnotation = type.getAnnotation(WebService.class);
- WebServiceProvider wsProviderAnnotation = type.getAnnotation(WebServiceProvider.class);
- if (wsAnnotation != null || wsProviderAnnotation != null) {
- Endpoint endpoint = createEndpoint(this.beanFactory.getBean(beanName));
- if (this.endpointProperties != null) {
- endpoint.setProperties(this.endpointProperties);
- }
- if (this.executor != null) {
- endpoint.setExecutor(this.executor);
- }
- if (wsAnnotation != null) {
- publishEndpoint(endpoint, wsAnnotation);
- }
- else {
- publishEndpoint(endpoint, wsProviderAnnotation);
- }
- this.publishedEndpoints.add(endpoint);
- }
- }
- }
- catch (CannotLoadBeanClassException ex) {
- // ignore beans where the class is not resolvable
- }
- }
- }
-
- /**
- * Create the actual Endpoint instance.
- * @param bean the service object to wrap
- * @return the Endpoint instance
- * @see Endpoint#create(Object)
- * @see Endpoint#create(String, Object)
- */
- protected Endpoint createEndpoint(Object bean) {
- return (this.endpointFeatures != null ?
- Endpoint.create(this.bindingType, bean, this.endpointFeatures) :
- Endpoint.create(this.bindingType, bean));
- }
-
-
- /**
- * Actually publish the given endpoint. To be implemented by subclasses.
- * @param endpoint the JAX-WS Endpoint object
- * @param annotation the service bean's WebService annotation
- */
- protected abstract void publishEndpoint(Endpoint endpoint, WebService annotation);
-
- /**
- * Actually publish the given provider endpoint. To be implemented by subclasses.
- * @param endpoint the JAX-WS Provider Endpoint object
- * @param annotation the service bean's WebServiceProvider annotation
- */
- protected abstract void publishEndpoint(Endpoint endpoint, WebServiceProvider annotation);
-
-
- /**
- * Stops all published endpoints, taking the web services offline.
- */
- @Override
- public void destroy() {
- for (Endpoint endpoint : this.publishedEndpoints) {
- endpoint.stop();
- }
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortClientInterceptor.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortClientInterceptor.java
deleted file mode 100644
index e8ff14889a..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortClientInterceptor.java
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * Copyright 2002-2017 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.jaxws;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jws.WebService;
-import javax.xml.namespace.QName;
-import javax.xml.ws.BindingProvider;
-import javax.xml.ws.ProtocolException;
-import javax.xml.ws.Service;
-import javax.xml.ws.WebServiceException;
-import javax.xml.ws.WebServiceFeature;
-import javax.xml.ws.soap.SOAPFaultException;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-
-import org.springframework.aop.support.AopUtils;
-import org.springframework.beans.factory.BeanClassLoaderAware;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.lang.Nullable;
-import org.springframework.remoting.RemoteAccessException;
-import org.springframework.remoting.RemoteConnectFailureException;
-import org.springframework.remoting.RemoteLookupFailureException;
-import org.springframework.remoting.RemoteProxyFailureException;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.StringUtils;
-
-/**
- * {@link org.aopalliance.intercept.MethodInterceptor} for accessing a
- * specific port of a JAX-WS service.
- *
- * Uses either {@link LocalJaxWsServiceFactory}'s facilities underneath,
- * or takes an explicit reference to an existing JAX-WS Service instance
- * (e.g. obtained via {@link org.springframework.jndi.JndiObjectFactoryBean}).
- *
- * @author Juergen Hoeller
- * @since 2.5
- * @see #setPortName
- * @see #setServiceInterface
- * @see javax.xml.ws.Service#getPort
- * @see org.springframework.remoting.RemoteAccessException
- * @see org.springframework.jndi.JndiObjectFactoryBean
- */
-public class JaxWsPortClientInterceptor extends LocalJaxWsServiceFactory
- implements MethodInterceptor, BeanClassLoaderAware, InitializingBean {
-
- @Nullable
- private Service jaxWsService;
-
- @Nullable
- private String portName;
-
- @Nullable
- private String username;
-
- @Nullable
- private String password;
-
- @Nullable
- private String endpointAddress;
-
- private boolean maintainSession;
-
- private boolean useSoapAction;
-
- @Nullable
- private String soapActionUri;
-
- @Nullable
- private Map customProperties;
-
- @Nullable
- private WebServiceFeature[] portFeatures;
-
- @Nullable
- private Class> serviceInterface;
-
- private boolean lookupServiceOnStartup = true;
-
- @Nullable
- private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
-
- @Nullable
- private QName portQName;
-
- @Nullable
- private Object portStub;
-
- private final Object preparationMonitor = new Object();
-
-
- /**
- * Set a reference to an existing JAX-WS Service instance,
- * for example obtained via {@link org.springframework.jndi.JndiObjectFactoryBean}.
- * If not set, {@link LocalJaxWsServiceFactory}'s properties have to be specified.
- * @see #setWsdlDocumentUrl
- * @see #setNamespaceUri
- * @see #setServiceName
- * @see org.springframework.jndi.JndiObjectFactoryBean
- */
- public void setJaxWsService(@Nullable Service jaxWsService) {
- this.jaxWsService = jaxWsService;
- }
-
- /**
- * Return a reference to an existing JAX-WS Service instance, if any.
- */
- @Nullable
- public Service getJaxWsService() {
- return this.jaxWsService;
- }
-
- /**
- * Set the name of the port.
- * Corresponds to the "wsdl:port" name.
- */
- public void setPortName(@Nullable String portName) {
- this.portName = portName;
- }
-
- /**
- * Return the name of the port.
- */
- @Nullable
- public String getPortName() {
- return this.portName;
- }
-
- /**
- * Set the username to specify on the stub.
- * @see javax.xml.ws.BindingProvider#USERNAME_PROPERTY
- */
- public void setUsername(@Nullable String username) {
- this.username = username;
- }
-
- /**
- * Return the username to specify on the stub.
- */
- @Nullable
- public String getUsername() {
- return this.username;
- }
-
- /**
- * Set the password to specify on the stub.
- * @see javax.xml.ws.BindingProvider#PASSWORD_PROPERTY
- */
- public void setPassword(@Nullable String password) {
- this.password = password;
- }
-
- /**
- * Return the password to specify on the stub.
- */
- @Nullable
- public String getPassword() {
- return this.password;
- }
-
- /**
- * Set the endpoint address to specify on the stub.
- * @see javax.xml.ws.BindingProvider#ENDPOINT_ADDRESS_PROPERTY
- */
- public void setEndpointAddress(@Nullable String endpointAddress) {
- this.endpointAddress = endpointAddress;
- }
-
- /**
- * Return the endpoint address to specify on the stub.
- */
- @Nullable
- public String getEndpointAddress() {
- return this.endpointAddress;
- }
-
- /**
- * Set the "session.maintain" flag to specify on the stub.
- * @see javax.xml.ws.BindingProvider#SESSION_MAINTAIN_PROPERTY
- */
- public void setMaintainSession(boolean maintainSession) {
- this.maintainSession = maintainSession;
- }
-
- /**
- * Return the "session.maintain" flag to specify on the stub.
- */
- public boolean isMaintainSession() {
- return this.maintainSession;
- }
-
- /**
- * Set the "soapaction.use" flag to specify on the stub.
- * @see javax.xml.ws.BindingProvider#SOAPACTION_USE_PROPERTY
- */
- public void setUseSoapAction(boolean useSoapAction) {
- this.useSoapAction = useSoapAction;
- }
-
- /**
- * Return the "soapaction.use" flag to specify on the stub.
- */
- public boolean isUseSoapAction() {
- return this.useSoapAction;
- }
-
- /**
- * Set the SOAP action URI to specify on the stub.
- * @see javax.xml.ws.BindingProvider#SOAPACTION_URI_PROPERTY
- */
- public void setSoapActionUri(@Nullable String soapActionUri) {
- this.soapActionUri = soapActionUri;
- }
-
- /**
- * Return the SOAP action URI to specify on the stub.
- */
- @Nullable
- public String getSoapActionUri() {
- return this.soapActionUri;
- }
-
- /**
- * Set custom properties to be set on the stub.
- * Can be populated with a String "value" (parsed via PropertiesEditor)
- * or a "props" element in XML bean definitions.
- * @see javax.xml.ws.BindingProvider#getRequestContext()
- */
- public void setCustomProperties(Map customProperties) {
- this.customProperties = customProperties;
- }
-
- /**
- * Allow Map access to the custom properties to be set on the stub,
- * with the option to add or override specific entries.
- * Useful for specifying entries directly, for example via
- * "customProperties[myKey]". This is particularly useful for
- * adding or overriding entries in child bean definitions.
- */
- public Map getCustomProperties() {
- if (this.customProperties == null) {
- this.customProperties = new HashMap<>();
- }
- return this.customProperties;
- }
-
- /**
- * Add a custom property to this JAX-WS BindingProvider.
- * @param name the name of the attribute to expose
- * @param value the attribute value to expose
- * @see javax.xml.ws.BindingProvider#getRequestContext()
- */
- public void addCustomProperty(String name, Object value) {
- getCustomProperties().put(name, value);
- }
-
- /**
- * Specify WebServiceFeature objects (e.g. as inner bean definitions)
- * to apply to JAX-WS port stub creation.
- * @since 4.0
- * @see Service#getPort(Class, javax.xml.ws.WebServiceFeature...)
- * @see #setServiceFeatures
- */
- public void setPortFeatures(WebServiceFeature... features) {
- this.portFeatures = features;
- }
-
- /**
- * Set the interface of the service that this factory should create a proxy for.
- */
- public void setServiceInterface(@Nullable Class> serviceInterface) {
- if (serviceInterface != null) {
- Assert.isTrue(serviceInterface.isInterface(), "'serviceInterface' must be an interface");
- }
- this.serviceInterface = serviceInterface;
- }
-
- /**
- * Return the interface of the service that this factory should create a proxy for.
- */
- @Nullable
- public Class> getServiceInterface() {
- return this.serviceInterface;
- }
-
- /**
- * Set whether to look up the JAX-WS service on startup.
- * Default is "true". Turn this flag off to allow for late start
- * of the target server. In this case, the JAX-WS service will be
- * lazily fetched on first access.
- */
- public void setLookupServiceOnStartup(boolean lookupServiceOnStartup) {
- this.lookupServiceOnStartup = lookupServiceOnStartup;
- }
-
- /**
- * Set the bean ClassLoader to use for this interceptor: primarily for
- * building a client proxy in the {@link JaxWsPortProxyFactoryBean} subclass.
- */
- @Override
- public void setBeanClassLoader(@Nullable ClassLoader classLoader) {
- this.beanClassLoader = classLoader;
- }
-
- /**
- * Return the bean ClassLoader to use for this interceptor.
- */
- @Nullable
- protected ClassLoader getBeanClassLoader() {
- return this.beanClassLoader;
- }
-
-
- @Override
- public void afterPropertiesSet() {
- if (this.lookupServiceOnStartup) {
- prepare();
- }
- }
-
- /**
- * Initialize the JAX-WS port for this interceptor.
- */
- public void prepare() {
- Class> ifc = getServiceInterface();
- Assert.notNull(ifc, "Property 'serviceInterface' is required");
-
- WebService ann = ifc.getAnnotation(WebService.class);
- if (ann != null) {
- applyDefaultsFromAnnotation(ann);
- }
-
- Service serviceToUse = getJaxWsService();
- if (serviceToUse == null) {
- serviceToUse = createJaxWsService();
- }
-
- this.portQName = getQName(getPortName() != null ? getPortName() : ifc.getName());
- Object stub = getPortStub(serviceToUse, (getPortName() != null ? this.portQName : null));
- preparePortStub(stub);
- this.portStub = stub;
- }
-
- /**
- * Initialize this client interceptor's properties from the given WebService annotation,
- * if necessary and possible (i.e. if "wsdlDocumentUrl", "namespaceUri", "serviceName"
- * and "portName" haven't been set but corresponding values are declared at the
- * annotation level of the specified service interface).
- * @param ann the WebService annotation found on the specified service interface
- */
- protected void applyDefaultsFromAnnotation(WebService ann) {
- if (getWsdlDocumentUrl() == null) {
- String wsdl = ann.wsdlLocation();
- if (StringUtils.hasText(wsdl)) {
- try {
- setWsdlDocumentUrl(new URL(wsdl));
- }
- catch (MalformedURLException ex) {
- throw new IllegalStateException(
- "Encountered invalid @Service wsdlLocation value [" + wsdl + "]", ex);
- }
- }
- }
- if (getNamespaceUri() == null) {
- String ns = ann.targetNamespace();
- if (StringUtils.hasText(ns)) {
- setNamespaceUri(ns);
- }
- }
- if (getServiceName() == null) {
- String sn = ann.serviceName();
- if (StringUtils.hasText(sn)) {
- setServiceName(sn);
- }
- }
- if (getPortName() == null) {
- String pn = ann.portName();
- if (StringUtils.hasText(pn)) {
- setPortName(pn);
- }
- }
- }
-
- /**
- * Return whether this client interceptor has already been prepared,
- * i.e. has already looked up the JAX-WS service and port.
- */
- protected boolean isPrepared() {
- synchronized (this.preparationMonitor) {
- return (this.portStub != null);
- }
- }
-
- /**
- * Return the prepared QName for the port.
- * @see #setPortName
- * @see #getQName
- */
- @Nullable
- protected final QName getPortQName() {
- return this.portQName;
- }
-
- /**
- * Obtain the port stub from the given JAX-WS Service.
- * @param service the Service object to obtain the port from
- * @param portQName the name of the desired port, if specified
- * @return the corresponding port object as returned from
- * {@code Service.getPort(...)}
- */
- protected Object getPortStub(Service service, @Nullable QName portQName) {
- if (this.portFeatures != null) {
- return (portQName != null ? service.getPort(portQName, getServiceInterface(), this.portFeatures) :
- service.getPort(getServiceInterface(), this.portFeatures));
- }
- else {
- return (portQName != null ? service.getPort(portQName, getServiceInterface()) :
- service.getPort(getServiceInterface()));
- }
- }
-
- /**
- * Prepare the given JAX-WS port stub, applying properties to it.
- * Called by {@link #prepare}.
- * @param stub the current JAX-WS port stub
- * @see #setUsername
- * @see #setPassword
- * @see #setEndpointAddress
- * @see #setMaintainSession
- * @see #setCustomProperties
- */
- protected void preparePortStub(Object stub) {
- Map stubProperties = new HashMap<>();
- String username = getUsername();
- if (username != null) {
- stubProperties.put(BindingProvider.USERNAME_PROPERTY, username);
- }
- String password = getPassword();
- if (password != null) {
- stubProperties.put(BindingProvider.PASSWORD_PROPERTY, password);
- }
- String endpointAddress = getEndpointAddress();
- if (endpointAddress != null) {
- stubProperties.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointAddress);
- }
- if (isMaintainSession()) {
- stubProperties.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE);
- }
- if (isUseSoapAction()) {
- stubProperties.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
- }
- String soapActionUri = getSoapActionUri();
- if (soapActionUri != null) {
- stubProperties.put(BindingProvider.SOAPACTION_URI_PROPERTY, soapActionUri);
- }
- stubProperties.putAll(getCustomProperties());
- if (!stubProperties.isEmpty()) {
- if (!(stub instanceof BindingProvider)) {
- throw new RemoteLookupFailureException("Port stub of class [" + stub.getClass().getName() +
- "] is not a customizable JAX-WS stub: it does not implement interface [javax.xml.ws.BindingProvider]");
- }
- ((BindingProvider) stub).getRequestContext().putAll(stubProperties);
- }
- }
-
- /**
- * Return the underlying JAX-WS port stub that this interceptor delegates to
- * for each method invocation on the proxy.
- */
- @Nullable
- protected Object getPortStub() {
- return this.portStub;
- }
-
-
- @Override
- @Nullable
- public Object invoke(MethodInvocation invocation) throws Throwable {
- if (AopUtils.isToStringMethod(invocation.getMethod())) {
- return "JAX-WS proxy for port [" + getPortName() + "] of service [" + getServiceName() + "]";
- }
- // Lazily prepare service and stub if necessary.
- synchronized (this.preparationMonitor) {
- if (!isPrepared()) {
- prepare();
- }
- }
- return doInvoke(invocation);
- }
-
- /**
- * Perform a JAX-WS service invocation based on the given method invocation.
- * @param invocation the AOP method invocation
- * @return the invocation result, if any
- * @throws Throwable in case of invocation failure
- * @see #getPortStub()
- * @see #doInvoke(org.aopalliance.intercept.MethodInvocation, Object)
- */
- @Nullable
- protected Object doInvoke(MethodInvocation invocation) throws Throwable {
- try {
- return doInvoke(invocation, getPortStub());
- }
- catch (SOAPFaultException ex) {
- throw new JaxWsSoapFaultException(ex);
- }
- catch (ProtocolException ex) {
- throw new RemoteConnectFailureException(
- "Could not connect to remote service [" + getEndpointAddress() + "]", ex);
- }
- catch (WebServiceException ex) {
- throw new RemoteAccessException(
- "Could not access remote service at [" + getEndpointAddress() + "]", ex);
- }
- }
-
- /**
- * Perform a JAX-WS service invocation on the given port stub.
- * @param invocation the AOP method invocation
- * @param portStub the RMI port stub to invoke
- * @return the invocation result, if any
- * @throws Throwable in case of invocation failure
- * @see #getPortStub()
- */
- @Nullable
- protected Object doInvoke(MethodInvocation invocation, @Nullable Object portStub) throws Throwable {
- Method method = invocation.getMethod();
- try {
- return method.invoke(portStub, invocation.getArguments());
- }
- catch (InvocationTargetException ex) {
- throw ex.getTargetException();
- }
- catch (Throwable ex) {
- throw new RemoteProxyFailureException("Invocation of stub method failed: " + method, ex);
- }
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortProxyFactoryBean.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortProxyFactoryBean.java
deleted file mode 100644
index 3788d0e0e7..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortProxyFactoryBean.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2002-2017 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.jaxws;
-
-import javax.xml.ws.BindingProvider;
-
-import org.springframework.aop.framework.ProxyFactory;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.lang.Nullable;
-import org.springframework.util.Assert;
-
-/**
- * {@link org.springframework.beans.factory.FactoryBean} for a specific port of a
- * JAX-WS service. Exposes a proxy for the port, to be used for bean references.
- * Inherits configuration properties from {@link JaxWsPortClientInterceptor}.
- *
- * @author Juergen Hoeller
- * @since 2.5
- * @see #setServiceInterface
- * @see LocalJaxWsServiceFactoryBean
- */
-public class JaxWsPortProxyFactoryBean extends JaxWsPortClientInterceptor implements FactoryBean {
-
- @Nullable
- private Object serviceProxy;
-
-
- @Override
- public void afterPropertiesSet() {
- super.afterPropertiesSet();
-
- Class> ifc = getServiceInterface();
- Assert.notNull(ifc, "Property 'serviceInterface' is required");
-
- // Build a proxy that also exposes the JAX-WS BindingProvider interface.
- ProxyFactory pf = new ProxyFactory();
- pf.addInterface(ifc);
- pf.addInterface(BindingProvider.class);
- pf.addAdvice(this);
- this.serviceProxy = pf.getProxy(getBeanClassLoader());
- }
-
-
- @Override
- @Nullable
- public Object getObject() {
- return this.serviceProxy;
- }
-
- @Override
- public Class> getObjectType() {
- return getServiceInterface();
- }
-
- @Override
- public boolean isSingleton() {
- return true;
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsSoapFaultException.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsSoapFaultException.java
deleted file mode 100644
index 0205f56e68..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsSoapFaultException.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.jaxws;
-
-import javax.xml.namespace.QName;
-import javax.xml.soap.SOAPFault;
-import javax.xml.ws.soap.SOAPFaultException;
-
-import org.springframework.remoting.soap.SoapFaultException;
-
-/**
- * Spring SoapFaultException adapter for the JAX-WS
- * {@link javax.xml.ws.soap.SOAPFaultException} class.
- *
- * @author Juergen Hoeller
- * @since 2.5
- */
-@SuppressWarnings("serial")
-public class JaxWsSoapFaultException extends SoapFaultException {
-
- /**
- * Constructor for JaxWsSoapFaultException.
- * @param original the original JAX-WS SOAPFaultException to wrap
- */
- public JaxWsSoapFaultException(SOAPFaultException original) {
- super(original.getMessage(), original);
- }
-
- /**
- * Return the wrapped JAX-WS SOAPFault.
- */
- public final SOAPFault getFault() {
- return ((SOAPFaultException) getCause()).getFault();
- }
-
-
- @Override
- public String getFaultCode() {
- return getFault().getFaultCode();
- }
-
- @Override
- public QName getFaultCodeAsQName() {
- return getFault().getFaultCodeAsQName();
- }
-
- @Override
- public String getFaultString() {
- return getFault().getFaultString();
- }
-
- @Override
- public String getFaultActor() {
- return getFault().getFaultActor();
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/LocalJaxWsServiceFactory.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/LocalJaxWsServiceFactory.java
deleted file mode 100644
index 8abc4f1b02..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/jaxws/LocalJaxWsServiceFactory.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.jaxws;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.concurrent.Executor;
-
-import javax.xml.namespace.QName;
-import javax.xml.ws.Service;
-import javax.xml.ws.WebServiceFeature;
-import javax.xml.ws.handler.HandlerResolver;
-
-import org.springframework.core.io.Resource;
-import org.springframework.lang.Nullable;
-import org.springframework.util.Assert;
-
-/**
- * Factory for locally defined JAX-WS {@link javax.xml.ws.Service} references.
- * Uses the JAX-WS {@link javax.xml.ws.Service#create} factory API underneath.
- *
- * Serves as base class for {@link LocalJaxWsServiceFactoryBean} as well as
- * {@link JaxWsPortClientInterceptor} and {@link JaxWsPortProxyFactoryBean}.
- *
- * @author Juergen Hoeller
- * @since 2.5
- * @see javax.xml.ws.Service
- * @see LocalJaxWsServiceFactoryBean
- * @see JaxWsPortClientInterceptor
- * @see JaxWsPortProxyFactoryBean
- */
-public class LocalJaxWsServiceFactory {
-
- @Nullable
- private URL wsdlDocumentUrl;
-
- @Nullable
- private String namespaceUri;
-
- @Nullable
- private String serviceName;
-
- @Nullable
- private WebServiceFeature[] serviceFeatures;
-
- @Nullable
- private Executor executor;
-
- @Nullable
- private HandlerResolver handlerResolver;
-
-
- /**
- * Set the URL of the WSDL document that describes the service.
- * @see #setWsdlDocumentResource(Resource)
- */
- public void setWsdlDocumentUrl(@Nullable URL wsdlDocumentUrl) {
- this.wsdlDocumentUrl = wsdlDocumentUrl;
- }
-
- /**
- * Set the WSDL document URL as a {@link Resource}.
- * @since 3.2
- */
- public void setWsdlDocumentResource(Resource wsdlDocumentResource) throws IOException {
- Assert.notNull(wsdlDocumentResource, "WSDL Resource must not be null");
- this.wsdlDocumentUrl = wsdlDocumentResource.getURL();
- }
-
- /**
- * Return the URL of the WSDL document that describes the service.
- */
- @Nullable
- public URL getWsdlDocumentUrl() {
- return this.wsdlDocumentUrl;
- }
-
- /**
- * Set the namespace URI of the service.
- * Corresponds to the WSDL "targetNamespace".
- */
- public void setNamespaceUri(@Nullable String namespaceUri) {
- this.namespaceUri = (namespaceUri != null ? namespaceUri.trim() : null);
- }
-
- /**
- * Return the namespace URI of the service.
- */
- @Nullable
- public String getNamespaceUri() {
- return this.namespaceUri;
- }
-
- /**
- * Set the name of the service to look up.
- * Corresponds to the "wsdl:service" name.
- */
- public void setServiceName(@Nullable String serviceName) {
- this.serviceName = serviceName;
- }
-
- /**
- * Return the name of the service.
- */
- @Nullable
- public String getServiceName() {
- return this.serviceName;
- }
-
- /**
- * Specify WebServiceFeature objects (e.g. as inner bean definitions)
- * to apply to JAX-WS service creation.
- * @since 4.0
- * @see Service#create(QName, WebServiceFeature...)
- */
- public void setServiceFeatures(WebServiceFeature... serviceFeatures) {
- this.serviceFeatures = serviceFeatures;
- }
-
- /**
- * Set the JDK concurrent executor to use for asynchronous executions
- * that require callbacks.
- * @see javax.xml.ws.Service#setExecutor
- */
- public void setExecutor(Executor executor) {
- this.executor = executor;
- }
-
- /**
- * Set the JAX-WS HandlerResolver to use for all proxies and dispatchers
- * created through this factory.
- * @see javax.xml.ws.Service#setHandlerResolver
- */
- public void setHandlerResolver(HandlerResolver handlerResolver) {
- this.handlerResolver = handlerResolver;
- }
-
-
- /**
- * Create a JAX-WS Service according to the parameters of this factory.
- * @see #setServiceName
- * @see #setWsdlDocumentUrl
- */
- public Service createJaxWsService() {
- Assert.notNull(this.serviceName, "No service name specified");
- Service service;
-
- if (this.serviceFeatures != null) {
- service = (this.wsdlDocumentUrl != null ?
- Service.create(this.wsdlDocumentUrl, getQName(this.serviceName), this.serviceFeatures) :
- Service.create(getQName(this.serviceName), this.serviceFeatures));
- }
- else {
- service = (this.wsdlDocumentUrl != null ?
- Service.create(this.wsdlDocumentUrl, getQName(this.serviceName)) :
- Service.create(getQName(this.serviceName)));
- }
-
- if (this.executor != null) {
- service.setExecutor(this.executor);
- }
- if (this.handlerResolver != null) {
- service.setHandlerResolver(this.handlerResolver);
- }
-
- return service;
- }
-
- /**
- * Return a QName for the given name, relative to the namespace URI
- * of this factory, if given.
- * @see #setNamespaceUri
- */
- protected QName getQName(String name) {
- return (getNamespaceUri() != null ? new QName(getNamespaceUri(), name) : new QName(name));
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/LocalJaxWsServiceFactoryBean.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/LocalJaxWsServiceFactoryBean.java
deleted file mode 100644
index d512f7de6f..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/jaxws/LocalJaxWsServiceFactoryBean.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 2002-2017 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.jaxws;
-
-import javax.xml.ws.Service;
-
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.lang.Nullable;
-
-/**
- * {@link org.springframework.beans.factory.FactoryBean} for locally
- * defined JAX-WS Service references.
- * Uses {@link LocalJaxWsServiceFactory}'s facilities underneath.
- *
- *
Alternatively, JAX-WS Service references can be looked up
- * in the JNDI environment of the Java EE container.
- *
- * @author Juergen Hoeller
- * @since 2.5
- * @see javax.xml.ws.Service
- * @see org.springframework.jndi.JndiObjectFactoryBean
- * @see JaxWsPortProxyFactoryBean
- */
-public class LocalJaxWsServiceFactoryBean extends LocalJaxWsServiceFactory
- implements FactoryBean, InitializingBean {
-
- @Nullable
- private Service service;
-
-
- @Override
- public void afterPropertiesSet() {
- this.service = createJaxWsService();
- }
-
- @Override
- @Nullable
- public Service getObject() {
- return this.service;
- }
-
- @Override
- public Class extends Service> getObjectType() {
- return (this.service != null ? this.service.getClass() : Service.class);
- }
-
- @Override
- public boolean isSingleton() {
- return true;
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleHttpServerJaxWsServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleHttpServerJaxWsServiceExporter.java
deleted file mode 100644
index 54382b30d6..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleHttpServerJaxWsServiceExporter.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.jaxws;
-
-import java.net.InetSocketAddress;
-import java.util.List;
-
-import javax.jws.WebService;
-import javax.xml.ws.Endpoint;
-import javax.xml.ws.WebServiceProvider;
-
-import com.sun.net.httpserver.Authenticator;
-import com.sun.net.httpserver.Filter;
-import com.sun.net.httpserver.HttpContext;
-import com.sun.net.httpserver.HttpServer;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.lang.Nullable;
-import org.springframework.util.Assert;
-
-/**
- * Simple exporter for JAX-WS services, autodetecting annotated service beans
- * (through the JAX-WS {@link javax.jws.WebService} annotation) and exporting
- * them through the HTTP server included in Sun's JDK 1.6. The full address
- * for each service will consist of the server's base address with the
- * service name appended (e.g. "http://localhost:8080/OrderService").
- *
- * Note that this exporter will only work on Sun's JDK 1.6 or higher, as well
- * as on JDKs that ship Sun's entire class library as included in the Sun JDK.
- * For a portable JAX-WS exporter, have a look at {@link SimpleJaxWsServiceExporter}.
- *
- * @author Juergen Hoeller
- * @since 2.5.5
- * @see javax.jws.WebService
- * @see javax.xml.ws.Endpoint#publish(Object)
- * @see SimpleJaxWsServiceExporter
- * @deprecated as of Spring Framework 5.1, in favor of {@link SimpleJaxWsServiceExporter}
- */
-@Deprecated
-@org.springframework.lang.UsesSunHttpServer
-public class SimpleHttpServerJaxWsServiceExporter extends AbstractJaxWsServiceExporter {
-
- protected final Log logger = LogFactory.getLog(getClass());
-
- @Nullable
- private HttpServer server;
-
- private int port = 8080;
-
- @Nullable
- private String hostname;
-
- private int backlog = -1;
-
- private int shutdownDelay = 0;
-
- private String basePath = "/";
-
- @Nullable
- private List filters;
-
- @Nullable
- private Authenticator authenticator;
-
- private boolean localServer = false;
-
-
- /**
- * Specify an existing HTTP server to register the web service contexts
- * with. This will typically be a server managed by the general Spring
- * {@link org.springframework.remoting.support.SimpleHttpServerFactoryBean}.
- * Alternatively, configure a local HTTP server through the
- * {@link #setPort "port"}, {@link #setHostname "hostname"} and
- * {@link #setBacklog "backlog"} properties (or rely on the defaults there).
- */
- public void setServer(HttpServer server) {
- this.server = server;
- }
-
- /**
- * Specify the HTTP server's port. Default is 8080.
- *
Only applicable for a locally configured HTTP server.
- * Ignored when the {@link #setServer "server"} property has been specified.
- */
- public void setPort(int port) {
- this.port = port;
- }
-
- /**
- * Specify the HTTP server's hostname to bind to. Default is localhost;
- * can be overridden with a specific network address to bind to.
- *
Only applicable for a locally configured HTTP server.
- * Ignored when the {@link #setServer "server"} property has been specified.
- */
- public void setHostname(String hostname) {
- this.hostname = hostname;
- }
-
- /**
- * Specify the HTTP server's TCP backlog. Default is -1,
- * indicating the system's default value.
- *
Only applicable for a locally configured HTTP server.
- * Ignored when the {@link #setServer "server"} property has been specified.
- */
- public void setBacklog(int backlog) {
- this.backlog = backlog;
- }
-
- /**
- * Specify the number of seconds to wait until HTTP exchanges have
- * completed when shutting down the HTTP server. Default is 0.
- *
Only applicable for a locally configured HTTP server.
- * Ignored when the {@link #setServer "server"} property has been specified.
- */
- public void setShutdownDelay(int shutdownDelay) {
- this.shutdownDelay = shutdownDelay;
- }
-
- /**
- * Set the base path for context publication. Default is "/".
- *
For each context publication path, the service name will be
- * appended to this base address. E.g. service name "OrderService"
- * -> "/OrderService".
- * @see javax.xml.ws.Endpoint#publish(Object)
- * @see javax.jws.WebService#serviceName()
- */
- public void setBasePath(String basePath) {
- this.basePath = basePath;
- }
-
- /**
- * Register common {@link com.sun.net.httpserver.Filter Filters} to be
- * applied to all detected {@link javax.jws.WebService} annotated beans.
- */
- public void setFilters(List filters) {
- this.filters = filters;
- }
-
- /**
- * Register a common {@link com.sun.net.httpserver.Authenticator} to be
- * applied to all detected {@link javax.jws.WebService} annotated beans.
- */
- public void setAuthenticator(Authenticator authenticator) {
- this.authenticator = authenticator;
- }
-
-
- @Override
- public void afterPropertiesSet() throws Exception {
- if (this.server == null) {
- InetSocketAddress address = (this.hostname != null ?
- new InetSocketAddress(this.hostname, this.port) : new InetSocketAddress(this.port));
- HttpServer server = HttpServer.create(address, this.backlog);
- if (logger.isInfoEnabled()) {
- logger.info("Starting HttpServer at address " + address);
- }
- server.start();
- this.server = server;
- this.localServer = true;
- }
- super.afterPropertiesSet();
- }
-
- @Override
- protected void publishEndpoint(Endpoint endpoint, WebService annotation) {
- endpoint.publish(buildHttpContext(endpoint, annotation.serviceName()));
- }
-
- @Override
- protected void publishEndpoint(Endpoint endpoint, WebServiceProvider annotation) {
- endpoint.publish(buildHttpContext(endpoint, annotation.serviceName()));
- }
-
- /**
- * Build the HttpContext for the given endpoint.
- * @param endpoint the JAX-WS Provider Endpoint object
- * @param serviceName the given service name
- * @return the fully populated HttpContext
- */
- protected HttpContext buildHttpContext(Endpoint endpoint, String serviceName) {
- Assert.state(this.server != null, "No HttpServer available");
- String fullPath = calculateEndpointPath(endpoint, serviceName);
- HttpContext httpContext = this.server.createContext(fullPath);
- if (this.filters != null) {
- httpContext.getFilters().addAll(this.filters);
- }
- if (this.authenticator != null) {
- httpContext.setAuthenticator(this.authenticator);
- }
- return httpContext;
- }
-
- /**
- * Calculate the full endpoint path for the given endpoint.
- * @param endpoint the JAX-WS Provider Endpoint object
- * @param serviceName the given service name
- * @return the full endpoint path
- */
- protected String calculateEndpointPath(Endpoint endpoint, String serviceName) {
- return this.basePath + serviceName;
- }
-
-
- @Override
- public void destroy() {
- super.destroy();
- if (this.server != null && this.localServer) {
- logger.info("Stopping HttpServer");
- this.server.stop(this.shutdownDelay);
- }
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleJaxWsServiceExporter.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleJaxWsServiceExporter.java
deleted file mode 100644
index 06786578f9..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/jaxws/SimpleJaxWsServiceExporter.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2002-2018 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.jaxws;
-
-import javax.jws.WebService;
-import javax.xml.ws.Endpoint;
-import javax.xml.ws.WebServiceProvider;
-
-/**
- * Simple exporter for JAX-WS services, autodetecting annotated service beans
- * (through the JAX-WS {@link javax.jws.WebService} annotation) and exporting
- * them with a configured base address (by default "http://localhost:8080/")
- * using the JAX-WS provider's built-in publication support. The full address
- * for each service will consist of the base address with the service name
- * appended (e.g. "http://localhost:8080/OrderService").
- *
- * Note that this exporter will only work if the JAX-WS runtime actually
- * supports publishing with an address argument, i.e. if the JAX-WS runtime
- * ships an internal HTTP server.
- *
- * @author Juergen Hoeller
- * @since 2.5
- * @see javax.jws.WebService
- * @see javax.xml.ws.Endpoint#publish(String)
- */
-public class SimpleJaxWsServiceExporter extends AbstractJaxWsServiceExporter {
-
- /**
- * The default base address.
- */
- public static final String DEFAULT_BASE_ADDRESS = "http://localhost:8080/";
-
- private String baseAddress = DEFAULT_BASE_ADDRESS;
-
-
- /**
- * Set the base address for exported services.
- * Default is "http://localhost:8080/".
- *
For each actual publication address, the service name will be
- * appended to this base address. E.g. service name "OrderService"
- * -> "http://localhost:8080/OrderService".
- * @see javax.xml.ws.Endpoint#publish(String)
- * @see javax.jws.WebService#serviceName()
- */
- public void setBaseAddress(String baseAddress) {
- this.baseAddress = baseAddress;
- }
-
-
- @Override
- protected void publishEndpoint(Endpoint endpoint, WebService annotation) {
- endpoint.publish(calculateEndpointAddress(endpoint, annotation.serviceName()));
- }
-
- @Override
- protected void publishEndpoint(Endpoint endpoint, WebServiceProvider annotation) {
- endpoint.publish(calculateEndpointAddress(endpoint, annotation.serviceName()));
- }
-
- /**
- * Calculate the full endpoint address for the given endpoint.
- * @param endpoint the JAX-WS Provider Endpoint object
- * @param serviceName the given service name
- * @return the full endpoint address
- */
- protected String calculateEndpointAddress(Endpoint endpoint, String serviceName) {
- String fullAddress = this.baseAddress + serviceName;
- if (endpoint.getClass().getName().startsWith("weblogic.")) {
- // Workaround for WebLogic 10.3
- fullAddress = fullAddress + "/";
- }
- return fullAddress;
- }
-
-}
diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/package-info.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/package-info.java
deleted file mode 100644
index 6dc1423ab6..0000000000
--- a/spring-web/src/main/java/org/springframework/remoting/jaxws/package-info.java
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * Remoting classes for Web Services via JAX-WS (the successor of JAX-RPC),
- * as included in Java 6 and Java EE 5. This package provides proxy
- * factories for accessing JAX-WS services and ports.
- */
-@NonNullApi
-@NonNullFields
-package org.springframework.remoting.jaxws;
-
-import org.springframework.lang.NonNullApi;
-import org.springframework.lang.NonNullFields;
diff --git a/spring-web/src/test/java/org/springframework/remoting/caucho/CauchoRemotingTests.java b/spring-web/src/test/java/org/springframework/remoting/caucho/CauchoRemotingTests.java
deleted file mode 100644
index 58d1846bcf..0000000000
--- a/spring-web/src/test/java/org/springframework/remoting/caucho/CauchoRemotingTests.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2002-2019 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.caucho;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-
-import com.caucho.hessian.client.HessianProxyFactory;
-import com.sun.net.httpserver.HttpServer;
-import org.junit.jupiter.api.Test;
-
-import org.springframework.aop.framework.ProxyFactory;
-import org.springframework.beans.testfixture.beans.ITestBean;
-import org.springframework.beans.testfixture.beans.TestBean;
-import org.springframework.remoting.RemoteAccessException;
-import org.springframework.util.SocketUtils;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
-
-/**
- * @author Juergen Hoeller
- * @author Sam Brannen
- * @since 16.05.2003
- */
-public class CauchoRemotingTests {
-
- @Test
- public void hessianProxyFactoryBeanWithClassInsteadOfInterface() throws Exception {
- HessianProxyFactoryBean factory = new HessianProxyFactoryBean();
- assertThatIllegalArgumentException().isThrownBy(() ->
- factory.setServiceInterface(TestBean.class));
- }
-
- @Test
- public void hessianProxyFactoryBeanWithAccessError() throws Exception {
- HessianProxyFactoryBean factory = new HessianProxyFactoryBean();
- factory.setServiceInterface(ITestBean.class);
- factory.setServiceUrl("http://localhosta/testbean");
- factory.afterPropertiesSet();
-
- assertThat(factory.isSingleton()).as("Correct singleton value").isTrue();
- boolean condition = factory.getObject() instanceof ITestBean;
- assertThat(condition).isTrue();
- ITestBean bean = (ITestBean) factory.getObject();
-
- assertThatExceptionOfType(RemoteAccessException.class).isThrownBy(() ->
- bean.setName("test"));
- }
-
- @Test
- public void hessianProxyFactoryBeanWithAuthenticationAndAccessError() throws Exception {
- HessianProxyFactoryBean factory = new HessianProxyFactoryBean();
- factory.setServiceInterface(ITestBean.class);
- factory.setServiceUrl("http://localhosta/testbean");
- factory.setUsername("test");
- factory.setPassword("bean");
- factory.setOverloadEnabled(true);
- factory.afterPropertiesSet();
-
- assertThat(factory.isSingleton()).as("Correct singleton value").isTrue();
- boolean condition = factory.getObject() instanceof ITestBean;
- assertThat(condition).isTrue();
- ITestBean bean = (ITestBean) factory.getObject();
-
- assertThatExceptionOfType(RemoteAccessException.class).isThrownBy(() ->
- bean.setName("test"));
- }
-
- @Test
- public void hessianProxyFactoryBeanWithCustomProxyFactory() throws Exception {
- TestHessianProxyFactory proxyFactory = new TestHessianProxyFactory();
- HessianProxyFactoryBean factory = new HessianProxyFactoryBean();
- factory.setServiceInterface(ITestBean.class);
- factory.setServiceUrl("http://localhosta/testbean");
- factory.setProxyFactory(proxyFactory);
- factory.setUsername("test");
- factory.setPassword("bean");
- factory.setOverloadEnabled(true);
- factory.afterPropertiesSet();
- assertThat(factory.isSingleton()).as("Correct singleton value").isTrue();
- boolean condition = factory.getObject() instanceof ITestBean;
- assertThat(condition).isTrue();
- ITestBean bean = (ITestBean) factory.getObject();
-
- assertThat(proxyFactory.user).isEqualTo("test");
- assertThat(proxyFactory.password).isEqualTo("bean");
- assertThat(proxyFactory.overloadEnabled).isTrue();
-
- assertThatExceptionOfType(RemoteAccessException.class).isThrownBy(() ->
- bean.setName("test"));
- }
-
- @Test
- @SuppressWarnings("deprecation")
- public void simpleHessianServiceExporter() throws IOException {
- final int port = SocketUtils.findAvailableTcpPort();
-
- TestBean tb = new TestBean("tb");
- SimpleHessianServiceExporter exporter = new SimpleHessianServiceExporter();
- exporter.setService(tb);
- exporter.setServiceInterface(ITestBean.class);
- exporter.setDebug(true);
- exporter.prepare();
-
- HttpServer server = HttpServer.create(new InetSocketAddress(port), -1);
- server.createContext("/hessian", exporter);
- server.start();
- try {
- HessianClientInterceptor client = new HessianClientInterceptor();
- client.setServiceUrl("http://localhost:" + port + "/hessian");
- client.setServiceInterface(ITestBean.class);
- //client.setHessian2(true);
- client.prepare();
- ITestBean proxy = ProxyFactory.getProxy(ITestBean.class, client);
- assertThat(proxy.getName()).isEqualTo("tb");
- proxy.setName("test");
- assertThat(proxy.getName()).isEqualTo("test");
- }
- finally {
- server.stop(Integer.MAX_VALUE);
- }
- }
-
-
- private static class TestHessianProxyFactory extends HessianProxyFactory {
-
- private String user;
- private String password;
- private boolean overloadEnabled;
-
- @Override
- public void setUser(String user) {
- this.user = user;
- }
-
- @Override
- public void setPassword(String password) {
- this.password = password;
- }
-
- @Override
- public void setOverloadEnabled(boolean overloadEnabled) {
- this.overloadEnabled = overloadEnabled;
- }
- }
-
-}
diff --git a/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutorTests.java b/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutorTests.java
deleted file mode 100644
index c5d486f05e..0000000000
--- a/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpComponentsHttpInvokerRequestExecutorTests.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright 2002-2019 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.httpinvoker;
-
-import java.io.IOException;
-
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.Configurable;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.junit.jupiter.api.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.withSettings;
-
-/**
- * @author Stephane Nicoll
- */
-public class HttpComponentsHttpInvokerRequestExecutorTests {
-
- @Test
- public void customizeConnectionTimeout() throws IOException {
- HttpComponentsHttpInvokerRequestExecutor executor = new HttpComponentsHttpInvokerRequestExecutor();
- executor.setConnectTimeout(5000);
-
- HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service");
- HttpPost httpPost = executor.createHttpPost(config);
- assertThat(httpPost.getConfig().getConnectTimeout()).isEqualTo(5000);
- }
-
- @Test
- public void customizeConnectionRequestTimeout() throws IOException {
- HttpComponentsHttpInvokerRequestExecutor executor = new HttpComponentsHttpInvokerRequestExecutor();
- executor.setConnectionRequestTimeout(7000);
-
- HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service");
- HttpPost httpPost = executor.createHttpPost(config);
- assertThat(httpPost.getConfig().getConnectionRequestTimeout()).isEqualTo(7000);
- }
-
- @Test
- public void customizeReadTimeout() throws IOException {
- HttpComponentsHttpInvokerRequestExecutor executor = new HttpComponentsHttpInvokerRequestExecutor();
- executor.setReadTimeout(10000);
-
- HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service");
- HttpPost httpPost = executor.createHttpPost(config);
- assertThat(httpPost.getConfig().getSocketTimeout()).isEqualTo(10000);
- }
-
- @Test
- public void defaultSettingsOfHttpClientMergedOnExecutorCustomization() throws IOException {
- RequestConfig defaultConfig = RequestConfig.custom().setConnectTimeout(1234).build();
- CloseableHttpClient client = mock(CloseableHttpClient.class,
- withSettings().extraInterfaces(Configurable.class));
- Configurable configurable = (Configurable) client;
- given(configurable.getConfig()).willReturn(defaultConfig);
-
- HttpComponentsHttpInvokerRequestExecutor executor =
- new HttpComponentsHttpInvokerRequestExecutor(client);
- HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service");
- HttpPost httpPost = executor.createHttpPost(config);
- assertThat(httpPost.getConfig()).as("Default client configuration is expected").isSameAs(defaultConfig);
-
- executor.setConnectionRequestTimeout(4567);
- HttpPost httpPost2 = executor.createHttpPost(config);
- assertThat(httpPost2.getConfig()).isNotNull();
- assertThat(httpPost2.getConfig().getConnectionRequestTimeout()).isEqualTo(4567);
- // Default connection timeout merged
- assertThat(httpPost2.getConfig().getConnectTimeout()).isEqualTo(1234);
- }
-
- @Test
- public void localSettingsOverrideClientDefaultSettings() throws Exception {
- RequestConfig defaultConfig = RequestConfig.custom()
- .setConnectTimeout(1234).setConnectionRequestTimeout(6789).build();
- CloseableHttpClient client = mock(CloseableHttpClient.class,
- withSettings().extraInterfaces(Configurable.class));
- Configurable configurable = (Configurable) client;
- given(configurable.getConfig()).willReturn(defaultConfig);
-
- HttpComponentsHttpInvokerRequestExecutor executor =
- new HttpComponentsHttpInvokerRequestExecutor(client);
- executor.setConnectTimeout(5000);
-
- HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service");
- HttpPost httpPost = executor.createHttpPost(config);
- RequestConfig requestConfig = httpPost.getConfig();
- assertThat(requestConfig.getConnectTimeout()).isEqualTo(5000);
- assertThat(requestConfig.getConnectionRequestTimeout()).isEqualTo(6789);
- assertThat(requestConfig.getSocketTimeout()).isEqualTo(-1);
- }
-
- @Test
- public void mergeBasedOnCurrentHttpClient() throws Exception {
- RequestConfig defaultConfig = RequestConfig.custom()
- .setSocketTimeout(1234).build();
- final CloseableHttpClient client = mock(CloseableHttpClient.class,
- withSettings().extraInterfaces(Configurable.class));
- Configurable configurable = (Configurable) client;
- given(configurable.getConfig()).willReturn(defaultConfig);
-
- HttpComponentsHttpInvokerRequestExecutor executor =
- new HttpComponentsHttpInvokerRequestExecutor() {
- @Override
- public HttpClient getHttpClient() {
- return client;
- }
- };
- executor.setReadTimeout(5000);
- HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service");
- HttpPost httpPost = executor.createHttpPost(config);
- RequestConfig requestConfig = httpPost.getConfig();
- assertThat(requestConfig.getConnectTimeout()).isEqualTo(-1);
- assertThat(requestConfig.getConnectionRequestTimeout()).isEqualTo(-1);
- assertThat(requestConfig.getSocketTimeout()).isEqualTo(5000);
-
- // Update the Http client so that it returns an updated config
- RequestConfig updatedDefaultConfig = RequestConfig.custom()
- .setConnectTimeout(1234).build();
- given(configurable.getConfig()).willReturn(updatedDefaultConfig);
- executor.setReadTimeout(7000);
- HttpPost httpPost2 = executor.createHttpPost(config);
- RequestConfig requestConfig2 = httpPost2.getConfig();
- assertThat(requestConfig2.getConnectTimeout()).isEqualTo(1234);
- assertThat(requestConfig2.getConnectionRequestTimeout()).isEqualTo(-1);
- assertThat(requestConfig2.getSocketTimeout()).isEqualTo(7000);
- }
-
- @Test
- public void ignoreFactorySettings() throws IOException {
- CloseableHttpClient httpClient = HttpClientBuilder.create().build();
- HttpComponentsHttpInvokerRequestExecutor executor = new HttpComponentsHttpInvokerRequestExecutor(httpClient) {
- @Override
- protected RequestConfig createRequestConfig(HttpInvokerClientConfiguration config) {
- return null;
- }
- };
-
- HttpInvokerClientConfiguration config = mockHttpInvokerClientConfiguration("https://fake-service");
- HttpPost httpPost = executor.createHttpPost(config);
- assertThat(httpPost.getConfig()).as("custom request config should not be set").isNull();
- }
-
- private HttpInvokerClientConfiguration mockHttpInvokerClientConfiguration(String serviceUrl) {
- HttpInvokerClientConfiguration config = mock(HttpInvokerClientConfiguration.class);
- given(config.getServiceUrl()).willReturn(serviceUrl);
- return config;
- }
-
-}
diff --git a/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerFactoryBeanIntegrationTests.java b/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerFactoryBeanIntegrationTests.java
deleted file mode 100644
index a53d1e2e38..0000000000
--- a/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerFactoryBeanIntegrationTests.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2002-2020 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.httpinvoker;
-
-import org.junit.jupiter.api.Test;
-
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Lazy;
-import org.springframework.core.env.Environment;
-import org.springframework.remoting.support.RemoteInvocationResult;
-import org.springframework.scheduling.annotation.Async;
-import org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor;
-import org.springframework.stereotype.Component;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-/**
- * @author Stephane Nicoll
- */
-class HttpInvokerFactoryBeanIntegrationTests {
-
- @Test
- @SuppressWarnings("resource")
- void testLoadedConfigClass() {
- ApplicationContext context = new AnnotationConfigApplicationContext(InvokerAutowiringConfig.class);
- MyBean myBean = context.getBean("myBean", MyBean.class);
- assertThat(myBean.myService).isSameAs(context.getBean("myService"));
- myBean.myService.handle();
- myBean.myService.handleAsync();
- }
-
- @Test
- @SuppressWarnings("resource")
- void testNonLoadedConfigClass() {
- AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
- context.registerBeanDefinition("config", new RootBeanDefinition(InvokerAutowiringConfig.class.getName()));
- context.refresh();
- MyBean myBean = context.getBean("myBean", MyBean.class);
- assertThat(myBean.myService).isSameAs(context.getBean("myService"));
- myBean.myService.handle();
- myBean.myService.handleAsync();
- }
-
- @Test
- @SuppressWarnings("resource")
- void withConfigurationClassWithPlainFactoryBean() {
- AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
- context.register(ConfigWithPlainFactoryBean.class);
- context.refresh();
- MyBean myBean = context.getBean("myBean", MyBean.class);
- assertThat(myBean.myService).isSameAs(context.getBean("myService"));
- myBean.myService.handle();
- myBean.myService.handleAsync();
- }
-
-
- interface MyService {
-
- void handle();
-
- @Async
- public void handleAsync();
- }
-
-
- @Component("myBean")
- static class MyBean {
-
- @Autowired
- MyService myService;
- }
-
-
- @Configuration
- @ComponentScan
- @Lazy
- static class InvokerAutowiringConfig {
-
- @Bean
- AsyncAnnotationBeanPostProcessor aabpp() {
- return new AsyncAnnotationBeanPostProcessor();
- }
-
- @Bean
- @SuppressWarnings("deprecation")
- HttpInvokerProxyFactoryBean myService() {
- HttpInvokerProxyFactoryBean factory = new HttpInvokerProxyFactoryBean();
- factory.setServiceUrl("/svc/dummy");
- factory.setServiceInterface(MyService.class);
- factory.setHttpInvokerRequestExecutor((config, invocation) -> new RemoteInvocationResult());
- return factory;
- }
-
- @Bean
- FactoryBean myOtherService() {
- throw new IllegalStateException("Don't ever call me");
- }
- }
-
-
- @Configuration
- static class ConfigWithPlainFactoryBean {
-
- @Autowired
- Environment env;
-
- @Bean
- MyBean myBean() {
- return new MyBean();
- }
-
- @Bean
- @SuppressWarnings("deprecation")
- HttpInvokerProxyFactoryBean myService() {
- String name = env.getProperty("testbean.name");
- HttpInvokerProxyFactoryBean factory = new HttpInvokerProxyFactoryBean();
- factory.setServiceUrl("/svc/" + name);
- factory.setServiceInterface(MyService.class);
- factory.setHttpInvokerRequestExecutor((config, invocation) -> new RemoteInvocationResult());
- return factory;
- }
- }
-
-}
diff --git a/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerTests.java b/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerTests.java
deleted file mode 100644
index 8a2c697b69..0000000000
--- a/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerTests.java
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright 2002-2021 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.httpinvoker;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Arrays;
-import java.util.zip.GZIPInputStream;
-import java.util.zip.GZIPOutputStream;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.aopalliance.intercept.MethodInvocation;
-import org.junit.jupiter.api.Test;
-
-import org.springframework.beans.factory.BeanClassLoaderAware;
-import org.springframework.beans.testfixture.beans.ITestBean;
-import org.springframework.beans.testfixture.beans.TestBean;
-import org.springframework.remoting.RemoteAccessException;
-import org.springframework.remoting.support.DefaultRemoteInvocationExecutor;
-import org.springframework.remoting.support.RemoteInvocation;
-import org.springframework.remoting.support.RemoteInvocationResult;
-import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
-import org.springframework.web.testfixture.servlet.MockHttpServletResponse;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
-
-/**
- * @author Juergen Hoeller
- * @since 09.08.2004
- */
-@SuppressWarnings("deprecation")
-class HttpInvokerTests {
-
- @Test
- void httpInvokerProxyFactoryBeanAndServiceExporter() {
- doTestHttpInvokerProxyFactoryBeanAndServiceExporter(false);
- }
-
- @Test
- void httpInvokerProxyFactoryBeanAndServiceExporterWithExplicitClassLoader() {
- doTestHttpInvokerProxyFactoryBeanAndServiceExporter(true);
- }
-
- private void doTestHttpInvokerProxyFactoryBeanAndServiceExporter(boolean explicitClassLoader) {
- TestBean target = new TestBean("myname", 99);
-
- final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
- exporter.setServiceInterface(ITestBean.class);
- exporter.setService(target);
- exporter.afterPropertiesSet();
-
- HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean();
- pfb.setServiceInterface(ITestBean.class);
- pfb.setServiceUrl("https://myurl");
-
- pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() {
- @Override
- protected RemoteInvocationResult doExecuteRequest(
- HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) throws Exception {
- assertThat(config.getServiceUrl()).isEqualTo("https://myurl");
- MockHttpServletRequest request = new MockHttpServletRequest();
- MockHttpServletResponse response = new MockHttpServletResponse();
- request.setContent(baos.toByteArray());
- exporter.handleRequest(request, response);
- return readRemoteInvocationResult(
- new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl());
- }
- });
- if (explicitClassLoader) {
- ((BeanClassLoaderAware) pfb.getHttpInvokerRequestExecutor()).setBeanClassLoader(getClass().getClassLoader());
- }
-
- pfb.afterPropertiesSet();
- ITestBean proxy = (ITestBean) pfb.getObject();
- assertThat(proxy.getName()).isEqualTo("myname");
- assertThat(proxy.getAge()).isEqualTo(99);
- proxy.setAge(50);
- assertThat(proxy.getAge()).isEqualTo(50);
- proxy.setStringArray(new String[] {"str1", "str2"});
- assertThat(Arrays.equals(new String[] {"str1", "str2"}, proxy.getStringArray())).isTrue();
- proxy.setSomeIntegerArray(new Integer[] {1, 2, 3});
- assertThat(Arrays.equals(new Integer[] {1, 2, 3}, proxy.getSomeIntegerArray())).isTrue();
- proxy.setNestedIntegerArray(new Integer[][] {{1, 2, 3}, {4, 5, 6}});
- Integer[][] integerArray = proxy.getNestedIntegerArray();
- assertThat(Arrays.equals(new Integer[] {1, 2, 3}, integerArray[0])).isTrue();
- assertThat(Arrays.equals(new Integer[] {4, 5, 6}, integerArray[1])).isTrue();
- proxy.setSomeIntArray(new int[] {1, 2, 3});
- assertThat(Arrays.equals(new int[] {1, 2, 3}, proxy.getSomeIntArray())).isTrue();
- proxy.setNestedIntArray(new int[][] {{1, 2, 3}, {4, 5, 6}});
- int[][] intArray = proxy.getNestedIntArray();
- assertThat(Arrays.equals(new int[] {1, 2, 3}, intArray[0])).isTrue();
- assertThat(Arrays.equals(new int[] {4, 5, 6}, intArray[1])).isTrue();
-
- assertThatIllegalStateException().isThrownBy(() ->
- proxy.exceptional(new IllegalStateException()));
- assertThatExceptionOfType(IllegalAccessException.class).isThrownBy(() ->
- proxy.exceptional(new IllegalAccessException()));
- }
-
- @Test
- void httpInvokerProxyFactoryBeanAndServiceExporterWithIOException() throws Exception {
- TestBean target = new TestBean("myname", 99);
-
- final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
- exporter.setServiceInterface(ITestBean.class);
- exporter.setService(target);
- exporter.afterPropertiesSet();
-
- HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean();
- pfb.setServiceInterface(ITestBean.class);
- pfb.setServiceUrl("https://myurl");
-
- pfb.setHttpInvokerRequestExecutor((config, invocation) -> { throw new IOException("argh"); });
-
- pfb.afterPropertiesSet();
- ITestBean proxy = (ITestBean) pfb.getObject();
- assertThatExceptionOfType(RemoteAccessException.class)
- .isThrownBy(() -> proxy.setAge(50))
- .withCauseInstanceOf(IOException.class);
- }
-
- @Test
- void httpInvokerProxyFactoryBeanAndServiceExporterWithGzipCompression() {
- TestBean target = new TestBean("myname", 99);
-
- final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter() {
- @Override
- protected InputStream decorateInputStream(HttpServletRequest request, InputStream is) throws IOException {
- if ("gzip".equals(request.getHeader("Compression"))) {
- return new GZIPInputStream(is);
- }
- else {
- return is;
- }
- }
- @Override
- protected OutputStream decorateOutputStream(
- HttpServletRequest request, HttpServletResponse response, OutputStream os) throws IOException {
- if ("gzip".equals(request.getHeader("Compression"))) {
- return new GZIPOutputStream(os);
- }
- else {
- return os;
- }
- }
- };
- exporter.setServiceInterface(ITestBean.class);
- exporter.setService(target);
- exporter.afterPropertiesSet();
-
- HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean();
- pfb.setServiceInterface(ITestBean.class);
- pfb.setServiceUrl("https://myurl");
-
- pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() {
- @Override
- protected RemoteInvocationResult doExecuteRequest(
- HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)
- throws IOException, ClassNotFoundException {
- assertThat(config.getServiceUrl()).isEqualTo("https://myurl");
- MockHttpServletRequest request = new MockHttpServletRequest();
- request.addHeader("Compression", "gzip");
- MockHttpServletResponse response = new MockHttpServletResponse();
- request.setContent(baos.toByteArray());
- try {
- exporter.handleRequest(request, response);
- }
- catch (ServletException ex) {
- throw new IOException(ex.toString());
- }
- return readRemoteInvocationResult(
- new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl());
- }
- @Override
- protected OutputStream decorateOutputStream(OutputStream os) throws IOException {
- return new GZIPOutputStream(os);
- }
- @Override
- protected InputStream decorateInputStream(InputStream is) throws IOException {
- return new GZIPInputStream(is);
- }
- });
-
- pfb.afterPropertiesSet();
- ITestBean proxy = (ITestBean) pfb.getObject();
- assertThat(proxy.getName()).isEqualTo("myname");
- assertThat(proxy.getAge()).isEqualTo(99);
- proxy.setAge(50);
- assertThat(proxy.getAge()).isEqualTo(50);
-
- assertThatIllegalStateException().isThrownBy(() ->
- proxy.exceptional(new IllegalStateException()));
- assertThatExceptionOfType(IllegalAccessException.class).isThrownBy(() ->
- proxy.exceptional(new IllegalAccessException()));
- }
-
- @Test
- void httpInvokerProxyFactoryBeanAndServiceExporterWithWrappedInvocations() {
- TestBean target = new TestBean("myname", 99);
-
- final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter() {
- @Override
- protected RemoteInvocation doReadRemoteInvocation(ObjectInputStream ois)
- throws IOException, ClassNotFoundException {
- Object obj = ois.readObject();
- if (!(obj instanceof TestRemoteInvocationWrapper)) {
- throw new IOException("Deserialized object needs to be assignable to type [" +
- TestRemoteInvocationWrapper.class.getName() + "]: " + obj);
- }
- return ((TestRemoteInvocationWrapper) obj).remoteInvocation;
- }
- @Override
- protected void doWriteRemoteInvocationResult(RemoteInvocationResult result, ObjectOutputStream oos)
- throws IOException {
- oos.writeObject(new TestRemoteInvocationResultWrapper(result));
- }
- };
- exporter.setServiceInterface(ITestBean.class);
- exporter.setService(target);
- exporter.afterPropertiesSet();
-
- HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean();
- pfb.setServiceInterface(ITestBean.class);
- pfb.setServiceUrl("https://myurl");
-
- pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() {
- @Override
- protected RemoteInvocationResult doExecuteRequest(
- HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) throws Exception {
- assertThat(config.getServiceUrl()).isEqualTo("https://myurl");
- MockHttpServletRequest request = new MockHttpServletRequest();
- MockHttpServletResponse response = new MockHttpServletResponse();
- request.setContent(baos.toByteArray());
- exporter.handleRequest(request, response);
- return readRemoteInvocationResult(
- new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl());
- }
- @Override
- protected void doWriteRemoteInvocation(RemoteInvocation invocation, ObjectOutputStream oos) throws IOException {
- oos.writeObject(new TestRemoteInvocationWrapper(invocation));
- }
- @Override
- protected RemoteInvocationResult doReadRemoteInvocationResult(ObjectInputStream ois)
- throws IOException, ClassNotFoundException {
- Object obj = ois.readObject();
- if (!(obj instanceof TestRemoteInvocationResultWrapper)) {
- throw new IOException("Deserialized object needs to be assignable to type ["
- + TestRemoteInvocationResultWrapper.class.getName() + "]: " + obj);
- }
- return ((TestRemoteInvocationResultWrapper) obj).remoteInvocationResult;
- }
- });
-
- pfb.afterPropertiesSet();
- ITestBean proxy = (ITestBean) pfb.getObject();
- assertThat(proxy.getName()).isEqualTo("myname");
- assertThat(proxy.getAge()).isEqualTo(99);
- proxy.setAge(50);
- assertThat(proxy.getAge()).isEqualTo(50);
-
- assertThatIllegalStateException().isThrownBy(() ->
- proxy.exceptional(new IllegalStateException()));
- assertThatExceptionOfType(IllegalAccessException.class).isThrownBy(() ->
- proxy.exceptional(new IllegalAccessException()));
- }
-
- @Test
- void httpInvokerProxyFactoryBeanAndServiceExporterWithInvocationAttributes() {
- TestBean target = new TestBean("myname", 99);
-
- final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
- exporter.setServiceInterface(ITestBean.class);
- exporter.setService(target);
- exporter.setRemoteInvocationExecutor(new DefaultRemoteInvocationExecutor() {
- @Override
- public Object invoke(RemoteInvocation invocation, Object targetObject)
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- assertThat(invocation.getAttributes()).isNotNull();
- assertThat(invocation.getAttributes().size()).isEqualTo(1);
- assertThat(invocation.getAttributes().get("myKey")).isEqualTo("myValue");
- assertThat(invocation.getAttribute("myKey")).isEqualTo("myValue");
- return super.invoke(invocation, targetObject);
- }
- });
- exporter.afterPropertiesSet();
-
- HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean();
- pfb.setServiceInterface(ITestBean.class);
- pfb.setServiceUrl("https://myurl");
- pfb.setRemoteInvocationFactory(methodInvocation -> {
- RemoteInvocation invocation = new RemoteInvocation(methodInvocation);
- invocation.addAttribute("myKey", "myValue");
- assertThatIllegalStateException().isThrownBy(() ->
- invocation.addAttribute("myKey", "myValue"));
- assertThat(invocation.getAttributes()).isNotNull();
- assertThat(invocation.getAttributes().size()).isEqualTo(1);
- assertThat(invocation.getAttributes().get("myKey")).isEqualTo("myValue");
- assertThat(invocation.getAttribute("myKey")).isEqualTo("myValue");
- return invocation;
- });
-
- pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() {
- @Override
- protected RemoteInvocationResult doExecuteRequest(
- HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) throws Exception {
- assertThat(config.getServiceUrl()).isEqualTo("https://myurl");
- MockHttpServletRequest request = new MockHttpServletRequest();
- MockHttpServletResponse response = new MockHttpServletResponse();
- request.setContent(baos.toByteArray());
- exporter.handleRequest(request, response);
- return readRemoteInvocationResult(
- new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl());
- }
- });
-
- pfb.afterPropertiesSet();
- ITestBean proxy = (ITestBean) pfb.getObject();
- assertThat(proxy.getName()).isEqualTo("myname");
- assertThat(proxy.getAge()).isEqualTo(99);
- }
-
- @Test
- void httpInvokerProxyFactoryBeanAndServiceExporterWithCustomInvocationObject() {
- TestBean target = new TestBean("myname", 99);
-
- final HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
- exporter.setServiceInterface(ITestBean.class);
- exporter.setService(target);
- exporter.setRemoteInvocationExecutor(new DefaultRemoteInvocationExecutor() {
- @Override
- public Object invoke(RemoteInvocation invocation, Object targetObject)
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- boolean condition = invocation instanceof TestRemoteInvocation;
- assertThat(condition).isTrue();
- assertThat(invocation.getAttributes()).isNull();
- assertThat(invocation.getAttribute("myKey")).isNull();
- return super.invoke(invocation, targetObject);
- }
- });
- exporter.afterPropertiesSet();
-
- HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean();
- pfb.setServiceInterface(ITestBean.class);
- pfb.setServiceUrl("https://myurl");
- pfb.setRemoteInvocationFactory(methodInvocation -> {
- RemoteInvocation invocation = new TestRemoteInvocation(methodInvocation);
- assertThat(invocation.getAttributes()).isNull();
- assertThat(invocation.getAttribute("myKey")).isNull();
- return invocation;
- });
-
- pfb.setHttpInvokerRequestExecutor(new AbstractHttpInvokerRequestExecutor() {
- @Override
- protected RemoteInvocationResult doExecuteRequest(
- HttpInvokerClientConfiguration config, ByteArrayOutputStream baos) throws Exception {
- assertThat(config.getServiceUrl()).isEqualTo("https://myurl");
- MockHttpServletRequest request = new MockHttpServletRequest();
- MockHttpServletResponse response = new MockHttpServletResponse();
- request.setContent(baos.toByteArray());
- exporter.handleRequest(request, response);
- return readRemoteInvocationResult(
- new ByteArrayInputStream(response.getContentAsByteArray()), config.getCodebaseUrl());
- }
- });
-
- pfb.afterPropertiesSet();
- ITestBean proxy = (ITestBean) pfb.getObject();
- assertThat(proxy.getName()).isEqualTo("myname");
- assertThat(proxy.getAge()).isEqualTo(99);
- }
-
- @Test
- void httpInvokerWithSpecialLocalMethods() {
- String serviceUrl = "https://myurl";
- HttpInvokerProxyFactoryBean pfb = new HttpInvokerProxyFactoryBean();
- pfb.setServiceInterface(ITestBean.class);
- pfb.setServiceUrl(serviceUrl);
-
- pfb.setHttpInvokerRequestExecutor((config, invocation) -> { throw new IOException("argh"); });
-
- pfb.afterPropertiesSet();
- ITestBean proxy = (ITestBean) pfb.getObject();
-
- // shouldn't go through to remote service
- assertThat(proxy.toString().contains("HTTP invoker")).isTrue();
- assertThat(proxy.toString().contains(serviceUrl)).isTrue();
- assertThat(proxy.hashCode()).isEqualTo(proxy.hashCode());
- assertThat(proxy.equals(proxy)).isTrue();
-
- // should go through
- assertThatExceptionOfType(RemoteAccessException.class)
- .isThrownBy(() -> proxy.setAge(50))
- .withCauseInstanceOf(IOException.class);
- }
-
-
- @SuppressWarnings("serial")
- private static class TestRemoteInvocation extends RemoteInvocation {
-
- TestRemoteInvocation(MethodInvocation methodInvocation) {
- super(methodInvocation);
- }
- }
-
-
- @SuppressWarnings("serial")
- private static class TestRemoteInvocationWrapper implements Serializable {
-
- private final RemoteInvocation remoteInvocation;
-
- TestRemoteInvocationWrapper(RemoteInvocation remoteInvocation) {
- this.remoteInvocation = remoteInvocation;
- }
- }
-
-
- @SuppressWarnings("serial")
- private static class TestRemoteInvocationResultWrapper implements Serializable {
-
- private final RemoteInvocationResult remoteInvocationResult;
-
- TestRemoteInvocationResultWrapper(RemoteInvocationResult remoteInvocationResult) {
- this.remoteInvocationResult = remoteInvocationResult;
- }
- }
-
-}
diff --git a/spring-web/src/test/java/org/springframework/remoting/jaxws/JaxWsSupportTests.java b/spring-web/src/test/java/org/springframework/remoting/jaxws/JaxWsSupportTests.java
deleted file mode 100644
index 1a2d4f06a5..0000000000
--- a/spring-web/src/test/java/org/springframework/remoting/jaxws/JaxWsSupportTests.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright 2002-2019 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.jaxws;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import javax.xml.namespace.QName;
-import javax.xml.ws.BindingProvider;
-import javax.xml.ws.Service;
-import javax.xml.ws.WebServiceClient;
-import javax.xml.ws.WebServiceException;
-import javax.xml.ws.WebServiceFeature;
-import javax.xml.ws.WebServiceRef;
-import javax.xml.ws.soap.AddressingFeature;
-
-import org.junit.jupiter.api.Test;
-
-import org.springframework.beans.factory.BeanCreationException;
-import org.springframework.beans.factory.support.GenericBeanDefinition;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.context.annotation.AnnotationConfigUtils;
-import org.springframework.context.support.GenericApplicationContext;
-import org.springframework.remoting.RemoteAccessException;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-
-/**
- * @author Juergen Hoeller
- * @since 2.5
- */
-public class JaxWsSupportTests {
-
- @Test
- public void testJaxWsPortAccess() throws Exception {
- doTestJaxWsPortAccess((WebServiceFeature[]) null);
- }
-
- @Test
- public void testJaxWsPortAccessWithFeature() throws Exception {
- doTestJaxWsPortAccess(new AddressingFeature());
- }
-
- private void doTestJaxWsPortAccess(WebServiceFeature... features) throws Exception {
- GenericApplicationContext ac = new GenericApplicationContext();
-
- GenericBeanDefinition serviceDef = new GenericBeanDefinition();
- serviceDef.setBeanClass(OrderServiceImpl.class);
- ac.registerBeanDefinition("service", serviceDef);
-
- GenericBeanDefinition exporterDef = new GenericBeanDefinition();
- exporterDef.setBeanClass(SimpleJaxWsServiceExporter.class);
- exporterDef.getPropertyValues().add("baseAddress", "http://localhost:9999/");
- ac.registerBeanDefinition("exporter", exporterDef);
-
- GenericBeanDefinition clientDef = new GenericBeanDefinition();
- clientDef.setBeanClass(JaxWsPortProxyFactoryBean.class);
- clientDef.getPropertyValues().add("wsdlDocumentUrl", "http://localhost:9999/OrderService?wsdl");
- clientDef.getPropertyValues().add("namespaceUri", "http://jaxws.remoting.springframework.org/");
- clientDef.getPropertyValues().add("username", "juergen");
- clientDef.getPropertyValues().add("password", "hoeller");
- clientDef.getPropertyValues().add("serviceName", "OrderService");
- clientDef.getPropertyValues().add("serviceInterface", OrderService.class);
- clientDef.getPropertyValues().add("lookupServiceOnStartup", Boolean.FALSE);
- if (features != null) {
- clientDef.getPropertyValues().add("portFeatures", features);
- }
- ac.registerBeanDefinition("client", clientDef);
-
- GenericBeanDefinition serviceFactoryDef = new GenericBeanDefinition();
- serviceFactoryDef.setBeanClass(LocalJaxWsServiceFactoryBean.class);
- serviceFactoryDef.getPropertyValues().add("wsdlDocumentUrl", "http://localhost:9999/OrderService?wsdl");
- serviceFactoryDef.getPropertyValues().add("namespaceUri", "http://jaxws.remoting.springframework.org/");
- serviceFactoryDef.getPropertyValues().add("serviceName", "OrderService");
- ac.registerBeanDefinition("orderService", serviceFactoryDef);
-
- ac.registerBeanDefinition("accessor", new RootBeanDefinition(ServiceAccessor.class));
- AnnotationConfigUtils.registerAnnotationConfigProcessors(ac);
-
- try {
- ac.refresh();
-
- OrderService orderService = ac.getBean("client", OrderService.class);
- boolean condition = orderService instanceof BindingProvider;
- assertThat(condition).isTrue();
- ((BindingProvider) orderService).getRequestContext();
-
- String order = orderService.getOrder(1000);
- assertThat(order).isEqualTo("order 1000");
- assertThatExceptionOfType(Exception.class).isThrownBy(() ->
- orderService.getOrder(0))
- .matches(ex -> ex instanceof OrderNotFoundException ||
- ex instanceof RemoteAccessException);
- // ignore RemoteAccessException as probably setup issue with JAX-WS provider vs JAXB
-
- ServiceAccessor serviceAccessor = ac.getBean("accessor", ServiceAccessor.class);
- order = serviceAccessor.orderService.getOrder(1000);
- assertThat(order).isEqualTo("order 1000");
- assertThatExceptionOfType(Exception.class).isThrownBy(() ->
- serviceAccessor.orderService.getOrder(0))
- .matches(ex -> ex instanceof OrderNotFoundException ||
- ex instanceof WebServiceException);
- // ignore WebServiceException as probably setup issue with JAX-WS provider vs JAXB
- }
- catch (BeanCreationException ex) {
- if ("exporter".equals(ex.getBeanName()) && ex.getRootCause() instanceof ClassNotFoundException) {
- // ignore - probably running on JDK without the JAX-WS impl present
- }
- else {
- throw ex;
- }
- }
- finally {
- ac.close();
- }
- }
-
-
- public static class ServiceAccessor {
-
- @WebServiceRef
- public OrderService orderService;
-
- public OrderService myService;
-
- @WebServiceRef(value = OrderServiceService.class, wsdlLocation = "http://localhost:9999/OrderService?wsdl")
- public void setMyService(OrderService myService) {
- this.myService = myService;
- }
- }
-
-
- @WebServiceClient(targetNamespace = "http://jaxws.remoting.springframework.org/", name="OrderService")
- public static class OrderServiceService extends Service {
-
- public OrderServiceService() throws MalformedURLException {
- super(new URL("http://localhost:9999/OrderService?wsdl"),
- new QName("http://jaxws.remoting.springframework.org/", "OrderService"));
- }
-
- public OrderServiceService(URL wsdlDocumentLocation, QName serviceName) {
- super(wsdlDocumentLocation, serviceName);
- }
- }
-
-}
diff --git a/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderNotFoundException.java b/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderNotFoundException.java
deleted file mode 100644
index 58cc650d10..0000000000
--- a/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderNotFoundException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2002-2019 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.jaxws;
-
-import javax.xml.ws.WebFault;
-
-/**
- * @author Juergen Hoeller
- */
-@WebFault
-@SuppressWarnings("serial")
-public class OrderNotFoundException extends Exception {
-
- private final String faultInfo;
-
- public OrderNotFoundException(String message) {
- super(message);
- this.faultInfo = null;
- }
-
- public OrderNotFoundException(String message, String faultInfo) {
- super(message);
- this.faultInfo = faultInfo;
- }
-
- public String getFaultInfo() {
- return this.faultInfo;
- }
-
-}
diff --git a/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderService.java b/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderService.java
deleted file mode 100644
index 2b29d13cb3..0000000000
--- a/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderService.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2002-2007 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.jaxws;
-
-import javax.jws.WebService;
-import javax.jws.soap.SOAPBinding;
-
-/**
- * @author Juergen Hoeller
- */
-@WebService
-@SOAPBinding(style = SOAPBinding.Style.RPC)
-public interface OrderService {
-
- String getOrder(int id) throws OrderNotFoundException;
-
-}
diff --git a/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderServiceImpl.java b/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderServiceImpl.java
deleted file mode 100644
index 3f9c9781b3..0000000000
--- a/spring-web/src/test/java/org/springframework/remoting/jaxws/OrderServiceImpl.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2002-2012 the original author or authors.
- *
- * Licensed 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
- *
- * https://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.springframework.remoting.jaxws;
-
-import javax.annotation.Resource;
-import javax.jws.WebService;
-import javax.xml.ws.WebServiceContext;
-
-import org.springframework.util.Assert;
-
-/**
- * @author Juergen Hoeller
- */
-@WebService(serviceName="OrderService", portName="OrderService",
- endpointInterface = "org.springframework.remoting.jaxws.OrderService")
-public class OrderServiceImpl implements OrderService {
-
- @Resource
- private WebServiceContext webServiceContext;
-
- @Override
- public String getOrder(int id) throws OrderNotFoundException {
- Assert.notNull(this.webServiceContext, "WebServiceContext has not been injected");
- if (id == 0) {
- throw new OrderNotFoundException("Order 0 not found");
- }
- return "order " + id;
- }
-
-}