Defensive reference to JNDI API for JDK 9+ (optional `java.naming` module)

Closes gh-27483
This commit is contained in:
Juergen Hoeller 2021-09-28 18:15:22 +02:00
parent 2feedb98cc
commit 86b010a6b2
2 changed files with 41 additions and 11 deletions

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -146,22 +146,27 @@ import org.springframework.util.StringValueResolver;
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable { implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
// Defensive reference to JNDI API for JDK 9+ (optional java.naming module)
private static final boolean jndiPresent = ClassUtils.isPresent(
"javax.naming.InitialContext", CommonAnnotationBeanPostProcessor.class.getClassLoader());
private static final Set<Class<? extends Annotation>> resourceAnnotationTypes = new LinkedHashSet<>(4);
@Nullable @Nullable
private static final Class<? extends Annotation> webServiceRefClass; private static final Class<? extends Annotation> webServiceRefClass;
@Nullable @Nullable
private static final Class<? extends Annotation> ejbClass; private static final Class<? extends Annotation> ejbClass;
private static final Set<Class<? extends Annotation>> resourceAnnotationTypes = new LinkedHashSet<>(4);
static { static {
webServiceRefClass = loadAnnotationType("javax.xml.ws.WebServiceRef");
ejbClass = loadAnnotationType("javax.ejb.EJB");
resourceAnnotationTypes.add(Resource.class); resourceAnnotationTypes.add(Resource.class);
webServiceRefClass = loadAnnotationType("javax.xml.ws.WebServiceRef");
if (webServiceRefClass != null) { if (webServiceRefClass != null) {
resourceAnnotationTypes.add(webServiceRefClass); resourceAnnotationTypes.add(webServiceRefClass);
} }
ejbClass = loadAnnotationType("javax.ejb.EJB");
if (ejbClass != null) { if (ejbClass != null) {
resourceAnnotationTypes.add(ejbClass); resourceAnnotationTypes.add(ejbClass);
} }
@ -174,7 +179,8 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
private boolean alwaysUseJndiLookup = false; private boolean alwaysUseJndiLookup = false;
private transient BeanFactory jndiFactory = new SimpleJndiBeanFactory(); @Nullable
private transient BeanFactory jndiFactory;
@Nullable @Nullable
private transient BeanFactory resourceFactory; private transient BeanFactory resourceFactory;
@ -199,6 +205,11 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
setInitAnnotationType(PostConstruct.class); setInitAnnotationType(PostConstruct.class);
setDestroyAnnotationType(PreDestroy.class); setDestroyAnnotationType(PreDestroy.class);
ignoreResourceType("javax.xml.ws.WebServiceContext"); ignoreResourceType("javax.xml.ws.WebServiceContext");
// java.naming module present on JDK 9+?
if (jndiPresent) {
this.jndiFactory = new SimpleJndiBeanFactory();
}
} }
@ -464,6 +475,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
public void releaseTarget(Object target) { public void releaseTarget(Object target) {
} }
}; };
ProxyFactory pf = new ProxyFactory(); ProxyFactory pf = new ProxyFactory();
pf.setTargetSource(ts); pf.setTargetSource(ts);
if (element.lookupType.isInterface()) { if (element.lookupType.isInterface()) {
@ -484,12 +496,23 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
protected Object getResource(LookupElement element, @Nullable String requestingBeanName) protected Object getResource(LookupElement element, @Nullable String requestingBeanName)
throws NoSuchBeanDefinitionException { throws NoSuchBeanDefinitionException {
// JNDI lookup to perform?
String jndiName = null;
if (StringUtils.hasLength(element.mappedName)) { if (StringUtils.hasLength(element.mappedName)) {
return this.jndiFactory.getBean(element.mappedName, element.lookupType); jndiName = element.mappedName;
} }
if (this.alwaysUseJndiLookup) { else if (this.alwaysUseJndiLookup) {
return this.jndiFactory.getBean(element.name, element.lookupType); jndiName = element.name;
} }
if (jndiName != null) {
if (this.jndiFactory == null) {
throw new NoSuchBeanDefinitionException(element.lookupType,
"No JNDI factory configured - specify the 'jndiFactory' property");
}
return this.jndiFactory.getBean(jndiName, element.lookupType);
}
// Regular resource autowiring
if (this.resourceFactory == null) { if (this.resourceFactory == null) {
throw new NoSuchBeanDefinitionException(element.lookupType, throw new NoSuchBeanDefinitionException(element.lookupType,
"No resource factory configured - specify the 'resourceFactory' property"); "No resource factory configured - specify the 'resourceFactory' property");

View File

@ -27,6 +27,7 @@ import org.springframework.core.env.StandardEnvironment;
import org.springframework.jndi.JndiLocatorDelegate; import org.springframework.jndi.JndiLocatorDelegate;
import org.springframework.jndi.JndiPropertySource; import org.springframework.jndi.JndiPropertySource;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.web.context.ConfigurableWebEnvironment; import org.springframework.web.context.ConfigurableWebEnvironment;
/** /**
@ -39,6 +40,7 @@ import org.springframework.web.context.ConfigurableWebEnvironment;
* documentation for details. * documentation for details.
* *
* @author Chris Beams * @author Chris Beams
* @author Juergen Hoeller
* @since 3.1 * @since 3.1
* @see StandardEnvironment * @see StandardEnvironment
*/ */
@ -54,6 +56,11 @@ public class StandardServletEnvironment extends StandardEnvironment implements C
public static final String JNDI_PROPERTY_SOURCE_NAME = "jndiProperties"; public static final String JNDI_PROPERTY_SOURCE_NAME = "jndiProperties";
// Defensive reference to JNDI API for JDK 9+ (optional java.naming module)
private static final boolean jndiPresent = ClassUtils.isPresent(
"javax.naming.InitialContext", StandardServletEnvironment.class.getClassLoader());
/** /**
* Create a new {@code StandardServletEnvironment} instance. * Create a new {@code StandardServletEnvironment} instance.
*/ */
@ -100,7 +107,7 @@ public class StandardServletEnvironment extends StandardEnvironment implements C
protected void customizePropertySources(MutablePropertySources propertySources) { protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME)); propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME));
propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME)); propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME));
if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) { if (jndiPresent && JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME)); propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME));
} }
super.customizePropertySources(propertySources); super.customizePropertySources(propertySources);