From 209c8505e661cb77678ac4cd7f6e8b157e782e89 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 20 Jul 2019 16:10:49 +0200 Subject: [PATCH 1/3] Align forRawClassAssignableFromTypeVariable with 5.1 assertion style See gh-23321 --- .../core/ResolvableTypeTests.java | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java b/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java index f4a4490da25..58421740df0 100644 --- a/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java +++ b/spring-core/src/test/java/org/springframework/core/ResolvableTypeTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * 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. @@ -135,41 +135,41 @@ public class ResolvableTypeTests { assertTrue(type.isAssignableFrom(String.class)); } - @Test - public void forRawClassAssignableFromTypeVariable() { // gh-23321 + @Test // gh-23321 + public void forRawClassAssignableFromTypeVariable() throws Exception { ResolvableType typeVariable = ResolvableType.forClass(ExtendsList.class).as(List.class).getGeneric(); ResolvableType raw = ResolvableType.forRawClass(CharSequence.class); - assertThat(raw.resolve()).isEqualTo(CharSequence.class); - assertThat(typeVariable.resolve()).isEqualTo(CharSequence.class); - assertThat(raw.resolve().isAssignableFrom(typeVariable.resolve())).isTrue(); - assertThat(typeVariable.resolve().isAssignableFrom(raw.resolve())).isTrue(); - assertThat(raw.isAssignableFrom(typeVariable)).isTrue(); - assertThat(typeVariable.isAssignableFrom(raw)).isTrue(); + assertThat(raw.resolve(), equalTo(CharSequence.class)); + assertThat(typeVariable.resolve(), equalTo(CharSequence.class)); + assertTrue(raw.resolve().isAssignableFrom(typeVariable.resolve())); + assertTrue(typeVariable.resolve().isAssignableFrom(raw.resolve())); + assertTrue(raw.isAssignableFrom(typeVariable)); + assertTrue(typeVariable.isAssignableFrom(raw)); } @Test - public void forInstanceMustNotBeNull() { + public void forInstanceMustNotBeNull() throws Exception { this.thrown.expect(IllegalArgumentException.class); this.thrown.expectMessage("Instance must not be null"); ResolvableType.forInstance(null); } @Test - public void forInstanceNoProvider() { + public void forInstanceNoProvider() throws Exception { ResolvableType type = ResolvableType.forInstance(new Object()); assertThat(type.getType(), equalTo(Object.class)); assertThat(type.resolve(), equalTo(Object.class)); } @Test - public void forInstanceProvider() { + public void forInstanceProvider() throws Exception { ResolvableType type = ResolvableType.forInstance(new MyGenericInterfaceType<>(String.class)); assertThat(type.getRawClass(), equalTo(MyGenericInterfaceType.class)); assertThat(type.getGeneric().resolve(), equalTo(String.class)); } @Test - public void forInstanceProviderNull() { + public void forInstanceProviderNull() throws Exception { ResolvableType type = ResolvableType.forInstance(new MyGenericInterfaceType(null)); assertThat(type.getType(), equalTo(MyGenericInterfaceType.class)); assertThat(type.resolve(), equalTo(MyGenericInterfaceType.class)); @@ -443,12 +443,8 @@ public class ResolvableTypeTests { interfaces.add(interfaceType.toString()); } assertThat(interfaces.toString(), equalTo( - "[" - + "java.io.Serializable, " - + "java.lang.Cloneable, " - + "java.util.List, " - + "java.util.RandomAccess" - + "]")); + "[java.io.Serializable, java.lang.Cloneable, " + + "java.util.List, java.util.RandomAccess]")); } @Test From 4a09b323b6293347289b5122a94bd7b0a4e32917 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 20 Jul 2019 16:11:17 +0200 Subject: [PATCH 2/3] Apply getInterfaceMethodIfPossible without SecurityManager as well Closes gh-23323 --- .../support/AbstractAutowireCapableBeanFactory.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 1fe4f2ebc10..c11bce18655 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -1882,10 +1882,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac if (logger.isTraceEnabled()) { logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'"); } + Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod); if (System.getSecurityManager() != null) { - Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod); - AccessController.doPrivileged((PrivilegedAction) () -> { ReflectionUtils.makeAccessible(methodToInvoke); return null; @@ -1901,8 +1900,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac } else { try { - ReflectionUtils.makeAccessible(initMethod); - initMethod.invoke(bean); + ReflectionUtils.makeAccessible(methodToInvoke); + methodToInvoke.invoke(bean); } catch (InvocationTargetException ex) { throw ex.getTargetException(); From 0d37209b7881f6638fb8b6f84ee7a2eb759b1ca6 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 20 Jul 2019 16:23:31 +0200 Subject: [PATCH 3/3] Document default message handling in MessageSource.getMessage variants --- .../context/MessageSource.java | 44 ++++++++++++------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/context/MessageSource.java b/spring-context/src/main/java/org/springframework/context/MessageSource.java index 6396a016bb1..fb17668689a 100644 --- a/spring-context/src/main/java/org/springframework/context/MessageSource.java +++ b/spring-context/src/main/java/org/springframework/context/MessageSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * 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. @@ -26,10 +26,10 @@ import org.springframework.lang.Nullable; * *

Spring provides two out-of-the-box implementations for production: *

    - *
  • {@link org.springframework.context.support.ResourceBundleMessageSource}, - * built on top of the standard {@link java.util.ResourceBundle} - *
  • {@link org.springframework.context.support.ReloadableResourceBundleMessageSource}, - * being able to reload message definitions without restarting the VM + *
  • {@link org.springframework.context.support.ResourceBundleMessageSource}: built + * on top of the standard {@link java.util.ResourceBundle}, sharing its limitations. + *
  • {@link org.springframework.context.support.ReloadableResourceBundleMessageSource}: + * highly configurable, in particular with respect to reloading message definitions. *
* * @author Rod Johnson @@ -41,16 +41,17 @@ public interface MessageSource { /** * Try to resolve the message. Return default message if no message was found. - * @param code the code to lookup up, such as 'calculator.noRateSet'. Users of - * this class are encouraged to base message names on the relevant fully - * qualified class name, thus avoiding conflict and ensuring maximum clarity. + * @param code the code to lookup up, e.g. 'calculator.noRateSet'. + * MessageSource users are encouraged to base message names on qualified class + * or package names, avoiding potential conflicts and ensuring maximum clarity. * @param args an array of arguments that will be filled in for params within * the message (params look like "{0}", "{1,date}", "{2,time}" within a message), - * or {@code null} if none. + * or {@code null} if none * @param defaultMessage a default message to return if the lookup fails * @param locale the locale in which to do the lookup - * @return the resolved message if the lookup was successful; - * otherwise the default message passed as a parameter + * @return the resolved message if the lookup was successful, otherwise + * the default message passed as a parameter (which may be {@code null}) + * @see #getMessage(MessageSourceResolvable, Locale) * @see java.text.MessageFormat */ @Nullable @@ -58,13 +59,16 @@ public interface MessageSource { /** * Try to resolve the message. Treat as an error if the message can't be found. - * @param code the code to lookup up, such as 'calculator.noRateSet' + * @param code the code to lookup up, e.g. 'calculator.noRateSet'. + * MessageSource users are encouraged to base message names on qualified class + * or package names, avoiding potential conflicts and ensuring maximum clarity. * @param args an array of arguments that will be filled in for params within * the message (params look like "{0}", "{1,date}", "{2,time}" within a message), - * or {@code null} if none. + * or {@code null} if none * @param locale the locale in which to do the lookup - * @return the resolved message - * @throws NoSuchMessageException if the message wasn't found + * @return the resolved message (never {@code null}) + * @throws NoSuchMessageException if no corresponding message was found + * @see #getMessage(MessageSourceResolvable, Locale) * @see java.text.MessageFormat */ String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException; @@ -76,9 +80,15 @@ public interface MessageSource { * since at the time of calling this method we aren't able to determine if the * {@code defaultMessage} property of the resolvable is {@code null} or not. * @param resolvable the value object storing attributes required to resolve a message + * (may include a default message) * @param locale the locale in which to do the lookup - * @return the resolved message - * @throws NoSuchMessageException if the message wasn't found + * @return the resolved message (never {@code null} since even a + * {@code MessageSourceResolvable}-provided default message needs to be non-null) + * @throws NoSuchMessageException if no corresponding message was found + * (and no default message was provided by the {@code MessageSourceResolvable}) + * @see MessageSourceResolvable#getCodes() + * @see MessageSourceResolvable#getArguments() + * @see MessageSourceResolvable#getDefaultMessage() * @see java.text.MessageFormat */ String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;