Skip to content

Commit 3524401

Browse files
committed
Introduce a NativeDetector utility class
With the introduction of the -H:+InlineBeforeAnalysis native image compiler flag in GraalVM 21.0.0, it is now possible to use an utility method and get code removal at build time. This flag will be enabled as of Spring Native 0.9.0. closes gh-25795
1 parent 86423c9 commit 3524401

File tree

7 files changed

+58
-57
lines changed

7 files changed

+58
-57
lines changed

spring-aop/src/main/java/org/springframework/aop/framework/DefaultAopProxyFactory.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@
2020
import java.lang.reflect.Proxy;
2121

2222
import org.springframework.aop.SpringProxy;
23+
import org.springframework.core.NativeDetector;
2324

2425
/**
2526
* Default {@link AopProxyFactory} implementation, creating either a CGLIB proxy
@@ -47,17 +48,10 @@
4748
@SuppressWarnings("serial")
4849
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
4950

50-
/**
51-
* Whether this environment lives within a native image.
52-
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
53-
* @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
54-
*/
55-
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
56-
5751

5852
@Override
5953
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
60-
if (!IN_NATIVE_IMAGE &&
54+
if (!NativeDetector.inNativeImage() &&
6155
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
6256
Class<?> targetClass = config.getTargetClass();
6357
if (targetClass == null) {

spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import org.springframework.core.DefaultParameterNameDiscoverer;
7474
import org.springframework.core.MethodParameter;
7575
import org.springframework.core.NamedThreadLocal;
76+
import org.springframework.core.NativeDetector;
7677
import org.springframework.core.ParameterNameDiscoverer;
7778
import org.springframework.core.PriorityOrdered;
7879
import org.springframework.core.ResolvableType;
@@ -123,14 +124,6 @@
123124
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
124125
implements AutowireCapableBeanFactory {
125126

126-
/**
127-
* Whether this environment lives within a native image.
128-
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
129-
* @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
130-
*/
131-
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
132-
133-
134127
/** Strategy for creating bean instances. */
135128
private InstantiationStrategy instantiationStrategy;
136129

@@ -184,7 +177,7 @@ public AbstractAutowireCapableBeanFactory() {
184177
ignoreDependencyInterface(BeanNameAware.class);
185178
ignoreDependencyInterface(BeanFactoryAware.class);
186179
ignoreDependencyInterface(BeanClassLoaderAware.class);
187-
if (IN_NATIVE_IMAGE) {
180+
if (NativeDetector.inNativeImage()) {
188181
this.instantiationStrategy = new SimpleInstantiationStrategy();
189182
}
190183
else {

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -52,6 +52,7 @@
5252
import org.springframework.context.EnvironmentAware;
5353
import org.springframework.context.ResourceLoaderAware;
5454
import org.springframework.context.annotation.ConfigurationClassEnhancer.EnhancedConfiguration;
55+
import org.springframework.core.NativeDetector;
5556
import org.springframework.core.Ordered;
5657
import org.springframework.core.PriorityOrdered;
5758
import org.springframework.core.env.Environment;
@@ -104,13 +105,6 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
104105
private static final String IMPORT_REGISTRY_BEAN_NAME =
105106
ConfigurationClassPostProcessor.class.getName() + ".importRegistry";
106107

107-
/**
108-
* Whether this environment lives within a native image.
109-
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
110-
* @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
111-
*/
112-
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
113-
114108

115109
private final Log logger = LogFactory.getLog(getClass());
116110

@@ -427,7 +421,7 @@ else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {
427421
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
428422
}
429423
}
430-
if (configBeanDefs.isEmpty() || IN_NATIVE_IMAGE) {
424+
if (configBeanDefs.isEmpty() || NativeDetector.inNativeImage()) {
431425
// nothing to enhance -> return immediately
432426
enhanceConfigClasses.end();
433427
return;

spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -66,6 +66,7 @@
6666
import org.springframework.context.expression.StandardBeanExpressionResolver;
6767
import org.springframework.context.weaving.LoadTimeWeaverAware;
6868
import org.springframework.context.weaving.LoadTimeWeaverAwareProcessor;
69+
import org.springframework.core.NativeDetector;
6970
import org.springframework.core.ResolvableType;
7071
import org.springframework.core.SpringProperties;
7172
import org.springframework.core.annotation.AnnotationUtils;
@@ -164,13 +165,6 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
164165
*/
165166
private static final boolean shouldIgnoreSpel = SpringProperties.getFlag("spring.spel.ignore");
166167

167-
/**
168-
* Whether this environment lives within a native image.
169-
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
170-
* @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
171-
*/
172-
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
173-
174168

175169
static {
176170
// Eagerly load the ContextClosedEvent class to avoid weird classloader issues
@@ -711,7 +705,7 @@ protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
711705
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
712706

713707
// Detect a LoadTimeWeaver and prepare for weaving, if found.
714-
if (!IN_NATIVE_IMAGE && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
708+
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
715709
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
716710
// Set a temporary ClassLoader for type matching.
717711
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
@@ -752,7 +746,7 @@ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory b
752746

753747
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
754748
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
755-
if (!IN_NATIVE_IMAGE && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
749+
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
756750
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
757751
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
758752
}
@@ -943,7 +937,7 @@ protected void finishRefresh() {
943937
publishEvent(new ContextRefreshedEvent(this));
944938

945939
// Participate in LiveBeansView MBean, if active.
946-
if (!IN_NATIVE_IMAGE) {
940+
if (!NativeDetector.inNativeImage()) {
947941
LiveBeansView.registerApplicationContext(this);
948942
}
949943
}
@@ -1054,7 +1048,7 @@ protected void doClose() {
10541048
logger.debug("Closing " + this);
10551049
}
10561050

1057-
if (!IN_NATIVE_IMAGE) {
1051+
if (!NativeDetector.inNativeImage()) {
10581052
LiveBeansView.unregisterApplicationContext(this);
10591053
}
10601054

spring-core/src/main/java/org/springframework/core/DefaultParameterNameDiscoverer.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -39,15 +39,9 @@
3939
*/
4040
public class DefaultParameterNameDiscoverer extends PrioritizedParameterNameDiscoverer {
4141

42-
/**
43-
* Whether this environment lives within a native image.
44-
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
45-
* @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
46-
*/
47-
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
48-
4942
public DefaultParameterNameDiscoverer() {
50-
if (KotlinDetector.isKotlinReflectPresent() && !IN_NATIVE_IMAGE) {
43+
// TODO Remove this conditional inclusion when upgrading to Kotlin 1.5, see https://youtrack.jetbrains.com/issue/KT-44594
44+
if (KotlinDetector.isKotlinReflectPresent() && !NativeDetector.inNativeImage()) {
5145
addDiscoverer(new KotlinReflectionParameterNameDiscoverer());
5246
}
5347
addDiscoverer(new StandardReflectionParameterNameDiscoverer());
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2002-2021 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.core;
18+
19+
/**
20+
* A common delegate for detecting a GraalVM native image environment.
21+
*
22+
* <p>Requires using the {@code -H:+InlineBeforeAnalysis} native image compiler flag in order to allow code removal at
23+
* build time.
24+
*
25+
* @author Sebastien Deleuze
26+
* @since 5.3.4
27+
*/
28+
public abstract class NativeDetector {
29+
30+
// See https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java
31+
private static final boolean imageCode = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
32+
33+
/**
34+
* Returns {@code true} if invoked in the context of image building or during image runtime, else {@code false}.
35+
*/
36+
public static boolean inNativeImage() {
37+
return imageCode;
38+
}
39+
}

spring-core/src/main/java/org/springframework/core/SerializableTypeWrapper.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -59,13 +59,6 @@ final class SerializableTypeWrapper {
5959
private static final Class<?>[] SUPPORTED_SERIALIZABLE_TYPES = {
6060
GenericArrayType.class, ParameterizedType.class, TypeVariable.class, WildcardType.class};
6161

62-
/**
63-
* Whether this environment lives within a native image.
64-
* Exposed as a private static field rather than in a {@code NativeImageDetector.inNativeImage()} static method due to https://github.com/oracle/graal/issues/2594.
65-
* @see <a href="https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java">ImageInfo.java</a>
66-
*/
67-
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
68-
6962
static final ConcurrentReferenceHashMap<Type, Type> cache = new ConcurrentReferenceHashMap<>(256);
7063

7164

@@ -116,7 +109,7 @@ static Type forTypeProvider(TypeProvider provider) {
116109
// No serializable type wrapping necessary (e.g. for java.lang.Class)
117110
return providedType;
118111
}
119-
if (IN_NATIVE_IMAGE || !Serializable.class.isAssignableFrom(Class.class)) {
112+
if (NativeDetector.inNativeImage() || !Serializable.class.isAssignableFrom(Class.class)) {
120113
// Let's skip any wrapping attempts if types are generally not serializable in
121114
// the current runtime environment (even java.lang.Class itself, e.g. on GraalVM native images)
122115
return providedType;

0 commit comments

Comments
 (0)