diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/DefaultAopProxyFactory.java b/spring-aop/src/main/java/org/springframework/aop/framework/DefaultAopProxyFactory.java index d84df2f4c9..3e8c838704 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/DefaultAopProxyFactory.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/DefaultAopProxyFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * 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. @@ -20,6 +20,7 @@ import java.io.Serializable; import java.lang.reflect.Proxy; import org.springframework.aop.SpringProxy; +import org.springframework.core.NativeDetector; /** * Default {@link AopProxyFactory} implementation, creating either a CGLIB proxy @@ -47,17 +48,10 @@ import org.springframework.aop.SpringProxy; @SuppressWarnings("serial") public class DefaultAopProxyFactory implements AopProxyFactory, Serializable { - /** - * Whether this environment lives within a native image. - * Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594. - * @see ImageInfo.java - */ - private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null); - @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { - if (!IN_NATIVE_IMAGE && + if (!NativeDetector.inNativeImage() && (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) { Class> targetClass = config.getTargetClass(); if (targetClass == null) { 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 4997a7337a..ff76dcdd37 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 @@ -73,6 +73,7 @@ import org.springframework.beans.factory.config.TypedStringValue; import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.MethodParameter; import org.springframework.core.NamedThreadLocal; +import org.springframework.core.NativeDetector; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.PriorityOrdered; import org.springframework.core.ResolvableType; @@ -123,14 +124,6 @@ import org.springframework.util.StringUtils; public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory { - /** - * Whether this environment lives within a native image. - * Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594. - * @see ImageInfo.java - */ - private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null); - - /** Strategy for creating bean instances. */ private InstantiationStrategy instantiationStrategy; @@ -184,7 +177,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac ignoreDependencyInterface(BeanNameAware.class); ignoreDependencyInterface(BeanFactoryAware.class); ignoreDependencyInterface(BeanClassLoaderAware.class); - if (IN_NATIVE_IMAGE) { + if (NativeDetector.inNativeImage()) { this.instantiationStrategy = new SimpleInstantiationStrategy(); } else { diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java index 449c48fa87..326a5bab3a 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * 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. @@ -52,6 +52,7 @@ import org.springframework.context.ApplicationStartupAware; import org.springframework.context.EnvironmentAware; import org.springframework.context.ResourceLoaderAware; import org.springframework.context.annotation.ConfigurationClassEnhancer.EnhancedConfiguration; +import org.springframework.core.NativeDetector; import org.springframework.core.Ordered; import org.springframework.core.PriorityOrdered; import org.springframework.core.env.Environment; @@ -104,13 +105,6 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo private static final String IMPORT_REGISTRY_BEAN_NAME = ConfigurationClassPostProcessor.class.getName() + ".importRegistry"; - /** - * Whether this environment lives within a native image. - * Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594. - * @see ImageInfo.java - */ - private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null); - private final Log logger = LogFactory.getLog(getClass()); @@ -427,7 +421,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef); } } - if (configBeanDefs.isEmpty() || IN_NATIVE_IMAGE) { + if (configBeanDefs.isEmpty() || NativeDetector.inNativeImage()) { // nothing to enhance -> return immediately enhanceConfigClasses.end(); return; diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index e87edab5f6..86ca92ef6f 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * 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. @@ -66,6 +66,7 @@ import org.springframework.context.event.SimpleApplicationEventMulticaster; import org.springframework.context.expression.StandardBeanExpressionResolver; import org.springframework.context.weaving.LoadTimeWeaverAware; import org.springframework.context.weaving.LoadTimeWeaverAwareProcessor; +import org.springframework.core.NativeDetector; import org.springframework.core.ResolvableType; import org.springframework.core.SpringProperties; import org.springframework.core.annotation.AnnotationUtils; @@ -164,13 +165,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader */ private static final boolean shouldIgnoreSpel = SpringProperties.getFlag("spring.spel.ignore"); - /** - * Whether this environment lives within a native image. - * Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594. - * @see ImageInfo.java - */ - private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null); - static { // Eagerly load the ContextClosedEvent class to avoid weird classloader issues @@ -711,7 +705,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. - if (!IN_NATIVE_IMAGE && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { + if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); @@ -752,7 +746,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) - if (!IN_NATIVE_IMAGE && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { + if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } @@ -943,7 +937,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. - if (!IN_NATIVE_IMAGE) { + if (!NativeDetector.inNativeImage()) { LiveBeansView.registerApplicationContext(this); } } @@ -1054,7 +1048,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader logger.debug("Closing " + this); } - if (!IN_NATIVE_IMAGE) { + if (!NativeDetector.inNativeImage()) { LiveBeansView.unregisterApplicationContext(this); } diff --git a/spring-core/src/main/java/org/springframework/core/DefaultParameterNameDiscoverer.java b/spring-core/src/main/java/org/springframework/core/DefaultParameterNameDiscoverer.java index 283e5ba0f3..f4dca0f996 100644 --- a/spring-core/src/main/java/org/springframework/core/DefaultParameterNameDiscoverer.java +++ b/spring-core/src/main/java/org/springframework/core/DefaultParameterNameDiscoverer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * 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. @@ -39,15 +39,9 @@ package org.springframework.core; */ public class DefaultParameterNameDiscoverer extends PrioritizedParameterNameDiscoverer { - /** - * Whether this environment lives within a native image. - * Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594. - * @see ImageInfo.java - */ - private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null); - public DefaultParameterNameDiscoverer() { - if (KotlinDetector.isKotlinReflectPresent() && !IN_NATIVE_IMAGE) { + // TODO Remove this conditional inclusion when upgrading to Kotlin 1.5, see https://youtrack.jetbrains.com/issue/KT-44594 + if (KotlinDetector.isKotlinReflectPresent() && !NativeDetector.inNativeImage()) { addDiscoverer(new KotlinReflectionParameterNameDiscoverer()); } addDiscoverer(new StandardReflectionParameterNameDiscoverer()); diff --git a/spring-core/src/main/java/org/springframework/core/NativeDetector.java b/spring-core/src/main/java/org/springframework/core/NativeDetector.java new file mode 100644 index 0000000000..f2f191747e --- /dev/null +++ b/spring-core/src/main/java/org/springframework/core/NativeDetector.java @@ -0,0 +1,39 @@ +/* + * 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.core; + +/** + * A common delegate for detecting a GraalVM native image environment. + * + *
Requires using the {@code -H:+InlineBeforeAnalysis} native image compiler flag in order to allow code removal at
+ * build time.
+ *
+ * @author Sebastien Deleuze
+ * @since 5.3.4
+ */
+public abstract class NativeDetector {
+
+ // See https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java
+ private static final boolean imageCode = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
+
+ /**
+ * Returns {@code true} if invoked in the context of image building or during image runtime, else {@code false}.
+ */
+ public static boolean inNativeImage() {
+ return imageCode;
+ }
+}
diff --git a/spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java b/spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java
index 8a3a18e209..7d09fe2e06 100644
--- a/spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java
+++ b/spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2020 the original author or authors.
+ * 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.
@@ -59,13 +59,6 @@ final class SerializableTypeWrapper {
private static final Class>[] SUPPORTED_SERIALIZABLE_TYPES = {
GenericArrayType.class, ParameterizedType.class, TypeVariable.class, WildcardType.class};
- /**
- * Whether this environment lives within a native image.
- * Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
- * @see ImageInfo.java
- */
- private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
-
static final ConcurrentReferenceHashMap