Even though the Javadoc for Constants#toCode and #toCodeForSuffix
specifies that a null value for the 'namePrefix' and 'nameSuffix'
parameters are respectively allowed, before this change passing a null
to either would result in a NullPointerException.
This change fixes constant name lookup for null values of these params
as if an empty string had been passed instead. This way of handling a
null value is consistent with the rest of Constants class API.
Issue: SPR-8278
Before this change JibxMarshallerTests would fail on Windows with an
error message explaining that JiBX compiler generated classes are not
found on the classpath for binding with name 'binding'. Tests would
execute well on Linux and OS X.
Actual root cause of this bug is found to be in JiBX 1.1.5 release that
is used to build Spring. The binding name can be explicitly specified in
JiBX binding file. If omitted, when generating classes the JiBX compiler
as fall-back mechanism tries to derive the binding name from the binding
file name. That logic had a bug which gets manifested when configured
binding file path has mixed Windows and *nix style file separators, as
in case of JibxMarshallerTests being executed on a Windows platform.
This commit resolves this issue by upgrading Spring's build from JiBX
1.1.5 to 1.2.3, as the bug mentioned was fixed in JiBX 1.2. See JIBX-441
for more details.
Issue: SPR-8360
Before this fix ReflectivePropertyAccessor was not able to find write
method for valid property name that has first character in lower case
and second character in upper case. Write method lookup would always
convert first character of property name to upper case which is not
compliant with JavaBean specification. As consequence this caused an
unwanted behavior in SpEL when obtaining values of expressions that
reference such JavaBean properties.
As of this change, write method lookup skips conversion of property
name first character to upper case when property name is longer than
one character and second character is in upper case. This also fixes
mentioned bug in SpEL value resolution.
Issue: SPR-9123
Previously, if the resolution of a ${...} placeholder resulted in a
valid URL for the location of a log4j properties/XML file, the URL
would ultimately be malformed by an unnecessary call to to
WebUtils#getRealPath.
The implementation of Log4jWebConfigurer#initLogging now eagerly
attempts SystemPropertyUtils#resolvePlaceholders before checking to see
if the location is a valid URL, and bypassing the call to
WebUtils#getRealPath if so.
Issue: SPR-9417
Previously, StringUtils#parseLocaleString would parse locale strings
having the same lowercase token for both language and country
incorrectly, e.g. 'tr_tr' would parse to 'tr_TR_tr' as opposed to the
expected 'tr_TR'.
This commit fixes this behavior by using using String#lastIndexOf
instead of String#indexOf when determining the location of the country
code token.
Issue: SPR-9420
Updated the class-level JavaDoc for @Bean to better explain the
semantics of 'lite' mode.
Renamed "Configuration Class Lite Mode" to "@Bean Lite Mode".
Added discussion of @DependsOn to the class-level JavaDoc.
Issue: SPR-9401
In AnnotationUtils#findAnnotation(Method, Class), the search for a
method annotation fails if:
- the original method does not have the annotation
- an abstract superclass does not have an equivalent method declared
- an interface implemented by the superclass has the method and
the annotation -> this should be found, but is not!
This happens because the try-catch block in #findAnnotation is too wide:
cl.getDeclaredMethod() can throw NoSuchMethodException and skip the
'#searchOnInterfaces' call prematurely.
The try-catch block was made narrower to allow #searchOnInterfaces to
be called even if the abstract class does not have the method declared
at all.
Issue: SPR-9342
Overhauled the class-level JavaDoc in @Bean:
- added h3 headers for greater clarity and readability
- mentioned 'prototype' semantics for lite mode
Issue: SPR-9401
Prior to this change, Spring's MethodParameter#getParameterAnnotations
called java.lang.Method#getParameterAnnotations on every invocation.
The latter ends up contending for a monitor inside (Sun) JDK code. This
is problematic when dealing with the high number of @RequestMapping
invocations that can occur in a Spring MVC @Controller.
This commit eliminates this contention by caching values returned by
java.lang.Method#getParameterAnnotations in a static ConcurrentMap.
Note that only Method parameter annotations are cached, while
Constructor parameter annotations are not. This is because the
issue of primary concern is, as mentioned above, @RequestMapping
methods. By nature, constructors are called much more infrequently, and
in most cases in a single-threaded fashion.
Issue: SPR-9298
InjectionMetadata and LifecycleMetadata can end up having mostly empty
instance variables. In such cases memory usage can be improved a little
bit.
This patch addresses this in two ways:
- Creating a LinkedHashSet of the "right" size, the default capacity
is 16 but the exact capacity needed is known in advance.
- If the argument is empty then use Collections#emptySet which is a
constant so no additional memory is used. Since it's immutable there
is no need for the Collections#synchronizedSet wrapper.
Issue: SPR-9264
Prior to this change, AABPP#determineRequiredStatus never checked the
return value of ReflectionUtils#findMethod when searching for a
'#required' attribute. This call returns null for annotations such as
@Inject, @Value and @Resource, and subsequently causes a
NullPointerException to be thrown when ReflectionUtils#invokeMethod is
called. The NPE is caught immediately and #determineRequiredStatus
returns defaulting to true, but this this approach is inefficient. It
is also problematic for users who have set breakpoints on NPE -- they
end up debugging into Spring internals, which is a false positive.
This commit checks the return value of of ReflectionUtils#findMethod,
and in the case of null, eagerly returns true. There is no change to
external behavior, simply a more efficient and debugging-friendly
implementation.
Existing test cases already cover this change, given that it is purely
a refactoring.
Issue: SPR-9316
AbstractTransactionalAnnotatedConfigClassTests is now annotated with
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) so
that side-effects between tests are avoided.
Re-enabled TransactionalAnnotatedConfigClassWithAtConfigurationTests
and TransactionalAnnotatedConfigClassesWithoutAtConfigurationTests.
Also introduced a log4j FileAppender for tests that writes to
"build/spring-test.log".
Issue: SPR-9051
MappingJackson2JsonView and MappingJacksonJsonView now provide an
option that will set the Content-Length header of JSON responses.
Use of the option implies buffering of the response and it must be
enabled explicitly.
Issue: SPR-7866
This change makes it possible to provide a custom MessageCodesResolver
through the MVC Java config whether using @EnableWebMvc and extending
WebMVcConfigurerAdapter or sub-classing directly from
WebMvcConfigurationSupport.
Issue: SPR-9223
The claim: given an integration test class that is annotated with
@ContextConfiguration and declares a configuration class that is missing
an @Configuration annotation, if a transactional test method (i.e., one
annotated with @Transactional) changes the state of the database then
the
changes will not be rolled back as would be expected with the default
rollback semantics of the Spring TestContext Framework (TCF).
TransactionalAnnotatedConfigClassWithAtConfigurationTests is a concrete
implementation of AbstractTransactionalAnnotatedConfigClassTests that
uses
a true @Configuration class and thereby demonstrates the expected
behavior
of such transactional tests with automatic rollback.
TransactionalAnnotatedConfigClassesWithoutAtConfigurationTests is a
concrete implementation of
AbstractTransactionalAnnotatedConfigClassTests
that does NOT use a true @Configuration class but rather a 'lite mode'
configuration class (see the Javadoc for @Bean for details).
Using such a 'lite mode' configuration class results in the following:
- Its @Bean methods act as factory methods instead of singleton beans.
- The dataSource() method is invoked multiple times instead of once.
- The test instance and the TCF operate on different data sources.
- The transaction managed (and rolled back) by the TCF is not the
transaction that the application code or test instance uses.
Ultimately, the use of a 'lite mode' configuration class gives the false
appearance that there is a bug in the TCF (in that the transaction is
not
rolled back); however, the transaction managed by the TCF is in fact
rolled back.
In conclusion, these tests demonstrate both the intended behavior of the
TCF and the fact that using 'lite mode' configuration classes can lead
to
confusing results (both in tests and production code).
Issue: SPR-9051
SPR-7680 added QueryTimeoutException to Spring's DataAccessException
hierarchy, but did not integrate it into the
SQLExceptionSubclassTranslator; it was added mainly to accomodate users
defining their own custom exception translators.
However, it does make sense to translate any SQLTimeoutException to this
new QueryTimeoutException type, and this commit makes that change. It
does represent a slight backward-incompatibility, given that
QueryTimeoutException extends TransientDataAccessException, whereas
SQLExceptionSubclassTranslator previously returned the more specific
TransientDataAccessResourceException for any SQLTimeoutException.
It is expected that this incompatibily will be very low-impact, i.e. not
affecting many (if any) users. In any case, a major release (Spring 3.2)
is the right time to introduce such a change, and the migration path is
straightforward: any users depending on catching
TransientDataAccessResourceException in the case of query timeouts
should update those catch blocks to expect QueryTimeoutException
instead. Care should also be taken to ensure correctness of existing
catch blocks expecting TransientDataAccessException, as these blocks
will now catch QueryTimeoutException as well.
Issue: SPR-9376, SPR-7680
SPR-7591 introduced a java.nio.charset.Charset field within
HttpStatusCodeException. The former is non-serializable, thus by
extension the latter also became non-serializable.
Because the Charset field is only used for outputting the charset name
in HttpStatusCodeException#getResponseBodyAsString, it is reasonable to
store the value returned by Charset#name() instead of the actual Charset
object itself.
This commit refactors HttpStatusCodeException's responseCharset field to
be of type String instead of Charset and adds tests to prove that
HttpStatusCodeException objects are once again serializable as expected.
Issue: SPR-9273, SPR-7591
The new property can be used to ignore specific exceptions that may
otherwise be matched by the "exceptionMappings" property or resolved
through the defaultErrorView.
Issue: SPR-5193
It was claimed that when a {@code @ContextConfiguration} test class
references a config class missing an {@code @Configuration} annotation,
@Bean dependencies are wired successfully but the bean lifecycle is not
applied (no init methods are invoked, for example).
AnnotatedConfigClassesWithoutAtConfigurationTests refutes this claim by
demonstrating that @Bean methods in non-@Configuration classes are
properly handled as "annotated factory bean methods" and that lifecycle
callbacks in fact apply to such factory beans.
Issue: SPR-9051
When @ResponseStatus has a reason and servletResponse.sendError() is
called, the response is committed and should no longer be written to.
After this change, the ServletInvocableHandlerMethod will mark the
response fully handled and will ignore any non-null return values.
Issue: SPR-9159