This commit ensure that null-safety is consistent between
getters and setters in order to be able to provide beans
with properties with a common type when type safety is
taken in account like with Kotlin.
It also add a few missing property level @Nullable
annotations.
Issue: SPR-15792
This commits extends nullability declarations to the field level, formalizing the interaction between methods and their underlying fields and therefore avoiding any nullability mismatch.
Issue: SPR-15720
Beyond just formally declaring the current behavior, this revision actually enforces non-null behavior in selected signatures now, not tolerating null values anymore when not explicitly documented. It also changes some utility methods with historic null-in/null-out tolerance towards enforced non-null return values, making them a proper citizen in non-null assignments.
Some issues are left as to-do: in particular a thorough revision of spring-test, and a few tests with unclear failures (ignored as "TODO: NULLABLE") to be sorted out in a follow-up commit.
Issue: SPR-15540
This commit introduces 2 new @Nullable and @NonNullApi
annotations that leverage JSR 305 (dormant but available via
Findbugs jsr305 dependency and already used by libraries
like OkHttp) meta-annotations to specify explicitly
null-safety of Spring Framework parameters and return values.
In order to avoid adding too much annotations, the
default is set at package level with @NonNullApi and
@Nullable annotations are added when needed at parameter or
return value level. These annotations are intended to be used
on Spring Framework itself but also by other Spring projects.
@Nullable annotations have been introduced based on Javadoc
and search of patterns like "return null;". It is expected that
nullability of Spring Framework API will be polished with
complementary commits.
In practice, this will make the whole Spring Framework API
null-safe for Kotlin projects (when KT-10942 will be fixed)
since Kotlin will be able to leverage these annotations to
know if a parameter or a return value is nullable or not. But
this is also useful for Java developers as well since IntelliJ
IDEA, for example, also understands these annotations to
generate warnings when unsafe nullable usages are detected.
Issue: SPR-15540
This commit introduces QosSettings that gather the Qualify of Service
settings one can use when sending a message. Such object can now be
associated to any JMS endpoint that allows to send a reply as part of
the processing of an incoming message.
Issue: SPR-15408
String with version 5 the name of Java Platform, Enterprise Edition
changed from J2EE to Java EE. However a lot of the documentation still
uses the term J2EE.
This commit includes the following changes:
* replace J2EE with Java EE where appropriate
This is not a blind search and replace. The following occurrences
remain unchanged:
* references to old J2EE releases, most notably 1.3 and 1.4.
* references to "Expert One-On-One J2EE Design and Development"
* references to "Core J2EE patterns"
* XML namespaces
* package names
Issue: SPR-14811
See gh-1206
This commit adds a test runtime dependency on log4j 2 for every project
and migrates all log4j.properties files to log4j2-test.xml files.
Issue: SPR-14431
This commit fixes MessagingMessageConverter to no longer expose the lazy
message resolution algorithm. This restores proper behaviour for
converters used outside of that context.
Instead, such arrangement is now private to
AbstractAdaptableMessageListener (as it should).
Issue: SPR-14389
The test failure was caused by the previous commit. The Message
resolver now supports payload conversion so it can raise a
MessageConversionException, not MethodArgumentTypeMismatchException.
Support of @JsonView on @JmsListener annotated method that uses the
jackson converter. Also update MappingJackson2MessageConverter to offer
a public API to set the JSON view to use to serialize a payload.
Issue: SPR-13237
Previously, any `javax.jms.Message` was converted eagerly to the Message
abstraction. This leads to unnecessary conversion if the Payload is not
requested by the underlying method (i.e. if the `javax.jms.Message` is
injected directly).
This commit returns a `Message` implementation that holds the
`javax.jms.Message` and lazily resolve the payload or the headers on
demand (that is the first time they are requested).
Issue: SPR-13777
This commit migrates all remaining tests from JUnit 3 to JUnit 4, with
the exception of Spring's legacy JUnit 3.8 based testing framework that
is still in use in the spring-orm module.
Issue: SPR-13514
Previously, a method could only declare one Jms endpoint so if several
destinations share the exact same business logic, you'd still need one
separate method declaration per destination.
We now make sure that JmsListener is a repeatable annotation, introducing
JmsListeners for pre Java8 use cases.
Issue: SPR-13147
Add JmsResponse that can be used as return type of any JMS listener
method to indicate not only the response but also the actual destination
to which the reply should be sent.
Issue: SPR-13133
If a custom MessageConverter is set, it is not used for replies defined
via the Message abstraction. This commit harmonizes the behaviour of the
`MessagingMessageConverter` so that the conversion of the payload can
be converted for both incoming and outgoing messages.
Issue: SPR-12912
Previously, a custom `DestinationResolver` was not made available
to the underlying `MessageListener`: if a reply needs to be sent, the
default `DestinationResolver` was used.
This commit ensures that if a custom `DestinationResolver` has been set,
it is also configured accordingly for replies.
Issue: SPR-12927
The attributes of @JmsListener allows to specify the reference to a key
in the Environment but @SendTo did not.
This commit fixes this inconsistency so that response destinations are
now also externally configurable.
Issue: SPR-12899
Previously, the "pubSubDomain" drove the resolution of both the
destination of the listener and the default response destination.
A new "replyPubSubDomain" attribute has been added on the base listener
and can be used to listen on a topic and reply to a queue (or vice
versa). The attribute is exposed via the "response-destination-type" XML
attribute on the listener container element. It is also available on the
JmsListenerContainerFactory for use with the @JmsListener infrastructure.
Issue: SPR-12911
The auto startup flag can now be set on a JmsListenerContainerFactory to
control if the created container should be started automatically when the
application context starts.
Issue: SPR-12824
Previously, adding `@EnableAsync` on a blank application would lead to an
info message stating that `ProxyAsyncConfiguration` is not eligible for
getting processed by all BeanPostProcessors. Concretely, this is ok as
such internal configuration is not meant to be a target of such post
processing.
Revisit the condition for non infrastructure bean only. Add the
infrastructure role to a set of internal configuration, including the
`ProxyAsyncConfiguration`.
Issue: SPR-12761
Support the creation and registration of message listener containers in
a lazy manner, that is after the container initialization has completed.
Such support brought an interesting brainstorming of the thread safety
if JmsListenerEndpointRegistrar and JmsListenerEndpointRegistry so those
have also been revisited as part of this commit.
Issue: SPR-12774
Reduce logging level when no target annotation is found a on bean. For
consistency, update ScheduledAnnotationBeanPostProcessor and
JmsListenerAnnotationBeanPostProcessor that define the same log
statement.
Issue: SPR-12574
JmsInvokerClientInterceptor defines a receiveTimeout field but does not
handle such timeout. This commit adds an additional callback that throws
an RemoteTimeoutException instead.
Sub-classes can override the onReceiveTimeout to throw a different
exception or return a fallback RemoteInvocationResult.
Issue: SPR-12731
Previously, the default reply destination could not be discovered if the
@JmsListener annotation was placed on a bean that is eligible for
proxying as the proxy method is used internally and does not reveal
an annotation placed on the implementation.
This commit makes sure to resolve the most specific method when
searching that annotation.
Issue: SPR-12513
With this commit, Jackson builder is now used in spring-websocket
to create the ObjectMapper instance.
It is not possible to use the builder for spring-messaging
and spring-jms since these modules don't have a dependency on
spring-web, thus they now just customize the same features:
- MapperFeature#DEFAULT_VIEW_INCLUSION is disabled
- DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES is disabled
Issue: SPR-12293
Commit 6a04831 introduced a regression that lead to burst recovery
attempts when the broker is up but the listener is failing for some
reason (the most obvious one being that the destination does not
exist).
Since the sleep period between recovery attempts strategy is more
complex, we can't just sleep for a period of time. But we can create
an execution and apply it once which should work just fine for most
use cases.
Issue: SPR-12183
This commit allows to use place holder definitions for JmsListener
attributes, effectively allowing to externalize those settings from
the code.
Issue: SPR-12134
This commit also turns MessagingException into a NestedRuntimeException subclass which delivers a root message that has the cause message appended to it. That's a common expectation with the use of Spring exceptions since all of our exception hierarchies have historically been designed that way.
Issue: SPR-12064
Issue: SPR-12038
This commit moves JmsHandlerMethodFactory and its default
implementation to the messaging abstraction. Working on a similar
support for AMQP revealed that this factory has nothing that is JMS
specific and is exactly identical in the case of AMQP.
Issue: SPR-12053
This commit introduces MessagingExceptionTranslator, a messaging
exception translation infrastructure similar to what
PersistenceExceptionTranslator provides.
JmsMessagingTemplate does not throw raw JmsException anymore but
translates those to an instance of Spring's MessagingException
hierarchy.
Issue: SPR-12038
This commit updates JmsMessagingTemplate to support the
MessageRequestReplyOperation interface that provides synchronous
request/reply operations.
As JmsMessagingTemplate delegates everything under the scenes to
JmsTemplate, the latter has been updated as well to offer such lower
level operation.
Issue: SPR-12037
Prior to this commit, customizing the concurrency to use fo a given JMS
listener involved to define it in a specific listener-container. As
this is quite restrictive, users may stop using the XML namespace
support altogether to fallback on regular abstract bean definition for
the container.
This commit adds a concurrency attribute to the jms and jca listener
element as well as on the @JmsListener annotation. If the value is set,
it takes precedence; otherwise the value provided by the factory is
used.
Issue: SPR-11988
This commit supports two additional methods of the MessageProducer
interface as from JMS 2.0
An integration test infrastructure is necessary to be able to test
those scenario: this is taken care of in a separated initiative.
Issue: SPR-11950
Prior to this commit, no exception was raised if a message could not
be converted to the requested payload because no suitable converter
were found.
This commit adds an explicit check if the converted payload is null.
Issue: SPR-11817
Eclipse 4.4 early release versions have issues with generics.
This commit slightly tweaks the use of generics in
JmsMessagingTemplateTests so that the class compiles in the latest
builds of Eclipse 4.4
This commit revisits JmsMessagingTemplate and adds support for
receiving operations as well. JmsMessageSendingOperations has been
renamed to JmsMessageOperations.
The messaging abstraction did not split receiving and request-reply
operations. AbstractMessageReceivingTemplate has been created to hold
only the receiving operations.
Issue: SPR-11772
This commit adds a JMS implementation of MessageSendingOperations,
allowing to send JMS messages using Spring's standard Messaging
abstraction.
MessagingMessageConverter is a standard JMS's MessageConverter that
can convert Spring's Message to JMS message and vice versa. Existing
infrastructure has been updated to use this implementation.
Issue: SPR-11772
This commit avoids throwing JMSException from the listener execution
as this is not allowed per spec. Our SessionAwareMessageListener
gives a callback that can throw JMSException and we have "abused" it
so far.
Typical message processing goes in those 3 steps:
* Unmarshall the javax.jms.Message to the requested type
* Invoke the actual user method (including processing of method
arguments)
* Send a reply message, if any
Those three steps have been harmonized so that they don't throw a
JMSException anymore. For the later case, introduced
ReplyFailureException as a general exception indicating the
reply message could not have been sent.
Issue: SPR-11778
This commit adds an explicit error message when the BackOff instance
has returned BackOffExecution#STOP which basically means that no
further attempts are allowed.
This error message is a convenience way to notify that the container is
about to be shut down.
Issue: SPR-11746
This commit separates the BackOff configuration from an actual
execution. BackOffExecution now contains all the state of a
particular execution and BackOff is only meant to start (i.e.
create) a new execution.
The method "reset" has been removed as its no longer necessary:
when an execution does not need to be used for a given operation
anymore it can be simply discarded.
Issue: SPR-11746
This commit adds a "back-off" attribute to the jms:listener-container
element so that a BackOff instance can be provided for users of the
XML namespace.
Issue: SPR-11746
Prior to this commit, DefaultMessageListenerContainer was recovering
on failure using a fixed time interval, potentially in an infinite way.
This commit adds an extra "backoff" property to the container that
permits to fine tune the recovery interval using a BackOff instance.
FixedBackOff provides a fixed interval between two attempts and a
maximum number of retries. ExponentialBackOff increases an initial
interval until a maximum interval has been reached. A BackOff instance
can return a special "STOP" time value that indicates that no further
attemps should be made. DefaultMessageListenerContainer uses this
value to stop the container.
protected method "sleepInbetweenRecoveryAttempts" has been renamed
to "applyBackOff" and now returns a boolean that indicate if the
back off has been applied and a new attempt should now be made.
Issue: SPR-11746
This commit removes the queue attribute of the JmsListener annotation
as this information should be provided by the container factory and not
by each individual listener endpoints.
There was a side effect that an annotation value cannot be null, which
was forcing the container to be a queue-based container by default.
Issue: SPR-9882
This commit replaces the "responseDestination" attribute on the
JmsListener annotation by a support of the standard SendTo annotation.
Issue: SPR-11707
Prior to this commit, the default JmsListenerContainerFactory to use
must be explicitly set. Since having a single container factory is a
fairly common use case, we look up the default one automatically
using the bean name "jmsListenerContainerFactory".
It is still possible to provide an explicit default but since it refers
more to "the" container factory to use, the parameter has been
renamed to "containerFactory" which is shorter and more explicit.
The lookup strategy is lazy: if all endpoints are providing an
explicit container factory and no container factory with the
"jmsListenerContainerFactory" bean name exists, no exception
will be thrown.
Issue : SPR-11706
Clean up compiler warnings in the tests of spring-jms. This commit
adds type parameters to all the types (mostly `List` and `Map`).
I am not too sure about the `Map` type parameters in
`MessageContentsDelegate` and `ResponsiveMessageDelegate` however the
respective methods seem unused.
This commit adds the support of JMS annotated endpoint. Can be
activated both by @EnableJms or <jms:annotation-driven/> and
detects methods of managed beans annotated with @JmsListener,
either directly or through a meta-annotation.
Containers are created and managed under the cover by a registry
at application startup time. Container creation is delegated to a
JmsListenerContainerFactory that is identified by the containerFactory
attribute of the JmsListener annotation. Containers can be
retrieved from the registry using a custom id that can be specified
directly on the annotation.
A "factory-id" attribute is available on the container element of
the XML namespace. When it is present, the configuration defined at
the namespace level is used to build a JmsListenerContainerFactory
that is exposed with the value of the "factory-id" attribute. This can
be used as a smooth migration path for users having listener containers
defined at the namespace level. It is also possible to migrate all
listeners to annotated endpoints and yet keep the
<jms:listener-container> or <jms:jca-listener-container> element to
share the container configuration.
The configuration can be fine-tuned by implementing the
JmsListenerConfigurer interface which gives access to the registrar
used to register endpoints. This includes a programmatic registration
of endpoints in complement to the declarative approach. A default
JmsListenerContainerFactory can also be specified to be used if no
containerFactory has been set on the annotation.
Annotated methods can have flexible method arguments that are similar
to what @MessageMapping provides. In particular, jms listener endpoint
methods can fully use the messaging abstraction, including convenient
header accessors. It is also possible to inject the raw
javax.jms.Message and the Session for more advanced use cases. The
payload can be injected as long as the conversion service is able to
convert it from the original type of the JMS payload. By
default, a DefaultJmsHandlerMethodFactory is used but it can be
configured further to support additional method arguments or to
customize conversion and validation support.
The return type of an annotated method can also be an instance of
Spring's Message abstraction. Instead of just converting the payload,
such response type allows to communicate standard and custom headers.
The JmsHeaderMapper infrastructure from Spring integration has also
been migrated to the Spring framework. SimpleJmsHeaderMapper is based
on SI's DefaultJmsHeaderMapper. The simple implementation maps all
JMS headers so that the generated Message abstraction has all the
information stored in the protocol specific message.
Issue: SPR-9882
Prior to this commit, the codebase was using a mix of log4j.xml
and log4j.properties for test-related logging configuration. This
can be an issue as log4j takes the xml variant first when looking
for a default bootstrap configuration.
In practice, some modules declaring the properties variant were
taking the xml variant configuration from another module.
The general structure of the configuration has also been
harmonized to provide a standard console output as well as an
easy way to enable trace logs for the current module.
Fix a variety of typos throughout the project, primarily in
comments (javadoc or otherwise) but also in a handful of log messages
and a couple exception messages.
ISSUE: SPR-11123
Fix remaining Java compiler warnings, mainly around missing
generics or deprecated code.
Also add the `-Werror` compiler option to ensure that any future
warnings will fail the build.
Issue: SPR-11064
This fine-tuned change restores the original Spring 3.0 behavior for Oracle AQ, and also allows for other ConnectionFactory types to comply with the "getDataSource()" pattern.
Issue: SPR-10829