diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java b/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java index d58a44bf849..948cf9c78d0 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java @@ -63,6 +63,11 @@ import org.springframework.util.ObjectUtils; * lead to queue/topic mode, respectively; generic {@code createConnection} * calls will lead to a JMS 1.1 connection which is able to serve both modes. * + *

As of Spring Framework 5, this class supports JMS 2.0 {@code JMSContext} + * calls and therefore requires the JMS 2.0 API to be present at runtime. + * It may nevertheless run against a JMS 1.1 driver (bound to the JMS 2.0 API) + * as long as no actual JMS 2.0 calls are triggered by the application's setup. + * *

NOTE: This ConnectionFactory requires explicit closing of all Sessions * obtained from its shared Connection. This is the usual recommendation for * native JMS access code anyway. However, with this ConnectionFactory, its use diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/DelegatingConnectionFactory.java b/spring-jms/src/main/java/org/springframework/jms/connection/DelegatingConnectionFactory.java index eb3c2c94816..6479e675fde 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/DelegatingConnectionFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/DelegatingConnectionFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * 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. @@ -36,6 +36,11 @@ import org.springframework.util.Assert; * if necessary (e.g. when running JMS 1.0.2 API based code against a generic * JMS 1.1 ConnectionFactory, such as ActiveMQ's PooledConnectionFactory). * + *

As of Spring Framework 5, this class supports JMS 2.0 {@code JMSContext} + * calls and therefore requires the JMS 2.0 API to be present at runtime. + * It may nevertheless run against a JMS 1.1 driver (bound to the JMS 2.0 API) + * as long as no actual JMS 2.0 calls are triggered by the application's setup. + * *

This class allows for being subclassed, with subclasses overriding only * those methods (such as {@link #createConnection()}) that should not simply * delegate to the target ConnectionFactory. diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java b/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java index bb4fa8cd5f8..7e8f7fb1e42 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/SingleConnectionFactory.java @@ -61,6 +61,11 @@ import org.springframework.util.ClassUtils; * lead to queue/topic mode, respectively; generic {@code createConnection} * calls will lead to a JMS 1.1 connection which is able to serve both modes. * + *

As of Spring Framework 5, this class supports JMS 2.0 {@code JMSContext} + * calls and therefore requires the JMS 2.0 API to be present at runtime. + * It may nevertheless run against a JMS 1.1 driver (bound to the JMS 2.0 API) + * as long as no actual JMS 2.0 calls are triggered by the application's setup. + * *

Useful for testing and standalone environments in order to keep using the * same Connection for multiple {@link org.springframework.jms.core.JmsTemplate} * calls, without having a pooling ConnectionFactory underneath. This may span diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/TransactionAwareConnectionFactoryProxy.java b/spring-jms/src/main/java/org/springframework/jms/connection/TransactionAwareConnectionFactoryProxy.java index 6b096569c8d..f4eb2fdb42f 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/TransactionAwareConnectionFactoryProxy.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/TransactionAwareConnectionFactoryProxy.java @@ -72,6 +72,11 @@ import org.springframework.util.ClassUtils; * (e.g. to perform manual transaction control). For typical application purposes, * simply use the standard JMS Session interface. * + *

As of Spring Framework 5, this class delegates JMS 2.0 {@code JMSContext} + * calls and therefore requires the JMS 2.0 API to be present at runtime. + * It may nevertheless run against a JMS 1.1 driver (bound to the JMS 2.0 API) + * as long as no actual JMS 2.0 calls are triggered by the application's setup. + * * @author Juergen Hoeller * @since 2.0 * @see UserCredentialsConnectionFactoryAdapter diff --git a/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java b/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java index 6b2ab0d12db..688d1158bfc 100644 --- a/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java +++ b/spring-jms/src/main/java/org/springframework/jms/connection/UserCredentialsConnectionFactoryAdapter.java @@ -63,6 +63,11 @@ import org.springframework.util.StringUtils; * definition just for the option of implicitly passing in user credentials * if the particular target ConnectionFactory requires it. * + *

As of Spring Framework 5, this class delegates JMS 2.0 {@code JMSContext} + * calls and therefore requires the JMS 2.0 API to be present at runtime. + * It may nevertheless run against a JMS 1.1 driver (bound to the JMS 2.0 API) + * as long as no actual JMS 2.0 calls are triggered by the application's setup. + * * @author Juergen Hoeller * @since 1.2 * @see #createConnection diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index c7168f8d83a..6ce8b51cc3e 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -24,17 +24,16 @@ usual (Spring) POJOs. Currently, Spring supports the following remoting technolo * *Remote Method Invocation (RMI)*: Through the use of `RmiProxyFactoryBean` and `RmiServiceExporter`, Spring supports both traditional RMI (with `java.rmi.Remote` - interfaces and `java.rmi.RemoteException`) and transparent remoting through RMI invokers - (with any Java interface). + interfaces and `java.rmi.RemoteException`) and transparent remoting through RMI + invokers (with any Java interface). * *Spring's HTTP invoker*: Spring provides a special remoting strategy that allows for Java serialization though HTTP, supporting any Java interface (as the RMI - invoker does). The corresponding support classes are `HttpInvokerProxyFactoryBean` and - `HttpInvokerServiceExporter`. + invoker does). The corresponding support classes are `HttpInvokerProxyFactoryBean` + and `HttpInvokerServiceExporter`. * *Hessian*: By using Spring's `HessianProxyFactoryBean` and the `HessianServiceExporter`, you can transparently expose your services through the lightweight binary HTTP-based protocol provided by Caucho. -* *JAX-WS*: Spring provides remoting support for web services through JAX-WS (the - successor of JAX-RPC, as introduced in Java EE 5 and Java 6). +* *JAX-WS*: Spring provides remoting support for web services through JAX-WS. * *JMS*: Remoting by using JMS as the underlying protocol is supported through the `JmsInvokerServiceExporter` and `JmsInvokerProxyFactoryBean` classes. * *AMQP*: Remoting by using AMQP as the underlying protocol is supported by the Spring @@ -627,7 +626,6 @@ and Spring's `@Autowired` configuration annotation is still honored): public List getAccounts(String name) { return biz.getAccounts(name); } - } ---- ==== @@ -732,8 +730,8 @@ accordingly first. Check the JAX-WS documentation for details on those requireme [[remoting-jms]] === Exposing Services through JMS -You can also expose services transparently by using JMS as the underlying -communication protocol. The JMS remoting support in the Spring Framework is pretty basic. +You can also expose services transparently by using JMS as the underlying communication +protocol. The JMS remoting support in the Spring Framework is pretty basic. It sends and receives on the `same thread` and in the same non-transactional `Session`. As a result, throughput is implementation-dependent. Note that these single-threaded and non-transactional constraints apply only to Spring's JMS @@ -751,7 +749,6 @@ The following interface is used on both the server and the client sides: public interface CheckingAccountService { public void cancelAccount(Long accountId); - } ---- ==== @@ -769,13 +766,12 @@ The following simple implementation of the preceding interface is used on the se public void cancelAccount(Long accountId) { System.out.println("Cancelling account [" + accountId + "]"); } - } ---- ==== -The following configuration file contains the JMS-infrastructure beans that are shared on both -the client and server: +The following configuration file contains the JMS-infrastructure beans that are shared +on both the client and the server: ==== [source,xml,indent=0] @@ -846,7 +842,6 @@ On the server, you need to expose the service object that uses the public static void main(String[] args) throws Exception { new ClassPathXmlApplicationContext(new String[]{"com/foo/server.xml", "com/foo/jms.xml"}); } - } ---- ==== @@ -897,7 +892,6 @@ proxy takes care of forwarding the call to the server-side object via JMS): CheckingAccountService service = (CheckingAccountService) ctx.getBean("checkingAccountService"); service.cancelAccount(new Long(10)); } - } ---- ==== @@ -916,8 +910,8 @@ Auto-detection is not implemented for remote interfaces The main reason why auto-detection of implemented interfaces does not occur for remote interfaces is to avoid opening too many doors to remote callers. The target object might -implement internal callback interfaces, such as `InitializingBean` or `DisposableBean`, which -one would not want to expose to callers. +implement internal callback interfaces, such as `InitializingBean` or `DisposableBean` +which one would not want to expose to callers. Offering a proxy with all interfaces implemented by the target usually does not matter in the local case. However, when you export a remote service, you should expose a specific @@ -936,13 +930,13 @@ effort and puts you on the safe side regarding controlled exposure of specific m [[remoting-considerations]] === Considerations when Choosing a Technology -Each and every technology presented here has its drawbacks. When choosing a technology, you should carefully -consider your needs, the services you expose, and the objects you send -over the wire. +Each and every technology presented here has its drawbacks. When choosing a technology, +you should carefully consider your needs, the services you expose, and the objects you +send over the wire. When using RMI, you cannot access the objects through the HTTP protocol, -unless you tunnel the RMI traffic. RMI is a fairly heavy-weight protocol, in that -it supports full-object serialization, which is important when you use a complex data model +unless you tunnel the RMI traffic. RMI is a fairly heavy-weight protocol, in that it +supports full-object serialization, which is important when you use a complex data model that needs serialization over the wire. However, RMI-JRMP is tied to Java clients. It is a Java-to-Java remoting solution. @@ -967,8 +961,8 @@ technologies. Last but not least, EJB has an advantage over RMI, in that it supports standard role-based authentication and authorization and remote transaction propagation. It is possible to get RMI invokers or HTTP invokers to support security context propagation as -well, although this is not provided by core Spring. Spring offers only appropriate hooks for -plugging in third-party or custom solutions. +well, although this is not provided by core Spring. Spring offers only appropriate hooks +for plugging in third-party or custom solutions. @@ -1608,6 +1602,19 @@ implementation of Spring's `PlatformTransactionManager` for JMS (the cunningly n `JmsTransactionManager`). This allows for seamless integration of JMS as a transactional resource into Spring's transaction management mechanisms. +[NOTE] +==== +As of Spring Framework 5, Spring's JMS package fully supports JMS 2.0 and requires the +JMS 2.0 API to be present at runtime. We recommend the use of a JMS 2.0 compatible provider. + +If you happen to use an older message broker in your system, you may try upgrading to a +JMS 2.0 compatible driver for your existing broker generation. Alternatively, you may also +try to run against a JMS 1.1 based driver, simply putting the JMS 2.0 API jar on the +classpath but only using JMS 1.1 compatible API against your driver. Spring's JMS support +adheres to JMS 1.1 conventions by default, so with corresponding configuration it does +support such a scenario. However, please consider this for transition scenarios only. +==== + [[jms-using]]