Jakarta EE 9 migration

Upgrades many dependency declarations; removes old EJB 2.x support and outdated Servlet-based integrations (Commons FileUpload, FreeMarker JSP support, Tiles).

Closes gh-22093
Closes gh-25354
Closes gh-26185
Closes gh-27423
See gh-27424
This commit is contained in:
Juergen Hoeller
2021-09-17 09:14:07 +02:00
parent 5822f1bf85
commit d84ca2ba90
1291 changed files with 4992 additions and 25322 deletions

View File

@@ -41,8 +41,8 @@ import org.springframework.util.StringUtils;
* {@link org.springframework.stereotype.Repository @Repository}) are
* themselves annotated with {@code @Component}.
*
* <p>Also supports Java EE 6's {@link javax.annotation.ManagedBean} and
* JSR-330's {@link javax.inject.Named} annotations, if available. Note that
* <p>Also supports Jakarta EE's {@link jakarta.annotation.ManagedBean} and
* JSR-330's {@link jakarta.inject.Named} annotations, if available. Note that
* Spring component annotations always override such standard annotations.
*
* <p>If the annotation's value doesn't indicate a bean name, an appropriate
@@ -58,7 +58,7 @@ import org.springframework.util.StringUtils;
* @see org.springframework.stereotype.Repository#value()
* @see org.springframework.stereotype.Service#value()
* @see org.springframework.stereotype.Controller#value()
* @see javax.inject.Named#value()
* @see jakarta.inject.Named#value()
* @see FullyQualifiedAnnotationBeanNameGenerator
*/
public class AnnotationBeanNameGenerator implements BeanNameGenerator {
@@ -136,8 +136,8 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator {
boolean isStereotype = annotationType.equals(COMPONENT_ANNOTATION_CLASSNAME) ||
metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME) ||
annotationType.equals("javax.annotation.ManagedBean") ||
annotationType.equals("javax.inject.Named");
annotationType.equals("jakarta.annotation.ManagedBean") ||
annotationType.equals("jakarta.inject.Named");
return (isStereotype && attributes != null && attributes.containsKey("value"));
}

View File

@@ -32,7 +32,7 @@ import org.springframework.util.Assert;
* Standalone application context, accepting <em>component classes</em> as input &mdash;
* in particular {@link Configuration @Configuration}-annotated classes, but also plain
* {@link org.springframework.stereotype.Component @Component} types and JSR-330 compliant
* classes using {@code javax.inject} annotations.
* classes using {@code jakarta.inject} annotations.
*
* <p>Allows for registering classes one by one using {@link #register(Class...)}
* as well as for classpath scanning using {@link #scan(String...)}.

View File

@@ -123,8 +123,8 @@ public abstract class AnnotationConfigUtils {
static {
ClassLoader classLoader = AnnotationConfigUtils.class.getClassLoader();
jsr250Present = ClassUtils.isPresent("javax.annotation.Resource", classLoader);
jpaPresent = ClassUtils.isPresent("javax.persistence.EntityManagerFactory", classLoader) &&
jsr250Present = ClassUtils.isPresent("jakarta.annotation.Resource", classLoader);
jpaPresent = ClassUtils.isPresent("jakarta.persistence.EntityManagerFactory", classLoader) &&
ClassUtils.isPresent(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, classLoader);
}

View File

@@ -99,7 +99,7 @@ import org.springframework.core.annotation.AliasFor;
* <p><b>NOTE:</b> {@code @Order} values may influence priorities at injection points,
* but please be aware that they do not influence singleton startup order which is an
* orthogonal concern determined by dependency relationships and {@code @DependsOn}
* declarations as mentioned above. Also, {@link javax.annotation.Priority} is not
* declarations as mentioned above. Also, {@link jakarta.annotation.Priority} is not
* available at this level since it cannot be declared on methods; its semantics can
* be modeled through {@code @Order} values in combination with {@code @Primary} on
* a single bean per type.

View File

@@ -47,8 +47,8 @@ import org.springframework.util.PatternMatchUtils;
* {@link org.springframework.stereotype.Service @Service}, or
* {@link org.springframework.stereotype.Controller @Controller} stereotype.
*
* <p>Also supports Java EE 6's {@link javax.annotation.ManagedBean} and
* JSR-330's {@link javax.inject.Named} annotations, if available.
* <p>Also supports Jakarta EE's {@link jakarta.annotation.ManagedBean} and
* JSR-330's {@link jakarta.inject.Named} annotations, if available.
*
* @author Mark Fisher
* @author Juergen Hoeller

View File

@@ -197,8 +197,8 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
* {@link Component @Component} meta-annotation including the
* {@link Repository @Repository}, {@link Service @Service}, and
* {@link Controller @Controller} stereotype annotations.
* <p>Also supports Java EE 6's {@link javax.annotation.ManagedBean} and
* JSR-330's {@link javax.inject.Named} annotations, if available.
* <p>Also supports Jakarta EE's {@link jakarta.annotation.ManagedBean} and
* JSR-330's {@link jakarta.inject.Named} annotations, if available.
*
*/
@SuppressWarnings("unchecked")
@@ -207,16 +207,16 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
((Class<? extends Annotation>) ClassUtils.forName("jakarta.annotation.ManagedBean", cl)), false));
logger.trace("JSR-250 'jakarta.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
// JSR-250 1.1 API (as included in Jakarta EE) not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
((Class<? extends Annotation>) ClassUtils.forName("jakarta.inject.Named", cl)), false));
logger.trace("JSR-330 'jakarta.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.

View File

@@ -37,14 +37,15 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceRef;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import jakarta.annotation.Resource;
import jakarta.ejb.EJB;
import jakarta.xml.ws.Service;
import jakarta.xml.ws.WebServiceClient;
import jakarta.xml.ws.WebServiceRef;
import org.springframework.aop.TargetSource;
import org.springframework.aop.framework.ProxyFactory;
@@ -77,36 +78,32 @@ import org.springframework.util.StringValueResolver;
/**
* {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation
* that supports common Java annotations out of the box, in particular the JSR-250
* annotations in the {@code javax.annotation} package. These common Java
* annotations are supported in many Java EE 5 technologies (e.g. JSF 1.2),
* annotations in the {@code jakarta.annotation} package. These common Java
* annotations are supported in many Jakarta EE technologies (e.g. JSF 1.2),
* as well as in Java 6's JAX-WS.
*
* <p>This post-processor includes support for the {@link javax.annotation.PostConstruct}
* and {@link javax.annotation.PreDestroy} annotations - as init annotation
* <p>This post-processor includes support for the {@link jakarta.annotation.PostConstruct}
* and {@link jakarta.annotation.PreDestroy} annotations - as init annotation
* and destroy annotation, respectively - through inheriting from
* {@link InitDestroyAnnotationBeanPostProcessor} with pre-configured annotation types.
*
* <p>The central element is the {@link javax.annotation.Resource} annotation
* <p>The central element is the {@link jakarta.annotation.Resource} annotation
* for annotation-driven injection of named beans, by default from the containing
* Spring BeanFactory, with only {@code mappedName} references resolved in JNDI.
* The {@link #setAlwaysUseJndiLookup "alwaysUseJndiLookup" flag} enforces JNDI lookups
* equivalent to standard Java EE 5 resource injection for {@code name} references
* equivalent to standard Jakarta EE resource injection for {@code name} references
* and default names as well. The target beans can be simple POJOs, with no special
* requirements other than the type having to match.
*
* <p>The JAX-WS {@link javax.xml.ws.WebServiceRef} annotation is supported too,
* analogous to {@link javax.annotation.Resource} but with the capability of creating
* analogous to {@link jakarta.annotation.Resource} but with the capability of creating
* specific JAX-WS service endpoints. This may either point to an explicitly defined
* resource by name or operate on a locally specified JAX-WS service class. Finally,
* this post-processor also supports the EJB 3 {@link javax.ejb.EJB} annotation,
* analogous to {@link javax.annotation.Resource} as well, with the capability to
* this post-processor also supports the EJB 3 {@link jakarta.ejb.EJB} annotation,
* analogous to {@link jakarta.annotation.Resource} as well, with the capability to
* specify both a local bean name and a global JNDI name for fallback retrieval.
* The target beans can be plain POJOs as well as EJB 3 Session Beans in this case.
*
* <p>The common annotations supported by this post-processor are available in
* Java 6 (JDK 1.6) as well as in Java EE 5/6 (which provides a standalone jar for
* its common annotations as well, allowing for use in any Java 5 based application).
*
* <p>For default usage, resolving resource names as Spring bean names,
* simply define the following in your application context:
*
@@ -114,7 +111,7 @@ import org.springframework.util.StringValueResolver;
* &lt;bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/&gt;</pre>
*
* For direct JNDI access, resolving resource names as JNDI resource references
* within the Java EE application's "java:comp/env/" namespace, use the following:
* within the Jakarta EE application's "java:comp/env/" namespace, use the following:
*
* <pre class="code">
* &lt;bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"&gt;
@@ -156,7 +153,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
static {
webServiceRefClass = loadAnnotationType("javax.xml.ws.WebServiceRef");
ejbClass = loadAnnotationType("javax.ejb.EJB");
ejbClass = loadAnnotationType("jakarta.ejb.EJB");
resourceAnnotationTypes.add(Resource.class);
if (webServiceRefClass != null) {
@@ -191,7 +188,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
/**
* Create a new CommonAnnotationBeanPostProcessor,
* with the init and destroy annotation types set to
* {@link javax.annotation.PostConstruct} and {@link javax.annotation.PreDestroy},
* {@link jakarta.annotation.PostConstruct} and {@link jakarta.annotation.PreDestroy},
* respectively.
*/
public CommonAnnotationBeanPostProcessor() {
@@ -229,11 +226,11 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
}
/**
* Set whether to always use JNDI lookups equivalent to standard Java EE 5 resource
* Set whether to always use JNDI lookups equivalent to standard Jakarta EE resource
* injection, <b>even for {@code name} attributes and default names</b>.
* <p>Default is "false": Resource names are used for Spring bean lookups in the
* containing BeanFactory; only {@code mappedName} attributes point directly
* into JNDI. Switch this flag to "true" for enforcing Java EE style JNDI lookups
* into JNDI. Switch this flag to "true" for enforcing Jakarta EE style JNDI lookups
* in any case, even for {@code name} attributes and default names.
* @see #setJndiFactory
* @see #setResourceFactory
@@ -249,7 +246,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
* This factory will also be used if "alwaysUseJndiLookup" is set to "true" in order
* to enforce JNDI lookups even for {@code name} attributes and default names.
* <p>The default is a {@link org.springframework.jndi.support.SimpleJndiBeanFactory}
* for JNDI lookup behavior equivalent to standard Java EE 5 resource injection.
* for JNDI lookup behavior equivalent to standard Jakarta EE resource injection.
* @see #setResourceFactory
* @see #setAlwaysUseJndiLookup
*/
@@ -266,7 +263,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
* if any, looking up resource names as Spring bean names. Specify the resource
* factory explicitly for programmatic usage of this post-processor.
* <p>Specifying Spring's {@link org.springframework.jndi.support.SimpleJndiBeanFactory}
* leads to JNDI lookup behavior equivalent to standard Java EE 5 resource injection,
* leads to JNDI lookup behavior equivalent to standard Jakarta EE resource injection,
* even for {@code name} attributes and default names. This is the same behavior
* that the "alwaysUseJndiLookup" flag enables.
* @see #setAlwaysUseJndiLookup

View File

@@ -86,7 +86,7 @@ import org.springframework.stereotype.Component;
* <p>{@code @Configuration} is meta-annotated with {@link Component @Component}, therefore
* {@code @Configuration} classes are candidates for component scanning (typically using
* Spring XML's {@code <context:component-scan/>} element) and therefore may also take
* advantage of {@link Autowired @Autowired}/{@link javax.inject.Inject @Inject}
* advantage of {@link Autowired @Autowired}/{@link jakarta.inject.Inject @Inject}
* like any regular {@code @Component}. In particular, if a single constructor is present
* autowiring semantics will be applied transparently for that constructor:
*

View File

@@ -26,7 +26,7 @@ import org.springframework.lang.Nullable;
/**
* Simple {@link ScopeMetadataResolver} implementation that follows JSR-330 scoping rules:
* defaulting to prototype scope unless {@link javax.inject.Singleton} is present.
* defaulting to prototype scope unless {@link jakarta.inject.Singleton} is present.
*
* <p>This scope resolver can be used with {@link ClassPathBeanDefinitionScanner} and
* {@link AnnotatedBeanDefinitionReader} for standard JSR-330 compliance. However,
@@ -46,7 +46,7 @@ public class Jsr330ScopeMetadataResolver implements ScopeMetadataResolver {
public Jsr330ScopeMetadataResolver() {
registerScope("javax.inject.Singleton", BeanDefinition.SCOPE_SINGLETON);
registerScope("jakarta.inject.Singleton", BeanDefinition.SCOPE_SINGLETON);
}
@@ -93,7 +93,7 @@ public class Jsr330ScopeMetadataResolver implements ScopeMetadataResolver {
String found = null;
for (String annType : annTypes) {
Set<String> metaAnns = annDef.getMetadata().getMetaAnnotationTypes(annType);
if (metaAnns.contains("javax.inject.Scope")) {
if (metaAnns.contains("jakarta.inject.Scope")) {
if (found != null) {
throw new IllegalStateException("Found ambiguous scope annotations on bean class [" +
definition.getBeanClassName() + "]: " + found + ", " + annType);

View File

@@ -44,9 +44,9 @@ import java.lang.annotation.Target;
*
* <p>In addition to its role for component initialization, this annotation may also be placed
* on injection points marked with {@link org.springframework.beans.factory.annotation.Autowired}
* or {@link javax.inject.Inject}: In that context, it leads to the creation of a
* or {@link jakarta.inject.Inject}: In that context, it leads to the creation of a
* lazy-resolution proxy for all affected dependencies, as an alternative to using
* {@link org.springframework.beans.factory.ObjectFactory} or {@link javax.inject.Provider}.
* {@link org.springframework.beans.factory.ObjectFactory} or {@link jakarta.inject.Provider}.
*
* @author Chris Beams
* @author Juergen Hoeller

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");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@ package org.springframework.context.annotation;
import java.util.Map;
import javax.management.MBeanServer;
import javax.naming.NamingException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
@@ -28,14 +27,10 @@ import org.springframework.context.EnvironmentAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.jmx.MBeanServerNotFoundException;
import org.springframework.jmx.export.annotation.AnnotationMBeanExporter;
import org.springframework.jmx.support.RegistrationPolicy;
import org.springframework.jmx.support.WebSphereMBeanServerFactoryBean;
import org.springframework.jndi.JndiLocatorDelegate;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
@@ -116,15 +111,6 @@ public class MBeanExportConfiguration implements ImportAware, EnvironmentAware,
Assert.state(this.beanFactory != null, "No BeanFactory set");
exporter.setServer(this.beanFactory.getBean(server, MBeanServer.class));
}
else {
SpecificPlatform specificPlatform = SpecificPlatform.get();
if (specificPlatform != null) {
MBeanServer mbeanServer = specificPlatform.getMBeanServer();
if (mbeanServer != null) {
exporter.setServer(mbeanServer);
}
}
}
}
private void setupRegistrationPolicy(AnnotationMBeanExporter exporter, AnnotationAttributes enableMBeanExport) {
@@ -132,58 +118,4 @@ public class MBeanExportConfiguration implements ImportAware, EnvironmentAware,
exporter.setRegistrationPolicy(registrationPolicy);
}
/**
* Specific platforms that might need custom MBean handling.
*/
public enum SpecificPlatform {
/**
* Weblogic.
*/
WEBLOGIC("weblogic.management.Helper") {
@Override
public MBeanServer getMBeanServer() {
try {
return new JndiLocatorDelegate().lookup("java:comp/env/jmx/runtime", MBeanServer.class);
}
catch (NamingException ex) {
throw new MBeanServerNotFoundException("Failed to retrieve WebLogic MBeanServer from JNDI", ex);
}
}
},
/**
* Websphere.
*/
WEBSPHERE("com.ibm.websphere.management.AdminServiceFactory") {
@Override
public MBeanServer getMBeanServer() {
WebSphereMBeanServerFactoryBean fb = new WebSphereMBeanServerFactoryBean();
fb.afterPropertiesSet();
return fb.getObject();
}
};
private final String identifyingClass;
SpecificPlatform(String identifyingClass) {
this.identifyingClass = identifyingClass;
}
@Nullable
public abstract MBeanServer getMBeanServer();
@Nullable
public static SpecificPlatform get() {
ClassLoader classLoader = MBeanExportConfiguration.class.getClassLoader();
for (SpecificPlatform environment : values()) {
if (ClassUtils.isPresent(environment.identifyingClass, classLoader)) {
return environment;
}
}
return null;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -76,12 +76,6 @@ class MBeanExportBeanDefinitionParser extends AbstractBeanDefinitionParser {
if (StringUtils.hasText(serverBeanName)) {
builder.addPropertyReference("server", serverBeanName);
}
else {
AbstractBeanDefinition specialServer = MBeanServerBeanDefinitionParser.findServerForSpecialEnvironment();
if (specialServer != null) {
builder.addPropertyValue("server", specialServer);
}
}
String registration = element.getAttribute(REGISTRATION_ATTRIBUTE);
RegistrationPolicy registrationPolicy = RegistrationPolicy.FAIL_ON_EXISTING;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 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.
@@ -24,10 +24,6 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.jmx.support.MBeanServerFactoryBean;
import org.springframework.jmx.support.WebSphereMBeanServerFactoryBean;
import org.springframework.jndi.JndiObjectFactoryBean;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
@@ -49,17 +45,6 @@ class MBeanServerBeanDefinitionParser extends AbstractBeanDefinitionParser {
private static final String AGENT_ID_ATTRIBUTE = "agent-id";
private static final boolean weblogicPresent;
private static final boolean webspherePresent;
static {
ClassLoader classLoader = MBeanServerBeanDefinitionParser.class.getClassLoader();
weblogicPresent = ClassUtils.isPresent("weblogic.management.Helper", classLoader);
webspherePresent = ClassUtils.isPresent("com.ibm.websphere.management.AdminServiceFactory", classLoader);
}
@Override
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) {
String id = element.getAttribute(ID_ATTRIBUTE);
@@ -74,10 +59,7 @@ class MBeanServerBeanDefinitionParser extends AbstractBeanDefinitionParser {
bd.getPropertyValues().add("agentId", agentId);
return bd;
}
AbstractBeanDefinition specialServer = findServerForSpecialEnvironment();
if (specialServer != null) {
return specialServer;
}
RootBeanDefinition bd = new RootBeanDefinition(MBeanServerFactoryBean.class);
bd.getPropertyValues().add("locateExistingServerIfPossible", Boolean.TRUE);
@@ -87,19 +69,4 @@ class MBeanServerBeanDefinitionParser extends AbstractBeanDefinitionParser {
return bd;
}
@Nullable
static AbstractBeanDefinition findServerForSpecialEnvironment() {
if (weblogicPresent) {
RootBeanDefinition bd = new RootBeanDefinition(JndiObjectFactoryBean.class);
bd.getPropertyValues().add("jndiName", "java:comp/env/jmx/runtime");
return bd;
}
else if (webspherePresent) {
return new RootBeanDefinition(WebSphereMBeanServerFactoryBean.class);
}
else {
return null;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 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.
@@ -30,8 +30,6 @@ import org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver;
import org.springframework.instrument.classloading.glassfish.GlassFishLoadTimeWeaver;
import org.springframework.instrument.classloading.jboss.JBossLoadTimeWeaver;
import org.springframework.instrument.classloading.tomcat.TomcatLoadTimeWeaver;
import org.springframework.instrument.classloading.weblogic.WebLogicLoadTimeWeaver;
import org.springframework.instrument.classloading.websphere.WebSphereLoadTimeWeaver;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@@ -45,10 +43,9 @@ import org.springframework.util.Assert;
* on a {@code @Configuration} class.
*
* <p>This class implements a runtime environment check for obtaining the
* appropriate weaver implementation. As of Spring Framework 5.0, it detects
* Oracle WebLogic 10+, GlassFish 4+, Tomcat 8+, WildFly 8+, IBM WebSphere 8.5+,
* {@link InstrumentationSavingAgent Spring's VM agent}, and any {@link ClassLoader}
* supported by Spring's {@link ReflectiveLoadTimeWeaver} (such as Liberty's).
* appropriate weaver implementation, including
* {@link InstrumentationSavingAgent Spring's VM agent} and any {@link ClassLoader}
* supported by Spring's {@link ReflectiveLoadTimeWeaver}.
*
* @author Juergen Hoeller
* @author Ramnivas Laddad
@@ -120,12 +117,6 @@ public class DefaultContextLoadTimeWeaver implements LoadTimeWeaver, BeanClassLo
else if (name.startsWith("org.jboss.modules")) {
return new JBossLoadTimeWeaver(classLoader);
}
else if (name.startsWith("com.ibm.ws.classloader")) {
return new WebSphereLoadTimeWeaver(classLoader);
}
else if (name.startsWith("weblogic")) {
return new WebLogicLoadTimeWeaver(classLoader);
}
}
catch (Exception ex) {
if (logger.isInfoEnabled()) {

View File

@@ -1,213 +0,0 @@
/*
* Copyright 2002-2020 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.ejb.access;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.rmi.RemoteException;
import javax.ejb.EJBHome;
import javax.ejb.EJBObject;
import javax.naming.NamingException;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.lang.Nullable;
import org.springframework.remoting.RemoteConnectFailureException;
import org.springframework.remoting.RemoteLookupFailureException;
/**
* Base class for interceptors proxying remote Stateless Session Beans.
* Designed for EJB 2.x, but works for EJB 3 Session Beans as well.
*
* <p>Such an interceptor must be the last interceptor in the advice chain.
* In this case, there is no target object.
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public abstract class AbstractRemoteSlsbInvokerInterceptor extends AbstractSlsbInvokerInterceptor {
private boolean refreshHomeOnConnectFailure = false;
private volatile boolean homeAsComponent;
/**
* Set whether to refresh the EJB home on connect failure.
* Default is "false".
* <p>Can be turned on to allow for hot restart of the EJB server.
* If a cached EJB home throws an RMI exception that indicates a
* remote connect failure, a fresh home will be fetched and the
* invocation will be retried.
* @see java.rmi.ConnectException
* @see java.rmi.ConnectIOException
* @see java.rmi.NoSuchObjectException
*/
public void setRefreshHomeOnConnectFailure(boolean refreshHomeOnConnectFailure) {
this.refreshHomeOnConnectFailure = refreshHomeOnConnectFailure;
}
@Override
protected boolean isHomeRefreshable() {
return this.refreshHomeOnConnectFailure;
}
/**
* Check for EJB3-style home object that serves as EJB component directly.
*/
@Override
protected Method getCreateMethod(Object home) throws EjbAccessException {
if (this.homeAsComponent) {
return null;
}
if (!(home instanceof EJBHome)) {
// An EJB3 Session Bean...
this.homeAsComponent = true;
return null;
}
return super.getCreateMethod(home);
}
/**
* Fetches an EJB home object and delegates to {@code doInvoke}.
* <p>If configured to refresh on connect failure, it will call
* {@link #refreshAndRetry} on corresponding RMI exceptions.
* @see #getHome
* @see #doInvoke
* @see #refreshAndRetry
*/
@Override
@Nullable
public Object invokeInContext(MethodInvocation invocation) throws Throwable {
try {
return doInvoke(invocation);
}
catch (RemoteConnectFailureException ex) {
return handleRemoteConnectFailure(invocation, ex);
}
catch (RemoteException ex) {
if (isConnectFailure(ex)) {
return handleRemoteConnectFailure(invocation, ex);
}
else {
throw ex;
}
}
}
/**
* Determine whether the given RMI exception indicates a connect failure.
* <p>The default implementation delegates to RmiClientInterceptorUtils.
* @param ex the RMI exception to check
* @return whether the exception should be treated as connect failure
* @see org.springframework.remoting.rmi.RmiClientInterceptorUtils#isConnectFailure
*/
@SuppressWarnings("deprecation")
protected boolean isConnectFailure(RemoteException ex) {
return org.springframework.remoting.rmi.RmiClientInterceptorUtils.isConnectFailure(ex);
}
@Nullable
private Object handleRemoteConnectFailure(MethodInvocation invocation, Exception ex) throws Throwable {
if (this.refreshHomeOnConnectFailure) {
if (logger.isDebugEnabled()) {
logger.debug("Could not connect to remote EJB [" + getJndiName() + "] - retrying", ex);
}
else if (logger.isWarnEnabled()) {
logger.warn("Could not connect to remote EJB [" + getJndiName() + "] - retrying");
}
return refreshAndRetry(invocation);
}
else {
throw ex;
}
}
/**
* Refresh the EJB home object and retry the given invocation.
* Called by invoke on connect failure.
* @param invocation the AOP method invocation
* @return the invocation result, if any
* @throws Throwable in case of invocation failure
* @see #invoke
*/
@Nullable
protected Object refreshAndRetry(MethodInvocation invocation) throws Throwable {
try {
refreshHome();
}
catch (NamingException ex) {
throw new RemoteLookupFailureException("Failed to locate remote EJB [" + getJndiName() + "]", ex);
}
return doInvoke(invocation);
}
/**
* Perform the given invocation on the current EJB home.
* Template method to be implemented by subclasses.
* @param invocation the AOP method invocation
* @return the invocation result, if any
* @throws Throwable in case of invocation failure
* @see #getHome
* @see #newSessionBeanInstance
*/
@Nullable
protected abstract Object doInvoke(MethodInvocation invocation) throws Throwable;
/**
* Return a new instance of the stateless session bean.
* To be invoked by concrete remote SLSB invoker subclasses.
* <p>Can be overridden to change the algorithm.
* @throws NamingException if thrown by JNDI
* @throws InvocationTargetException if thrown by the create method
* @see #create
*/
protected Object newSessionBeanInstance() throws NamingException, InvocationTargetException {
if (logger.isDebugEnabled()) {
logger.debug("Trying to create reference to remote EJB");
}
Object ejbInstance = create();
if (logger.isDebugEnabled()) {
logger.debug("Obtained reference to remote EJB: " + ejbInstance);
}
return ejbInstance;
}
/**
* Remove the given EJB instance.
* To be invoked by concrete remote SLSB invoker subclasses.
* @param ejb the EJB instance to remove
* @see javax.ejb.EJBObject#remove
*/
protected void removeSessionBeanInstance(@Nullable EJBObject ejb) {
if (ejb != null && !this.homeAsComponent) {
try {
ejb.remove();
}
catch (Throwable ex) {
logger.warn("Could not invoke 'remove' on remote EJB proxy", ex);
}
}
}
}

View File

@@ -1,238 +0,0 @@
/*
* Copyright 2002-2018 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.ejb.access;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.naming.Context;
import javax.naming.NamingException;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.jndi.JndiObjectLocator;
import org.springframework.lang.Nullable;
/**
* Base class for AOP interceptors invoking local or remote Stateless Session Beans.
* Designed for EJB 2.x, but works for EJB 3 Session Beans as well.
*
* <p>Such an interceptor must be the last interceptor in the advice chain.
* In this case, there is no direct target object: The call is handled in a
* special way, getting executed on an EJB instance retrieved via an EJB home.
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public abstract class AbstractSlsbInvokerInterceptor extends JndiObjectLocator
implements MethodInterceptor {
private boolean lookupHomeOnStartup = true;
private boolean cacheHome = true;
private boolean exposeAccessContext = false;
/**
* The EJB's home object, potentially cached.
* The type must be Object as it could be either EJBHome or EJBLocalHome.
*/
@Nullable
private Object cachedHome;
/**
* The no-arg create() method required on EJB homes, potentially cached.
*/
@Nullable
private Method createMethod;
private final Object homeMonitor = new Object();
/**
* Set whether to look up the EJB home object on startup.
* Default is "true".
* <p>Can be turned off to allow for late start of the EJB server.
* In this case, the EJB home object will be fetched on first access.
* @see #setCacheHome
*/
public void setLookupHomeOnStartup(boolean lookupHomeOnStartup) {
this.lookupHomeOnStartup = lookupHomeOnStartup;
}
/**
* Set whether to cache the EJB home object once it has been located.
* Default is "true".
* <p>Can be turned off to allow for hot restart of the EJB server.
* In this case, the EJB home object will be fetched for each invocation.
* @see #setLookupHomeOnStartup
*/
public void setCacheHome(boolean cacheHome) {
this.cacheHome = cacheHome;
}
/**
* Set whether to expose the JNDI environment context for all access to the target
* EJB, i.e. for all method invocations on the exposed object reference.
* <p>Default is "false", i.e. to only expose the JNDI context for object lookup.
* Switch this flag to "true" in order to expose the JNDI environment (including
* the authorization context) for each EJB invocation, as needed by WebLogic
* for EJBs with authorization requirements.
*/
public void setExposeAccessContext(boolean exposeAccessContext) {
this.exposeAccessContext = exposeAccessContext;
}
/**
* Fetches EJB home on startup, if necessary.
* @see #setLookupHomeOnStartup
* @see #refreshHome
*/
@Override
public void afterPropertiesSet() throws NamingException {
super.afterPropertiesSet();
if (this.lookupHomeOnStartup) {
// look up EJB home and create method
refreshHome();
}
}
/**
* Refresh the cached home object, if applicable.
* Also caches the create method on the home object.
* @throws NamingException if thrown by the JNDI lookup
* @see #lookup
* @see #getCreateMethod
*/
protected void refreshHome() throws NamingException {
synchronized (this.homeMonitor) {
Object home = lookup();
if (this.cacheHome) {
this.cachedHome = home;
this.createMethod = getCreateMethod(home);
}
}
}
/**
* Determine the create method of the given EJB home object.
* @param home the EJB home object
* @return the create method
* @throws EjbAccessException if the method couldn't be retrieved
*/
@Nullable
protected Method getCreateMethod(Object home) throws EjbAccessException {
try {
// Cache the EJB create() method that must be declared on the home interface.
return home.getClass().getMethod("create");
}
catch (NoSuchMethodException ex) {
throw new EjbAccessException("EJB home [" + home + "] has no no-arg create() method");
}
}
/**
* Return the EJB home object to use. Called for each invocation.
* <p>Default implementation returns the home created on initialization,
* if any; else, it invokes lookup to get a new proxy for each invocation.
* <p>Can be overridden in subclasses, for example to cache a home object
* for a given amount of time before recreating it, or to test the home
* object whether it is still alive.
* @return the EJB home object to use for an invocation
* @throws NamingException if proxy creation failed
* @see #lookup
* @see #getCreateMethod
*/
protected Object getHome() throws NamingException {
if (!this.cacheHome || (this.lookupHomeOnStartup && !isHomeRefreshable())) {
return (this.cachedHome != null ? this.cachedHome : lookup());
}
else {
synchronized (this.homeMonitor) {
if (this.cachedHome == null) {
this.cachedHome = lookup();
this.createMethod = getCreateMethod(this.cachedHome);
}
return this.cachedHome;
}
}
}
/**
* Return whether the cached EJB home object is potentially
* subject to on-demand refreshing. Default is "false".
*/
protected boolean isHomeRefreshable() {
return false;
}
/**
* Prepares the thread context if necessary, and delegates to
* {@link #invokeInContext}.
*/
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
Context ctx = (this.exposeAccessContext ? getJndiTemplate().getContext() : null);
try {
return invokeInContext(invocation);
}
finally {
getJndiTemplate().releaseContext(ctx);
}
}
/**
* Perform the given invocation on the current EJB home,
* within the thread context being prepared accordingly.
* Template method to be implemented by subclasses.
* @param invocation the AOP method invocation
* @return the invocation result, if any
* @throws Throwable in case of invocation failure
*/
@Nullable
protected abstract Object invokeInContext(MethodInvocation invocation) throws Throwable;
/**
* Invokes the {@code create()} method on the cached EJB home object.
* @return a new EJBObject or EJBLocalObject
* @throws NamingException if thrown by JNDI
* @throws InvocationTargetException if thrown by the create method
*/
protected Object create() throws NamingException, InvocationTargetException {
try {
Object home = getHome();
Method createMethodToUse = this.createMethod;
if (createMethodToUse == null) {
createMethodToUse = getCreateMethod(home);
}
if (createMethodToUse == null) {
return home;
}
// Invoke create() method on EJB home object.
return createMethodToUse.invoke(home, (Object[]) null);
}
catch (IllegalAccessException ex) {
throw new EjbAccessException("Could not access EJB home create() method", ex);
}
}
}

View File

@@ -1,47 +0,0 @@
/*
* Copyright 2002-2012 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.ejb.access;
import org.springframework.core.NestedRuntimeException;
/**
* Exception that gets thrown when an EJB stub cannot be accessed properly.
*
* @author Juergen Hoeller
* @since 2.0
*/
@SuppressWarnings("serial")
public class EjbAccessException extends NestedRuntimeException {
/**
* Constructor for EjbAccessException.
* @param msg the detail message
*/
public EjbAccessException(String msg) {
super(msg);
}
/**
* Constructor for EjbAccessException.
* @param msg the detail message
* @param cause the root cause
*/
public EjbAccessException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@@ -1,179 +0,0 @@
/*
* Copyright 2002-2020 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.ejb.access;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.ejb.CreateException;
import javax.ejb.EJBLocalHome;
import javax.ejb.EJBLocalObject;
import javax.naming.NamingException;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.lang.Nullable;
/**
* Invoker for a local Stateless Session Bean.
* Designed for EJB 2.x, but works for EJB 3 Session Beans as well.
*
* <p>Caches the home object, since a local EJB home can never go stale.
* See {@link org.springframework.jndi.JndiObjectLocator} for info on
* how to specify the JNDI location of the target EJB.
*
* <p>In a bean container, this class is normally best used as a singleton. However,
* if that bean container pre-instantiates singletons (as do the XML ApplicationContext
* variants) you may have a problem if the bean container is loaded before the EJB
* container loads the target EJB. That is because by default the JNDI lookup will be
* performed in the init method of this class and cached, but the EJB will not have been
* bound at the target location yet. The best solution is to set the lookupHomeOnStartup
* property to false, in which case the home will be fetched on first access to the EJB.
* (This flag is only true by default for backwards compatibility reasons).
*
* @author Rod Johnson
* @author Juergen Hoeller
* @see AbstractSlsbInvokerInterceptor#setLookupHomeOnStartup
* @see AbstractSlsbInvokerInterceptor#setCacheHome
*/
public class LocalSlsbInvokerInterceptor extends AbstractSlsbInvokerInterceptor {
private volatile boolean homeAsComponent;
/**
* This implementation "creates" a new EJB instance for each invocation.
* Can be overridden for custom invocation strategies.
* <p>Alternatively, override {@link #getSessionBeanInstance} and
* {@link #releaseSessionBeanInstance} to change EJB instance creation,
* for example to hold a single shared EJB instance.
*/
@Override
@Nullable
public Object invokeInContext(MethodInvocation invocation) throws Throwable {
Object ejb = null;
try {
ejb = getSessionBeanInstance();
Method method = invocation.getMethod();
if (method.getDeclaringClass().isInstance(ejb)) {
// directly implemented
return method.invoke(ejb, invocation.getArguments());
}
else {
// not directly implemented
Method ejbMethod = ejb.getClass().getMethod(method.getName(), method.getParameterTypes());
return ejbMethod.invoke(ejb, invocation.getArguments());
}
}
catch (InvocationTargetException ex) {
Throwable targetEx = ex.getTargetException();
if (logger.isDebugEnabled()) {
logger.debug("Method of local EJB [" + getJndiName() + "] threw exception", targetEx);
}
if (targetEx instanceof CreateException) {
throw new EjbAccessException("Could not create local EJB [" + getJndiName() + "]", targetEx);
}
else {
throw targetEx;
}
}
catch (NamingException ex) {
throw new EjbAccessException("Failed to locate local EJB [" + getJndiName() + "]", ex);
}
catch (IllegalAccessException ex) {
throw new EjbAccessException("Could not access method [" + invocation.getMethod().getName() +
"] of local EJB [" + getJndiName() + "]", ex);
}
finally {
if (ejb instanceof EJBLocalObject) {
releaseSessionBeanInstance((EJBLocalObject) ejb);
}
}
}
/**
* Check for EJB3-style home object that serves as EJB component directly.
*/
@Override
protected Method getCreateMethod(Object home) throws EjbAccessException {
if (this.homeAsComponent) {
return null;
}
if (!(home instanceof EJBLocalHome)) {
// An EJB3 Session Bean...
this.homeAsComponent = true;
return null;
}
return super.getCreateMethod(home);
}
/**
* Return an EJB instance to delegate the call to.
* Default implementation delegates to newSessionBeanInstance.
* @throws NamingException if thrown by JNDI
* @throws InvocationTargetException if thrown by the create method
* @see #newSessionBeanInstance
*/
protected Object getSessionBeanInstance() throws NamingException, InvocationTargetException {
return newSessionBeanInstance();
}
/**
* Release the given EJB instance.
* Default implementation delegates to removeSessionBeanInstance.
* @param ejb the EJB instance to release
* @see #removeSessionBeanInstance
*/
protected void releaseSessionBeanInstance(EJBLocalObject ejb) {
removeSessionBeanInstance(ejb);
}
/**
* Return a new instance of the stateless session bean.
* Can be overridden to change the algorithm.
* @throws NamingException if thrown by JNDI
* @throws InvocationTargetException if thrown by the create method
* @see #create
*/
protected Object newSessionBeanInstance() throws NamingException, InvocationTargetException {
if (logger.isDebugEnabled()) {
logger.debug("Trying to create reference to local EJB");
}
Object ejbInstance = create();
if (logger.isDebugEnabled()) {
logger.debug("Obtained reference to local EJB: " + ejbInstance);
}
return ejbInstance;
}
/**
* Remove the given EJB instance.
* @param ejb the EJB instance to remove
* @see javax.ejb.EJBLocalObject#remove()
*/
protected void removeSessionBeanInstance(@Nullable EJBLocalObject ejb) {
if (ejb != null && !this.homeAsComponent) {
try {
ejb.remove();
}
catch (Throwable ex) {
logger.warn("Could not invoke 'remove' on local EJB proxy", ex);
}
}
}
}

View File

@@ -1,116 +0,0 @@
/*
* Copyright 2002-2018 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.ejb.access;
import javax.naming.NamingException;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
* Convenient {@link FactoryBean} for local Stateless Session Bean (SLSB) proxies.
* Designed for EJB 2.x, but works for EJB 3 Session Beans as well.
*
* <p>See {@link org.springframework.jndi.JndiObjectLocator} for info on
* how to specify the JNDI location of the target EJB.
*
* <p>If you want control over interceptor chaining, use an AOP ProxyFactoryBean
* with LocalSlsbInvokerInterceptor rather than rely on this class.
*
* <p>In a bean container, this class is normally best used as a singleton. However,
* if that bean container pre-instantiates singletons (as do the XML ApplicationContext
* variants) you may have a problem if the bean container is loaded before the EJB
* container loads the target EJB. That is because by default the JNDI lookup will be
* performed in the init method of this class and cached, but the EJB will not have been
* bound at the target location yet. The best solution is to set the "lookupHomeOnStartup"
* property to "false", in which case the home will be fetched on first access to the EJB.
* (This flag is only true by default for backwards compatibility reasons).
*
* @author Rod Johnson
* @author Colin Sampaleanu
* @since 09.05.2003
* @see AbstractSlsbInvokerInterceptor#setLookupHomeOnStartup
* @see AbstractSlsbInvokerInterceptor#setCacheHome
*/
public class LocalStatelessSessionProxyFactoryBean extends LocalSlsbInvokerInterceptor
implements FactoryBean<Object>, BeanClassLoaderAware {
/** The business interface of the EJB we're proxying. */
@Nullable
private Class<?> businessInterface;
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
/** EJBLocalObject. */
@Nullable
private Object proxy;
/**
* Set the business interface of the EJB we're proxying.
* This will normally be a super-interface of the EJB local component interface.
* Using a business methods interface is a best practice when implementing EJBs.
* @param businessInterface set the business interface of the EJB
*/
public void setBusinessInterface(@Nullable Class<?> businessInterface) {
this.businessInterface = businessInterface;
}
/**
* Return the business interface of the EJB we're proxying.
*/
@Nullable
public Class<?> getBusinessInterface() {
return this.businessInterface;
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
@Override
public void afterPropertiesSet() throws NamingException {
super.afterPropertiesSet();
if (this.businessInterface == null) {
throw new IllegalArgumentException("businessInterface is required");
}
this.proxy = new ProxyFactory(this.businessInterface, this).getProxy(this.beanClassLoader);
}
@Override
@Nullable
public Object getObject() {
return this.proxy;
}
@Override
public Class<?> getObjectType() {
return this.businessInterface;
}
@Override
public boolean isSingleton() {
return true;
}
}

View File

@@ -1,188 +0,0 @@
/*
* Copyright 2002-2017 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.ejb.access;
import java.lang.reflect.InvocationTargetException;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBObject;
import javax.naming.NamingException;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.lang.Nullable;
import org.springframework.remoting.RemoteLookupFailureException;
/**
* Basic invoker for a remote Stateless Session Bean.
* Designed for EJB 2.x, but works for EJB 3 Session Beans as well.
*
* <p>"Creates" a new EJB instance for each invocation, or caches the session
* bean instance for all invocations (see {@link #setCacheSessionBean}).
* See {@link org.springframework.jndi.JndiObjectLocator} for info on
* how to specify the JNDI location of the target EJB.
*
* <p>In a bean container, this class is normally best used as a singleton. However,
* if that bean container pre-instantiates singletons (as do the XML ApplicationContext
* variants) you may have a problem if the bean container is loaded before the EJB
* container loads the target EJB. That is because by default the JNDI lookup will be
* performed in the init method of this class and cached, but the EJB will not have been
* bound at the target location yet. The best solution is to set the "lookupHomeOnStartup"
* property to "false", in which case the home will be fetched on first access to the EJB.
* (This flag is only true by default for backwards compatibility reasons).
*
* <p>This invoker is typically used with an RMI business interface, which serves
* as super-interface of the EJB component interface. Alternatively, this invoker
* can also proxy a remote SLSB with a matching non-RMI business interface, i.e. an
* interface that mirrors the EJB business methods but does not declare RemoteExceptions.
* In the latter case, RemoteExceptions thrown by the EJB stub will automatically get
* converted to Spring's unchecked RemoteAccessException.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 09.05.2003
* @see org.springframework.remoting.RemoteAccessException
* @see AbstractSlsbInvokerInterceptor#setLookupHomeOnStartup
* @see AbstractSlsbInvokerInterceptor#setCacheHome
* @see AbstractRemoteSlsbInvokerInterceptor#setRefreshHomeOnConnectFailure
*/
public class SimpleRemoteSlsbInvokerInterceptor extends AbstractRemoteSlsbInvokerInterceptor
implements DisposableBean {
private boolean cacheSessionBean = false;
@Nullable
private Object beanInstance;
private final Object beanInstanceMonitor = new Object();
/**
* Set whether to cache the actual session bean object.
* <p>Off by default for standard EJB compliance. Turn this flag
* on to optimize session bean access for servers that are
* known to allow for caching the actual session bean object.
* @see #setCacheHome
*/
public void setCacheSessionBean(boolean cacheSessionBean) {
this.cacheSessionBean = cacheSessionBean;
}
/**
* This implementation "creates" a new EJB instance for each invocation.
* Can be overridden for custom invocation strategies.
* <p>Alternatively, override {@link #getSessionBeanInstance} and
* {@link #releaseSessionBeanInstance} to change EJB instance creation,
* for example to hold a single shared EJB component instance.
*/
@Override
@Nullable
@SuppressWarnings("deprecation")
protected Object doInvoke(MethodInvocation invocation) throws Throwable {
Object ejb = null;
try {
ejb = getSessionBeanInstance();
return org.springframework.remoting.rmi.RmiClientInterceptorUtils.invokeRemoteMethod(invocation, ejb);
}
catch (NamingException ex) {
throw new RemoteLookupFailureException("Failed to locate remote EJB [" + getJndiName() + "]", ex);
}
catch (InvocationTargetException ex) {
Throwable targetEx = ex.getTargetException();
if (targetEx instanceof RemoteException) {
RemoteException rex = (RemoteException) targetEx;
throw org.springframework.remoting.rmi.RmiClientInterceptorUtils.convertRmiAccessException(
invocation.getMethod(), rex, isConnectFailure(rex), getJndiName());
}
else if (targetEx instanceof CreateException) {
throw org.springframework.remoting.rmi.RmiClientInterceptorUtils.convertRmiAccessException(
invocation.getMethod(), targetEx, "Could not create remote EJB [" + getJndiName() + "]");
}
throw targetEx;
}
finally {
if (ejb instanceof EJBObject) {
releaseSessionBeanInstance((EJBObject) ejb);
}
}
}
/**
* Return an EJB component instance to delegate the call to.
* <p>The default implementation delegates to {@link #newSessionBeanInstance}.
* @return the EJB component instance
* @throws NamingException if thrown by JNDI
* @throws InvocationTargetException if thrown by the create method
* @see #newSessionBeanInstance
*/
protected Object getSessionBeanInstance() throws NamingException, InvocationTargetException {
if (this.cacheSessionBean) {
synchronized (this.beanInstanceMonitor) {
if (this.beanInstance == null) {
this.beanInstance = newSessionBeanInstance();
}
return this.beanInstance;
}
}
else {
return newSessionBeanInstance();
}
}
/**
* Release the given EJB instance.
* <p>The default implementation delegates to {@link #removeSessionBeanInstance}.
* @param ejb the EJB component instance to release
* @see #removeSessionBeanInstance
*/
protected void releaseSessionBeanInstance(EJBObject ejb) {
if (!this.cacheSessionBean) {
removeSessionBeanInstance(ejb);
}
}
/**
* Reset the cached session bean instance, if necessary.
*/
@Override
protected void refreshHome() throws NamingException {
super.refreshHome();
if (this.cacheSessionBean) {
synchronized (this.beanInstanceMonitor) {
this.beanInstance = null;
}
}
}
/**
* Remove the cached session bean instance, if necessary.
*/
@Override
public void destroy() {
if (this.cacheSessionBean) {
synchronized (this.beanInstanceMonitor) {
if (this.beanInstance instanceof EJBObject) {
removeSessionBeanInstance((EJBObject) this.beanInstance);
}
}
}
}
}

View File

@@ -1,130 +0,0 @@
/*
* Copyright 2002-2018 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.ejb.access;
import javax.naming.NamingException;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
* Convenient {@link FactoryBean} for remote SLSB proxies.
* Designed for EJB 2.x, but works for EJB 3 Session Beans as well.
*
* <p>See {@link org.springframework.jndi.JndiObjectLocator} for info on
* how to specify the JNDI location of the target EJB.
*
* <p>If you want control over interceptor chaining, use an AOP ProxyFactoryBean
* with SimpleRemoteSlsbInvokerInterceptor rather than rely on this class.
*
* <p>In a bean container, this class is normally best used as a singleton. However,
* if that bean container pre-instantiates singletons (as do the XML ApplicationContext
* variants) you may have a problem if the bean container is loaded before the EJB
* container loads the target EJB. That is because by default the JNDI lookup will be
* performed in the init method of this class and cached, but the EJB will not have been
* bound at the target location yet. The best solution is to set the lookupHomeOnStartup
* property to false, in which case the home will be fetched on first access to the EJB.
* (This flag is only true by default for backwards compatibility reasons).
*
* <p>This proxy factory is typically used with an RMI business interface, which serves
* as super-interface of the EJB component interface. Alternatively, this factory
* can also proxy a remote SLSB with a matching non-RMI business interface, i.e. an
* interface that mirrors the EJB business methods but does not declare RemoteExceptions.
* In the latter case, RemoteExceptions thrown by the EJB stub will automatically get
* converted to Spring's unchecked RemoteAccessException.
*
* @author Rod Johnson
* @author Colin Sampaleanu
* @author Juergen Hoeller
* @since 09.05.2003
* @see org.springframework.remoting.RemoteAccessException
* @see AbstractSlsbInvokerInterceptor#setLookupHomeOnStartup
* @see AbstractSlsbInvokerInterceptor#setCacheHome
* @see AbstractRemoteSlsbInvokerInterceptor#setRefreshHomeOnConnectFailure
*/
public class SimpleRemoteStatelessSessionProxyFactoryBean extends SimpleRemoteSlsbInvokerInterceptor
implements FactoryBean<Object>, BeanClassLoaderAware {
/** The business interface of the EJB we're proxying. */
@Nullable
private Class<?> businessInterface;
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
/** EJBObject. */
@Nullable
private Object proxy;
/**
* Set the business interface of the EJB we're proxying.
* This will normally be a super-interface of the EJB remote component interface.
* Using a business methods interface is a best practice when implementing EJBs.
* <p>You can also specify a matching non-RMI business interface, i.e. an interface
* that mirrors the EJB business methods but does not declare RemoteExceptions.
* In this case, RemoteExceptions thrown by the EJB stub will automatically get
* converted to Spring's generic RemoteAccessException.
* @param businessInterface the business interface of the EJB
*/
public void setBusinessInterface(@Nullable Class<?> businessInterface) {
this.businessInterface = businessInterface;
}
/**
* Return the business interface of the EJB we're proxying.
*/
@Nullable
public Class<?> getBusinessInterface() {
return this.businessInterface;
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
@Override
public void afterPropertiesSet() throws NamingException {
super.afterPropertiesSet();
if (this.businessInterface == null) {
throw new IllegalArgumentException("businessInterface is required");
}
this.proxy = new ProxyFactory(this.businessInterface, this).getProxy(this.beanClassLoader);
}
@Override
@Nullable
public Object getObject() {
return this.proxy;
}
@Override
public Class<?> getObjectType() {
return this.businessInterface;
}
@Override
public boolean isSingleton() {
return true;
}
}

View File

@@ -1,27 +0,0 @@
/**
* This package contains classes that allow easy access to EJBs.
* The basis are AOP interceptors run before and after the EJB invocation.
* In particular, the classes in this package allow transparent access
* to stateless session beans (SLSBs) with local interfaces, avoiding
* the need for application code using them to use EJB-specific APIs
* and JNDI lookups, and work with business interfaces that could be
* implemented without using EJB. This provides a valuable decoupling
* of client (such as web components) and business objects (which may
* or may not be EJBs). This gives us the choice of introducing EJB
* into an application (or removing EJB from an application) without
* affecting code using business objects.
*
* <p>The motivation for the classes in this package is discussed in Chapter 11 of
* <a href="https://www.amazon.com/exec/obidos/tg/detail/-/0764543857/">Expert One-On-One J2EE Design and Development</a>
* by Rod Johnson (Wrox, 2002).
*
* <p>However, the implementation and naming of classes in this package has changed.
* It now uses FactoryBeans and AOP, rather than the custom bean definitions described in
* <i>Expert One-on-One J2EE</i>.
*/
@NonNullApi
@NonNullFields
package org.springframework.ejb.access;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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.
@@ -18,12 +18,12 @@ package org.springframework.ejb.config;
import org.w3c.dom.Element;
import org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean;
import org.springframework.jndi.JndiObjectFactoryBean;
/**
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser}
* implementation for parsing '{@code local-slsb}' tags and
* creating {@link LocalStatelessSessionProxyFactoryBean} definitions.
* creating plain {@link JndiObjectFactoryBean} definitions.
*
* @author Rob Harrop
* @author Juergen Hoeller
@@ -32,8 +32,8 @@ import org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean;
class LocalStatelessSessionBeanDefinitionParser extends AbstractJndiLocatingBeanDefinitionParser {
@Override
protected String getBeanClassName(Element element) {
return "org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean";
protected Class<?> getBeanClass(Element element) {
return JndiObjectFactoryBean.class;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 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.
@@ -18,12 +18,12 @@ package org.springframework.ejb.config;
import org.w3c.dom.Element;
import org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean;
import org.springframework.jndi.JndiObjectFactoryBean;
/**
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser}
* implementation for parsing '{@code remote-slsb}' tags and
* creating {@link SimpleRemoteStatelessSessionProxyFactoryBean} definitions.
* creating plain {@link JndiObjectFactoryBean} definitions.
*
* @author Rob Harrop
* @author Juergen Hoeller
@@ -32,8 +32,8 @@ import org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBe
class RemoteStatelessSessionBeanDefinitionParser extends AbstractJndiLocatingBeanDefinitionParser {
@Override
protected String getBeanClassName(Element element) {
return "org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean";
protected Class<?> getBeanClass(Element element) {
return JndiObjectFactoryBean.class;
}
}

View File

@@ -1,5 +1,5 @@
/**
* Support package for EJB/Java EE-related configuration,
* Support package for EJB/Jakarta EE-related configuration,
* with XML schema being the primary configuration format.
*/
@NonNullApi

View File

@@ -1,117 +0,0 @@
/*
* Copyright 2002-2018 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.instrument.classloading.weblogic;
import java.lang.instrument.ClassFileTransformer;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.springframework.util.Assert;
/**
* Reflective wrapper around a WebLogic 10 class loader. Used to
* encapsulate the classloader-specific methods (discovered and
* called through reflection) from the load-time weaver.
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 2.5
*/
class WebLogicClassLoaderAdapter {
private static final String GENERIC_CLASS_LOADER_NAME = "weblogic.utils.classloaders.GenericClassLoader";
private static final String CLASS_PRE_PROCESSOR_NAME = "weblogic.utils.classloaders.ClassPreProcessor";
private final ClassLoader classLoader;
private final Class<?> wlPreProcessorClass;
private final Method addPreProcessorMethod;
private final Method getClassFinderMethod;
private final Method getParentMethod;
private final Constructor<?> wlGenericClassLoaderConstructor;
public WebLogicClassLoaderAdapter(ClassLoader classLoader) {
Class<?> wlGenericClassLoaderClass;
try {
wlGenericClassLoaderClass = classLoader.loadClass(GENERIC_CLASS_LOADER_NAME);
this.wlPreProcessorClass = classLoader.loadClass(CLASS_PRE_PROCESSOR_NAME);
this.addPreProcessorMethod = classLoader.getClass().getMethod(
"addInstanceClassPreProcessor", this.wlPreProcessorClass);
this.getClassFinderMethod = classLoader.getClass().getMethod("getClassFinder");
this.getParentMethod = classLoader.getClass().getMethod("getParent");
this.wlGenericClassLoaderConstructor = wlGenericClassLoaderClass.getConstructor(
this.getClassFinderMethod.getReturnType(), ClassLoader.class);
}
catch (Throwable ex) {
throw new IllegalStateException(
"Could not initialize WebLogic LoadTimeWeaver because WebLogic 10 API classes are not available", ex);
}
if (!wlGenericClassLoaderClass.isInstance(classLoader)) {
throw new IllegalArgumentException(
"ClassLoader must be an instance of [" + wlGenericClassLoaderClass.getName() + "]: " + classLoader);
}
this.classLoader = classLoader;
}
public void addTransformer(ClassFileTransformer transformer) {
Assert.notNull(transformer, "ClassFileTransformer must not be null");
try {
InvocationHandler adapter = new WebLogicClassPreProcessorAdapter(transformer, this.classLoader);
Object adapterInstance = Proxy.newProxyInstance(this.wlPreProcessorClass.getClassLoader(),
new Class<?>[] {this.wlPreProcessorClass}, adapter);
this.addPreProcessorMethod.invoke(this.classLoader, adapterInstance);
}
catch (InvocationTargetException ex) {
throw new IllegalStateException("WebLogic addInstanceClassPreProcessor method threw exception", ex.getCause());
}
catch (Throwable ex) {
throw new IllegalStateException("Could not invoke WebLogic addInstanceClassPreProcessor method", ex);
}
}
public ClassLoader getClassLoader() {
return this.classLoader;
}
public ClassLoader getThrowawayClassLoader() {
try {
Object classFinder = this.getClassFinderMethod.invoke(this.classLoader);
Object parent = this.getParentMethod.invoke(this.classLoader);
// arguments for 'clone'-like method
return (ClassLoader) this.wlGenericClassLoaderConstructor.newInstance(classFinder, parent);
}
catch (InvocationTargetException ex) {
throw new IllegalStateException("WebLogic GenericClassLoader constructor failed", ex.getCause());
}
catch (Throwable ex) {
throw new IllegalStateException("Could not construct WebLogic GenericClassLoader", ex);
}
}
}

View File

@@ -1,97 +0,0 @@
/*
* Copyright 2002-2017 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.instrument.classloading.weblogic;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Hashtable;
import org.springframework.lang.Nullable;
/**
* Adapter that implements WebLogic ClassPreProcessor interface, delegating to a
* standard JDK {@link ClassFileTransformer} underneath.
*
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is
* being used.
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 2.5
*/
class WebLogicClassPreProcessorAdapter implements InvocationHandler {
private final ClassFileTransformer transformer;
private final ClassLoader loader;
/**
* Construct a new {@link WebLogicClassPreProcessorAdapter}.
*/
public WebLogicClassPreProcessorAdapter(ClassFileTransformer transformer, ClassLoader loader) {
this.transformer = transformer;
this.loader = loader;
}
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String name = method.getName();
if ("equals".equals(name)) {
return (proxy == args[0]);
}
else if ("hashCode".equals(name)) {
return hashCode();
}
else if ("toString".equals(name)) {
return toString();
}
else if ("initialize".equals(name)) {
initialize((Hashtable<?, ?>) args[0]);
return null;
}
else if ("preProcess".equals(name)) {
return preProcess((String) args[0], (byte[]) args[1]);
}
else {
throw new IllegalArgumentException("Unknown method: " + method);
}
}
public void initialize(Hashtable<?, ?> params) {
}
public byte[] preProcess(String className, byte[] classBytes) {
try {
byte[] result = this.transformer.transform(this.loader, className, null, null, classBytes);
return (result != null ? result : classBytes);
}
catch (IllegalClassFormatException ex) {
throw new IllegalStateException("Cannot transform due to illegal class format", ex);
}
}
@Override
public String toString() {
return getClass().getName() + " for transformer: " + this.transformer;
}
}

View File

@@ -1,78 +0,0 @@
/*
* Copyright 2002-2016 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.instrument.classloading.weblogic;
import java.lang.instrument.ClassFileTransformer;
import org.springframework.core.OverridingClassLoader;
import org.springframework.instrument.classloading.LoadTimeWeaver;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* {@link LoadTimeWeaver} implementation for WebLogic's instrumentable
* ClassLoader.
*
* <p><b>NOTE:</b> Requires BEA WebLogic version 10 or higher.
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 2.5
*/
public class WebLogicLoadTimeWeaver implements LoadTimeWeaver {
private final WebLogicClassLoaderAdapter classLoader;
/**
* Creates a new instance of the {@link WebLogicLoadTimeWeaver} class using
* the default {@link ClassLoader class loader}.
* @see org.springframework.util.ClassUtils#getDefaultClassLoader()
*/
public WebLogicLoadTimeWeaver() {
this(ClassUtils.getDefaultClassLoader());
}
/**
* Creates a new instance of the {@link WebLogicLoadTimeWeaver} class using
* the supplied {@link ClassLoader}.
* @param classLoader the {@code ClassLoader} to delegate to for weaving
*/
public WebLogicLoadTimeWeaver(@Nullable ClassLoader classLoader) {
Assert.notNull(classLoader, "ClassLoader must not be null");
this.classLoader = new WebLogicClassLoaderAdapter(classLoader);
}
@Override
public void addTransformer(ClassFileTransformer transformer) {
this.classLoader.addTransformer(transformer);
}
@Override
public ClassLoader getInstrumentableClassLoader() {
return this.classLoader.getClassLoader();
}
@Override
public ClassLoader getThrowawayClassLoader() {
return new OverridingClassLoader(this.classLoader.getClassLoader(),
this.classLoader.getThrowawayClassLoader());
}
}

View File

@@ -1,9 +0,0 @@
/**
* Support for class instrumentation on BEA WebLogic 10+.
*/
@NonNullApi
@NonNullFields
package org.springframework.instrument.classloading.weblogic;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;

View File

@@ -1,120 +0,0 @@
/*
* Copyright 2002-2018 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.instrument.classloading.websphere;
import java.lang.instrument.ClassFileTransformer;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import org.springframework.util.Assert;
/**
* Reflective wrapper around a WebSphere 7+ class loader. Used to
* encapsulate the classloader-specific methods (discovered and
* called through reflection) from the load-time weaver.
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3.1
*/
class WebSphereClassLoaderAdapter {
private static final String COMPOUND_CLASS_LOADER_NAME = "com.ibm.ws.classloader.CompoundClassLoader";
private static final String CLASS_PRE_PROCESSOR_NAME = "com.ibm.websphere.classloader.ClassLoaderInstancePreDefinePlugin";
private static final String PLUGINS_FIELD = "preDefinePlugins";
private ClassLoader classLoader;
private Class<?> wsPreProcessorClass;
private Method addPreDefinePlugin;
private Constructor<? extends ClassLoader> cloneConstructor;
private Field transformerList;
public WebSphereClassLoaderAdapter(ClassLoader classLoader) {
Class<?> wsCompoundClassLoaderClass;
try {
wsCompoundClassLoaderClass = classLoader.loadClass(COMPOUND_CLASS_LOADER_NAME);
this.cloneConstructor = classLoader.getClass().getDeclaredConstructor(wsCompoundClassLoaderClass);
this.cloneConstructor.setAccessible(true);
this.wsPreProcessorClass = classLoader.loadClass(CLASS_PRE_PROCESSOR_NAME);
this.addPreDefinePlugin = classLoader.getClass().getMethod("addPreDefinePlugin", this.wsPreProcessorClass);
this.transformerList = wsCompoundClassLoaderClass.getDeclaredField(PLUGINS_FIELD);
this.transformerList.setAccessible(true);
}
catch (Throwable ex) {
throw new IllegalStateException(
"Could not initialize WebSphere LoadTimeWeaver because WebSphere API classes are not available", ex);
}
if (!wsCompoundClassLoaderClass.isInstance(classLoader)) {
throw new IllegalArgumentException(
"ClassLoader must be an instance of [" + COMPOUND_CLASS_LOADER_NAME + "]: " + classLoader);
}
this.classLoader = classLoader;
}
public ClassLoader getClassLoader() {
return this.classLoader;
}
public void addTransformer(ClassFileTransformer transformer) {
Assert.notNull(transformer, "ClassFileTransformer must not be null");
try {
InvocationHandler adapter = new WebSphereClassPreDefinePlugin(transformer);
Object adapterInstance = Proxy.newProxyInstance(this.wsPreProcessorClass.getClassLoader(),
new Class<?>[] {this.wsPreProcessorClass}, adapter);
this.addPreDefinePlugin.invoke(this.classLoader, adapterInstance);
}
catch (InvocationTargetException ex) {
throw new IllegalStateException("WebSphere addPreDefinePlugin method threw exception", ex.getCause());
}
catch (Throwable ex) {
throw new IllegalStateException("Could not invoke WebSphere addPreDefinePlugin method", ex);
}
}
public ClassLoader getThrowawayClassLoader() {
try {
ClassLoader loader = this.cloneConstructor.newInstance(getClassLoader());
// Clear out the transformers (copied as well)
List<?> list = (List<?>) this.transformerList.get(loader);
list.clear();
return loader;
}
catch (InvocationTargetException ex) {
throw new IllegalStateException("WebSphere CompoundClassLoader constructor failed", ex.getCause());
}
catch (Throwable ex) {
throw new IllegalStateException("Could not construct WebSphere CompoundClassLoader", ex);
}
}
}

View File

@@ -1,95 +0,0 @@
/*
* Copyright 2002-2020 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.instrument.classloading.websphere;
import java.lang.instrument.ClassFileTransformer;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.security.CodeSource;
import org.springframework.util.FileCopyUtils;
/**
* Adapter that implements WebSphere 7.0 ClassPreProcessPlugin interface,
* delegating to a standard JDK {@link ClassFileTransformer} underneath.
*
* <p>To avoid compile time checks again the vendor API, a dynamic proxy is
* being used.
*
* @author Costin Leau
* @since 3.1
*/
class WebSphereClassPreDefinePlugin implements InvocationHandler {
private final ClassFileTransformer transformer;
/**
* Create a new {@link WebSphereClassPreDefinePlugin}.
* @param transformer the {@link ClassFileTransformer} to be adapted
* (must not be {@code null})
*/
public WebSphereClassPreDefinePlugin(ClassFileTransformer transformer) {
this.transformer = transformer;
ClassLoader classLoader = transformer.getClass().getClassLoader();
// First force the full class loading of the weaver by invoking transformation on a dummy class
try {
String dummyClass = Dummy.class.getName().replace('.', '/');
byte[] bytes = FileCopyUtils.copyToByteArray(classLoader.getResourceAsStream(dummyClass + ".class"));
transformer.transform(classLoader, dummyClass, null, null, bytes);
}
catch (Throwable ex) {
throw new IllegalArgumentException("Cannot load transformer", ex);
}
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
switch (method.getName()) {
case "equals":
return (proxy == args[0]);
case "hashCode":
return hashCode();
case "toString":
return toString();
case "transformClass":
return transform((String) args[0], (byte[]) args[1], (CodeSource) args[2], (ClassLoader) args[3]);
default:
throw new IllegalArgumentException("Unknown method: " + method);
}
}
protected byte[] transform(String className, byte[] classfileBuffer, CodeSource codeSource, ClassLoader classLoader)
throws Exception {
// NB: WebSphere passes className as "." without class while the transformer expects a VM "/" format
byte[] result = this.transformer.transform(classLoader, className.replace('.', '/'), null, null, classfileBuffer);
return (result != null ? result : classfileBuffer);
}
@Override
public String toString() {
return getClass().getName() + " for transformer: " + this.transformer;
}
private static class Dummy {
}
}

View File

@@ -1,75 +0,0 @@
/*
* Copyright 2002-2017 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.instrument.classloading.websphere;
import java.lang.instrument.ClassFileTransformer;
import org.springframework.core.OverridingClassLoader;
import org.springframework.instrument.classloading.LoadTimeWeaver;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* {@link LoadTimeWeaver} implementation for WebSphere's instrumentable ClassLoader.
* Compatible with WebSphere 7 as well as 8 and 9.
*
* @author Costin Leau
* @since 3.1
*/
public class WebSphereLoadTimeWeaver implements LoadTimeWeaver {
private final WebSphereClassLoaderAdapter classLoader;
/**
* Create a new instance of the {@link WebSphereLoadTimeWeaver} class using
* the default {@link ClassLoader class loader}.
* @see org.springframework.util.ClassUtils#getDefaultClassLoader()
*/
public WebSphereLoadTimeWeaver() {
this(ClassUtils.getDefaultClassLoader());
}
/**
* Create a new instance of the {@link WebSphereLoadTimeWeaver} class using
* the supplied {@link ClassLoader}.
* @param classLoader the {@code ClassLoader} to delegate to for weaving
*/
public WebSphereLoadTimeWeaver(@Nullable ClassLoader classLoader) {
Assert.notNull(classLoader, "ClassLoader must not be null");
this.classLoader = new WebSphereClassLoaderAdapter(classLoader);
}
@Override
public void addTransformer(ClassFileTransformer transformer) {
this.classLoader.addTransformer(transformer);
}
@Override
public ClassLoader getInstrumentableClassLoader() {
return this.classLoader.getClassLoader();
}
@Override
public ClassLoader getThrowawayClassLoader() {
return new OverridingClassLoader(this.classLoader.getClassLoader(),
this.classLoader.getThrowawayClassLoader());
}
}

View File

@@ -1,9 +0,0 @@
/**
* Support for class instrumentation on IBM WebSphere Application Server 7+.
*/
@NonNullApi
@NonNullFields
package org.springframework.instrument.classloading.websphere;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;

View File

@@ -1,105 +0,0 @@
/*
* 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.
* 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.jmx.support;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.management.MBeanServer;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jmx.MBeanServerNotFoundException;
import org.springframework.lang.Nullable;
/**
* {@link FactoryBean} that obtains a WebSphere {@link javax.management.MBeanServer}
* reference through WebSphere's proprietary {@code AdminServiceFactory} API,
* available on WebSphere 5.1 and higher.
*
* <p>Exposes the {@code MBeanServer} for bean references.
*
* <p>This {@code FactoryBean} is a direct alternative to {@link MBeanServerFactoryBean},
* which uses standard JMX 1.2 API to access the platform's {@link MBeanServer}.
*
* <p>See the javadocs for WebSphere's
* <a href="https://www.ibm.com/support/knowledgecenter/SSEQTJ_9.0.0/com.ibm.websphere.javadoc.doc/web/apidocs/com/ibm/websphere/management/AdminServiceFactory.html">{@code AdminServiceFactory}</a>
* and
* <a href="https://www.ibm.com/support/knowledgecenter/SSEQTJ_9.0.0/com.ibm.websphere.javadoc.doc/web/apidocs/com/ibm/websphere/management/MBeanFactory.html">{@code MBeanFactory}</a>.
*
* @author Juergen Hoeller
* @author Rob Harrop
* @since 2.0.3
* @see javax.management.MBeanServer
* @see MBeanServerFactoryBean
*/
public class WebSphereMBeanServerFactoryBean implements FactoryBean<MBeanServer>, InitializingBean {
private static final String ADMIN_SERVICE_FACTORY_CLASS = "com.ibm.websphere.management.AdminServiceFactory";
private static final String GET_MBEAN_FACTORY_METHOD = "getMBeanFactory";
private static final String GET_MBEAN_SERVER_METHOD = "getMBeanServer";
@Nullable
private MBeanServer mbeanServer;
@Override
public void afterPropertiesSet() throws MBeanServerNotFoundException {
try {
/*
* this.mbeanServer = AdminServiceFactory.getMBeanFactory().getMBeanServer();
*/
Class<?> adminServiceClass = getClass().getClassLoader().loadClass(ADMIN_SERVICE_FACTORY_CLASS);
Method getMBeanFactoryMethod = adminServiceClass.getMethod(GET_MBEAN_FACTORY_METHOD);
Object mbeanFactory = getMBeanFactoryMethod.invoke(null);
Method getMBeanServerMethod = mbeanFactory.getClass().getMethod(GET_MBEAN_SERVER_METHOD);
this.mbeanServer = (MBeanServer) getMBeanServerMethod.invoke(mbeanFactory);
}
catch (ClassNotFoundException ex) {
throw new MBeanServerNotFoundException("Could not find WebSphere's AdminServiceFactory class", ex);
}
catch (InvocationTargetException ex) {
throw new MBeanServerNotFoundException(
"WebSphere's AdminServiceFactory.getMBeanFactory/getMBeanServer method failed", ex.getTargetException());
}
catch (Exception ex) {
throw new MBeanServerNotFoundException(
"Could not access WebSphere's AdminServiceFactory.getMBeanFactory/getMBeanServer method", ex);
}
}
@Override
@Nullable
public MBeanServer getObject() {
return this.mbeanServer;
}
@Override
public Class<? extends MBeanServer> getObjectType() {
return (this.mbeanServer != null ? this.mbeanServer.getClass() : MBeanServer.class);
}
@Override
public boolean isSingleton() {
return true;
}
}

View File

@@ -77,7 +77,7 @@ public class JndiLocatorDelegate extends JndiLocatorSupport {
}
/**
* Check whether a default JNDI environment, as in a Java EE environment,
* Check whether a default JNDI environment, as in a Jakarta EE environment,
* is available on this JVM.
* @return {@code true} if a default InitialContext can be used,
* {@code false} if not

View File

@@ -27,7 +27,7 @@ import org.springframework.util.Assert;
* bean properties.
*
* <p>JNDI names may or may not include the "java:comp/env/" prefix expected
* by Java EE applications when accessing a locally mapped (ENC - Environmental
* by Jakarta EE applications when accessing a locally mapped (ENC - Environmental
* Naming Context) resource. If it doesn't, the "java:comp/env/" prefix will
* be prepended if the "resourceRef" property is true (the default is
* <strong>false</strong>) and no other scheme (e.g. "java:") is given.
@@ -40,7 +40,7 @@ import org.springframework.util.Assert;
*/
public abstract class JndiLocatorSupport extends JndiAccessor {
/** JNDI prefix used in a Java EE container. */
/** JNDI prefix used in a Jakarta EE container. */
public static final String CONTAINER_PREFIX = "java:comp/env/";
@@ -48,7 +48,7 @@ public abstract class JndiLocatorSupport extends JndiAccessor {
/**
* Set whether the lookup occurs in a Java EE container, i.e. if the prefix
* Set whether the lookup occurs in a Jakarta EE container, i.e. if the prefix
* "java:comp/env/" needs to be added if the JNDI name doesn't already
* contain it. Default is "false".
* <p>Note: Will only get applied if no other scheme (e.g. "java:") is given.
@@ -58,7 +58,7 @@ public abstract class JndiLocatorSupport extends JndiAccessor {
}
/**
* Return whether the lookup occurs in a Java EE container.
* Return whether the lookup occurs in a Jakarta EE container.
*/
public boolean isResourceRef() {
return this.resourceRef;

View File

@@ -28,7 +28,7 @@ import org.springframework.util.StringUtils;
* providing configurable lookup of a specific JNDI resource.
*
* <p>Exposes a {@link #setJndiName "jndiName"} property. This may or may not
* include the "java:comp/env/" prefix expected by Java EE applications when
* include the "java:comp/env/" prefix expected by Jakarta EE applications when
* accessing a locally mapped (Environmental Naming Context) resource. If it
* doesn't, the "java:comp/env/" prefix will be prepended if the "resourceRef"
* property is true (the default is <strong>false</strong>) and no other scheme

View File

@@ -39,7 +39,7 @@ import org.springframework.lang.Nullable;
* &lt;/bean&gt;
*
* &lt;bean id="queueConnectionFactory" class="org.springframework.aop.framework.ProxyFactoryBean"&gt;
* &lt;property name="proxyInterfaces" value="javax.jms.QueueConnectionFactory"/&gt;
* &lt;property name="proxyInterfaces" value="jakarta.jms.QueueConnectionFactory"/&gt;
* &lt;property name="targetSource" ref="queueConnectionFactoryTarget"/&gt;
* &lt;/bean&gt;</pre>
*

View File

@@ -44,7 +44,7 @@ import org.springframework.lang.Nullable;
* the {@link org.springframework.beans.factory.ListableBeanFactory} interface.
*
* <p>This factory resolves given bean names as JNDI names within the
* Java EE application's "java:comp/env/" namespace. It caches the resolved
* Jakarta EE application's "java:comp/env/" namespace. It caches the resolved
* types for all obtained objects, and optionally also caches shareable
* objects (if they are explicitly marked as
* {@link #addShareableResource shareable resource}.

View File

@@ -39,7 +39,7 @@ import org.springframework.lang.Nullable;
* and adding extended trigger capabilities.
*
* <p>This interface is roughly equivalent to a JSR-236
* {@code ManagedScheduledExecutorService} as supported in Java EE 7
* {@code ManagedScheduledExecutorService} as supported in Jakarta EE
* environments but aligned with Spring's {@code TaskExecutor} model.
*
* @author Juergen Hoeller

View File

@@ -41,7 +41,7 @@ import java.lang.annotation.Target;
* {@code Future} that can be used to track the result of the asynchronous method
* execution. However, since the target method needs to implement the same signature,
* it will have to return a temporary {@code Future} handle that just passes a value
* through: e.g. Spring's {@link AsyncResult}, EJB 3.1's {@link javax.ejb.AsyncResult},
* through: e.g. Spring's {@link AsyncResult}, EJB 3.1's {@link jakarta.ejb.AsyncResult},
* or {@link java.util.concurrent.CompletableFuture#completedFuture(Object)}.
*
* @author Juergen Hoeller

View File

@@ -42,7 +42,7 @@ import org.springframework.util.function.SingletonSupplier;
* annotation. This annotation can be used at the method and type level in
* implementation classes as well as in service interfaces.
*
* <p>This advisor detects the EJB 3.1 {@code javax.ejb.Asynchronous}
* <p>This advisor detects the EJB 3.1 {@code jakarta.ejb.Asynchronous}
* annotation as well, treating it exactly like Spring's own {@code Async}.
* Furthermore, a custom async annotation type may get specified through the
* {@link #setAsyncAnnotationType "asyncAnnotationType"} property.
@@ -99,7 +99,7 @@ public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements B
asyncAnnotationTypes.add(Async.class);
try {
asyncAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.ejb.Asynchronous", AsyncAnnotationAdvisor.class.getClassLoader()));
ClassUtils.forName("jakarta.ejb.Asynchronous", AsyncAnnotationAdvisor.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
// If EJB 3.1 API not present, simply ignore.
@@ -112,7 +112,7 @@ public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements B
/**
* Set the 'async' annotation type.
* <p>The default async annotation type is the {@link Async} annotation, as well
* as the EJB 3.1 {@code javax.ejb.Asynchronous} annotation (if present).
* as the EJB 3.1 {@code jakarta.ejb.Asynchronous} annotation (if present).
* <p>This setter property exists so that developers can provide their own
* (non-Spring-specific) annotation type to indicate that a method is to
* be executed asynchronously.

View File

@@ -42,7 +42,7 @@ import org.springframework.util.function.SingletonSupplier;
* be provided as well as the annotation type that indicates a method should be
* invoked asynchronously. If no annotation type is specified, this post-
* processor will detect both Spring's {@link Async @Async} annotation as well
* as the EJB 3.1 {@code javax.ejb.Asynchronous} annotation.
* as the EJB 3.1 {@code jakarta.ejb.Asynchronous} annotation.
*
* <p>For methods having a {@code void} return type, any exception thrown
* during the asynchronous method invocation cannot be accessed by the
@@ -130,7 +130,7 @@ public class AsyncAnnotationBeanPostProcessor extends AbstractBeanFactoryAwareAd
/**
* Set the 'async' annotation type to be detected at either class or method
* level. By default, both the {@link Async} annotation and the EJB 3.1
* {@code javax.ejb.Asynchronous} annotation will be detected.
* {@code jakarta.ejb.Asynchronous} annotation will be detected.
* <p>This setter property exists so that developers can provide their own
* (non-Spring-specific) annotation type to indicate that a method (or all
* methods of a given class) should be invoked asynchronously.

View File

@@ -43,7 +43,7 @@ import org.springframework.core.Ordered;
* }</pre>
*
* {@code MyAsyncBean} is a user-defined type with one or more methods annotated with
* either Spring's {@code @Async} annotation, the EJB 3.1 {@code @javax.ejb.Asynchronous}
* either Spring's {@code @Async} annotation, the EJB 3.1 {@code @jakarta.ejb.Asynchronous}
* annotation, or any custom annotation specified via the {@link #annotation} attribute.
* The aspect is added transparently for any registered bean, for instance via this
* configuration:
@@ -166,7 +166,7 @@ public @interface EnableAsync {
* Indicate the 'async' annotation type to be detected at either class
* or method level.
* <p>By default, both Spring's @{@link Async} annotation and the EJB 3.1
* {@code @javax.ejb.Asynchronous} annotation will be detected.
* {@code @jakarta.ejb.Asynchronous} annotation will be detected.
* <p>This attribute exists so that developers can provide their own
* custom annotation type to indicate that a method (or all methods of
* a given class) should be invoked asynchronously.

View File

@@ -23,8 +23,8 @@ import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import javax.enterprise.concurrent.ManagedExecutors;
import javax.enterprise.concurrent.ManagedTask;
import jakarta.enterprise.concurrent.ManagedExecutors;
import jakarta.enterprise.concurrent.ManagedTask;
import org.springframework.core.task.AsyncListenableTaskExecutor;
import org.springframework.core.task.TaskDecorator;
@@ -41,11 +41,11 @@ import org.springframework.util.concurrent.ListenableFuture;
* Also detects an extended {@code java.util.concurrent.ExecutorService}, adapting
* the {@link org.springframework.core.task.AsyncTaskExecutor} interface accordingly.
*
* <p>Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedExecutorService}
* in order to expose {@link javax.enterprise.concurrent.ManagedTask} adapters for it,
* <p>Autodetects a JSR-236 {@link jakarta.enterprise.concurrent.ManagedExecutorService}
* in order to expose {@link jakarta.enterprise.concurrent.ManagedTask} adapters for it,
* exposing a long-running hint based on {@link SchedulingAwareRunnable} and an identity
* name based on the given Runnable/Callable's {@code toString()}. For JSR-236 style
* lookup in a Java EE 7 environment, consider using {@link DefaultManagedTaskExecutor}.
* lookup in a Jakarta EE environment, consider using {@link DefaultManagedTaskExecutor}.
*
* <p>Note that there is a pre-built {@link ThreadPoolTaskExecutor} that allows
* for defining a {@link java.util.concurrent.ThreadPoolExecutor} in bean style,
@@ -70,7 +70,7 @@ public class ConcurrentTaskExecutor implements AsyncListenableTaskExecutor, Sche
static {
try {
managedExecutorServiceClass = ClassUtils.forName(
"javax.enterprise.concurrent.ManagedExecutorService",
"jakarta.enterprise.concurrent.ManagedExecutorService",
ConcurrentTaskScheduler.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
@@ -95,8 +95,8 @@ public class ConcurrentTaskExecutor implements AsyncListenableTaskExecutor, Sche
/**
* Create a new ConcurrentTaskExecutor, using the given {@link java.util.concurrent.Executor}.
* <p>Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedExecutorService}
* in order to expose {@link javax.enterprise.concurrent.ManagedTask} adapters for it.
* <p>Autodetects a JSR-236 {@link jakarta.enterprise.concurrent.ManagedExecutorService}
* in order to expose {@link jakarta.enterprise.concurrent.ManagedTask} adapters for it.
* @param executor the {@link java.util.concurrent.Executor} to delegate to
*/
public ConcurrentTaskExecutor(@Nullable Executor executor) {
@@ -107,8 +107,8 @@ public class ConcurrentTaskExecutor implements AsyncListenableTaskExecutor, Sche
/**
* Specify the {@link java.util.concurrent.Executor} to delegate to.
* <p>Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedExecutorService}
* in order to expose {@link javax.enterprise.concurrent.ManagedTask} adapters for it.
* <p>Autodetects a JSR-236 {@link jakarta.enterprise.concurrent.ManagedExecutorService}
* in order to expose {@link jakarta.enterprise.concurrent.ManagedTask} adapters for it.
*/
public final void setConcurrentExecutor(@Nullable Executor executor) {
this.concurrentExecutor = (executor != null ? executor : Executors.newSingleThreadExecutor());

View File

@@ -25,8 +25,8 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import javax.enterprise.concurrent.LastExecution;
import javax.enterprise.concurrent.ManagedScheduledExecutorService;
import jakarta.enterprise.concurrent.LastExecution;
import jakarta.enterprise.concurrent.ManagedScheduledExecutorService;
import org.springframework.core.task.TaskRejectedException;
import org.springframework.lang.Nullable;
@@ -44,11 +44,11 @@ import org.springframework.util.ErrorHandler;
* Extends {@link ConcurrentTaskExecutor} in order to implement the
* {@link org.springframework.scheduling.SchedulingTaskExecutor} interface as well.
*
* <p>Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedScheduledExecutorService}
* <p>Autodetects a JSR-236 {@link jakarta.enterprise.concurrent.ManagedScheduledExecutorService}
* in order to use it for trigger-based scheduling if possible, instead of Spring's
* local trigger management which ends up delegating to regular delay-based scheduling
* against the {@code java.util.concurrent.ScheduledExecutorService} API. For JSR-236 style
* lookup in a Java EE 7 environment, consider using {@link DefaultManagedTaskScheduler}.
* lookup in a Jakarta EE environment, consider using {@link DefaultManagedTaskScheduler}.
*
* <p>Note that there is a pre-built {@link ThreadPoolTaskScheduler} that allows for
* defining a {@link java.util.concurrent.ScheduledThreadPoolExecutor} in bean style,
@@ -73,7 +73,7 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T
static {
try {
managedScheduledExecutorServiceClass = ClassUtils.forName(
"javax.enterprise.concurrent.ManagedScheduledExecutorService",
"jakarta.enterprise.concurrent.ManagedScheduledExecutorService",
ConcurrentTaskScheduler.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
@@ -106,7 +106,7 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T
/**
* Create a new ConcurrentTaskScheduler, using the given
* {@link java.util.concurrent.ScheduledExecutorService} as shared delegate.
* <p>Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedScheduledExecutorService}
* <p>Autodetects a JSR-236 {@link jakarta.enterprise.concurrent.ManagedScheduledExecutorService}
* in order to use it for trigger-based scheduling if possible,
* instead of Spring's local trigger management.
* @param scheduledExecutor the {@link java.util.concurrent.ScheduledExecutorService}
@@ -121,7 +121,7 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T
/**
* Create a new ConcurrentTaskScheduler, using the given {@link java.util.concurrent.Executor}
* and {@link java.util.concurrent.ScheduledExecutorService} as delegates.
* <p>Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedScheduledExecutorService}
* <p>Autodetects a JSR-236 {@link jakarta.enterprise.concurrent.ManagedScheduledExecutorService}
* in order to use it for trigger-based scheduling if possible,
* instead of Spring's local trigger management.
* @param concurrentExecutor the {@link java.util.concurrent.Executor} to delegate to
@@ -150,7 +150,7 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T
/**
* Specify the {@link java.util.concurrent.ScheduledExecutorService} to delegate to.
* <p>Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedScheduledExecutorService}
* <p>Autodetects a JSR-236 {@link jakarta.enterprise.concurrent.ManagedScheduledExecutorService}
* in order to use it for trigger-based scheduling if possible,
* instead of Spring's local trigger management.
* <p>Note: This will only apply to {@link TaskScheduler} invocations.
@@ -275,7 +275,7 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T
public ScheduledFuture<?> schedule(Runnable task, final Trigger trigger) {
ManagedScheduledExecutorService executor = (ManagedScheduledExecutorService) scheduledExecutor;
return executor.schedule(task, new javax.enterprise.concurrent.Trigger() {
return executor.schedule(task, new jakarta.enterprise.concurrent.Trigger() {
@Override
@Nullable
public Date getNextRunTime(@Nullable LastExecution le, Date taskScheduledTime) {

View File

@@ -31,10 +31,10 @@ import org.springframework.lang.Nullable;
/**
* JNDI-based variant of {@link CustomizableThreadFactory}, performing a default lookup
* for JSR-236's "java:comp/DefaultManagedThreadFactory" in a Java EE 7 environment,
* for JSR-236's "java:comp/DefaultManagedThreadFactory" in a Jakarta EE environment,
* falling back to the local {@link CustomizableThreadFactory} setup if not found.
*
* <p>This is a convenient way to use managed threads when running in a Java EE 7
* <p>This is a convenient way to use managed threads when running in a Jakarta EE
* environment, simply using regular local threads otherwise - without conditional
* setup (i.e. without profiles).
*
@@ -77,7 +77,7 @@ public class DefaultManagedAwareThreadFactory extends CustomizableThreadFactory
}
/**
* Set whether the lookup occurs in a Java EE container, i.e. if the prefix
* Set whether the lookup occurs in a Jakarta EE container, i.e. if the prefix
* "java:comp/env/" needs to be added if the JNDI name doesn't already
* contain it. PersistenceAnnotationBeanPostProcessor's default is "true".
* @see org.springframework.jndi.JndiLocatorSupport#setResourceRef

View File

@@ -28,16 +28,16 @@ import org.springframework.lang.Nullable;
/**
* JNDI-based variant of {@link ConcurrentTaskExecutor}, performing a default lookup for
* JSR-236's "java:comp/DefaultManagedExecutorService" in a Java EE 7/8 environment.
* JSR-236's "java:comp/DefaultManagedExecutorService" in a Jakarta EE/8 environment.
*
* <p>Note: This class is not strictly JSR-236 based; it can work with any regular
* {@link java.util.concurrent.Executor} that can be found in JNDI.
* The actual adapting to {@link javax.enterprise.concurrent.ManagedExecutorService}
* The actual adapting to {@link jakarta.enterprise.concurrent.ManagedExecutorService}
* happens in the base class {@link ConcurrentTaskExecutor} itself.
*
* @author Juergen Hoeller
* @since 4.0
* @see javax.enterprise.concurrent.ManagedExecutorService
* @see jakarta.enterprise.concurrent.ManagedExecutorService
*/
public class DefaultManagedTaskExecutor extends ConcurrentTaskExecutor implements InitializingBean {
@@ -64,7 +64,7 @@ public class DefaultManagedTaskExecutor extends ConcurrentTaskExecutor implement
}
/**
* Set whether the lookup occurs in a Java EE container, i.e. if the prefix
* Set whether the lookup occurs in a Jakarta EE container, i.e. if the prefix
* "java:comp/env/" needs to be added if the JNDI name doesn't already
* contain it. PersistenceAnnotationBeanPostProcessor's default is "true".
* @see org.springframework.jndi.JndiLocatorSupport#setResourceRef

View File

@@ -28,16 +28,16 @@ import org.springframework.lang.Nullable;
/**
* JNDI-based variant of {@link ConcurrentTaskScheduler}, performing a default lookup for
* JSR-236's "java:comp/DefaultManagedScheduledExecutorService" in a Java EE 7 environment.
* JSR-236's "java:comp/DefaultManagedScheduledExecutorService" in a Jakarta EE environment.
*
* <p>Note: This class is not strictly JSR-236 based; it can work with any regular
* {@link java.util.concurrent.ScheduledExecutorService} that can be found in JNDI.
* The actual adapting to {@link javax.enterprise.concurrent.ManagedScheduledExecutorService}
* The actual adapting to {@link jakarta.enterprise.concurrent.ManagedScheduledExecutorService}
* happens in the base class {@link ConcurrentTaskScheduler} itself.
*
* @author Juergen Hoeller
* @since 4.0
* @see javax.enterprise.concurrent.ManagedScheduledExecutorService
* @see jakarta.enterprise.concurrent.ManagedScheduledExecutorService
*/
public class DefaultManagedTaskScheduler extends ConcurrentTaskScheduler implements InitializingBean {
@@ -64,7 +64,7 @@ public class DefaultManagedTaskScheduler extends ConcurrentTaskScheduler impleme
}
/**
* Set whether the lookup occurs in a Java EE container, i.e. if the prefix
* Set whether the lookup occurs in a Jakarta EE container, i.e. if the prefix
* "java:comp/env/" needs to be added if the JNDI name doesn't already
* contain it. PersistenceAnnotationBeanPostProcessor's default is "true".
* @see org.springframework.jndi.JndiLocatorSupport#setResourceRef

View File

@@ -71,7 +71,7 @@ public abstract class ExecutorConfigurationSupport extends CustomizableThreadFac
/**
* Set the ThreadFactory to use for the ExecutorService's thread pool.
* Default is the underlying ExecutorService's default thread factory.
* <p>In a Java EE 7 or other managed environment with JSR-236 support,
* <p>In a Jakarta EE or other managed environment with JSR-236 support,
* consider specifying a JNDI-located ManagedThreadFactory: by default,
* to be found at "java:comp/DefaultManagedThreadFactory".
* Use the "jee:jndi-lookup" namespace element in XML or the programmatic
@@ -79,7 +79,7 @@ public abstract class ExecutorConfigurationSupport extends CustomizableThreadFac
* Alternatively, consider using Spring's {@link DefaultManagedAwareThreadFactory}
* with its fallback to local threads in case of no managed thread factory found.
* @see java.util.concurrent.Executors#defaultThreadFactory()
* @see javax.enterprise.concurrent.ManagedThreadFactory
* @see jakarta.enterprise.concurrent.ManagedThreadFactory
* @see DefaultManagedAwareThreadFactory
*/
public void setThreadFactory(@Nullable ThreadFactory threadFactory) {

View File

@@ -1,6 +1,6 @@
/**
* Scheduling convenience classes for the {@code java.util.concurrent}
* and {@code javax.enterprise.concurrent} packages, allowing to set up a
* and {@code jakarta.enterprise.concurrent} packages, allowing to set up a
* ThreadPoolExecutor or ScheduledThreadPoolExecutor as a bean in a Spring
* context. Provides support for the native {@code java.util.concurrent}
* interfaces as well as the Spring {@code TaskExecutor} mechanism.

View File

@@ -29,7 +29,7 @@ import org.springframework.core.annotation.AliasFor;
* Domain-Driven Design (Evans, 2003) as "a mechanism for encapsulating storage,
* retrieval, and search behavior which emulates a collection of objects".
*
* <p>Teams implementing traditional Java EE patterns such as "Data Access Object"
* <p>Teams implementing traditional Jakarta EE patterns such as "Data Access Object"
* may also apply this stereotype to DAO classes, though care should be taken to
* understand the distinction between Data Access Object and DDD-style repositories
* before doing so. This annotation is a general-purpose stereotype and individual teams

View File

@@ -76,7 +76,7 @@ public class ObjectError extends DefaultMessageSourceResolvable {
/**
* Preserve the source behind this error: possibly an {@link Exception}
* (typically {@link org.springframework.beans.PropertyAccessException})
* or a Bean Validation {@link javax.validation.ConstraintViolation}.
* or a Bean Validation {@link jakarta.validation.ConstraintViolation}.
* <p>Note that any such source object is being stored as transient:
* that is, it won't be part of a serialized error representation.
* @param source the source object
@@ -92,7 +92,7 @@ public class ObjectError extends DefaultMessageSourceResolvable {
/**
* Unwrap the source behind this error: possibly an {@link Exception}
* (typically {@link org.springframework.beans.PropertyAccessException})
* or a Bean Validation {@link javax.validation.ConstraintViolation}.
* or a Bean Validation {@link jakarta.validation.ConstraintViolation}.
* <p>The cause of the outermost exception will be introspected as well,
* e.g. the underlying conversion exception or exception thrown from a setter
* (instead of having to unwrap the {@code PropertyAccessException} in turn).
@@ -117,7 +117,7 @@ public class ObjectError extends DefaultMessageSourceResolvable {
/**
* Check the source behind this error: possibly an {@link Exception}
* (typically {@link org.springframework.beans.PropertyAccessException})
* or a Bean Validation {@link javax.validation.ConstraintViolation}.
* or a Bean Validation {@link jakarta.validation.ConstraintViolation}.
* <p>The cause of the outermost exception will be introspected as well,
* e.g. the underlying conversion exception or exception thrown from a setter
* (instead of having to unwrap the {@code PropertyAccessException} in turn).

View File

@@ -42,7 +42,7 @@ public interface SmartValidator extends Validator {
* @param target the object that is to be validated
* @param errors contextual state about the validation process
* @param validationHints one or more hint objects to be passed to the validation engine
* @see javax.validation.Validator#validate(Object, Class[])
* @see jakarta.validation.Validator#validate(Object, Class[])
*/
void validate(Object target, Errors errors, Object... validationHints);
@@ -56,7 +56,7 @@ public interface SmartValidator extends Validator {
* @param errors contextual state about the validation process
* @param validationHints one or more hint objects to be passed to the validation engine
* @since 5.1
* @see javax.validation.Validator#validateValue(Class, String, Object, Class[])
* @see jakarta.validation.Validator#validateValue(Class, String, Object, Class[])
*/
default void validateValue(
Class<?> targetType, String fieldName, @Nullable Object value, Errors errors, Object... validationHints) {

View File

@@ -23,7 +23,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Variant of JSR-303's {@link javax.validation.Valid}, supporting the
* Variant of JSR-303's {@link jakarta.validation.Valid}, supporting the
* specification of validation groups. Designed for convenient use with
* Spring's JSR-303 support but not JSR-303 specific.
*
@@ -43,7 +43,7 @@ import java.lang.annotation.Target;
*
* @author Juergen Hoeller
* @since 3.1
* @see javax.validation.Validator#validate(Object, Class[])
* @see jakarta.validation.Validator#validate(Object, Class[])
* @see org.springframework.validation.SmartValidator#validate(Object, org.springframework.validation.Errors, Object...)
* @see org.springframework.validation.beanvalidation.SpringValidatorAdapter
* @see org.springframework.validation.beanvalidation.MethodValidationPostProcessor

View File

@@ -34,7 +34,7 @@ public abstract class ValidationAnnotationUtils {
/**
* Determine any validation hints by the given annotation.
* <p>This implementation checks for {@code @javax.validation.Valid},
* <p>This implementation checks for {@code @jakarta.validation.Valid},
* Spring's {@link org.springframework.validation.annotation.Validated},
* and custom annotations whose name starts with "Valid".
* @param ann the annotation (potentially a validation annotation)
@@ -45,7 +45,7 @@ public abstract class ValidationAnnotationUtils {
public static Object[] determineValidationHints(Annotation ann) {
Class<? extends Annotation> annotationType = ann.annotationType();
String annotationName = annotationType.getName();
if ("javax.validation.Valid".equals(annotationName)) {
if ("jakarta.validation.Valid".equals(annotationName)) {
return EMPTY_OBJECT_ARRAY;
}
Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);

View File

@@ -19,10 +19,10 @@ package org.springframework.validation.beanvalidation;
import java.util.Iterator;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.BeansException;
@@ -60,7 +60,7 @@ public class BeanValidationPostProcessor implements BeanPostProcessor, Initializ
* Set the JSR-303 ValidatorFactory to delegate to for validating beans,
* using its default Validator.
* <p>Default is the default ValidatorFactory's default Validator.
* @see javax.validation.ValidatorFactory#getValidator()
* @see jakarta.validation.ValidatorFactory#getValidator()
*/
public void setValidatorFactory(ValidatorFactory validatorFactory) {
this.validator = validatorFactory.getValidator();
@@ -105,7 +105,7 @@ public class BeanValidationPostProcessor implements BeanPostProcessor, Initializ
/**
* Perform validation of the given bean.
* @param bean the bean instance to validate
* @see javax.validation.Validator#validate
* @see jakarta.validation.Validator#validate
*/
protected void doValidate(Object bean) {
Assert.state(this.validator != null, "No Validator set");

View File

@@ -16,12 +16,12 @@
package org.springframework.validation.beanvalidation;
import javax.validation.MessageInterpolator;
import javax.validation.TraversableResolver;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorContext;
import javax.validation.ValidatorFactory;
import jakarta.validation.MessageInterpolator;
import jakarta.validation.TraversableResolver;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorContext;
import jakarta.validation.ValidatorFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.lang.Nullable;
@@ -48,7 +48,7 @@ public class CustomValidatorBean extends SpringValidatorAdapter implements Valid
/**
* Set the ValidatorFactory to obtain the target Validator from.
* <p>Default is {@link javax.validation.Validation#buildDefaultValidatorFactory()}.
* <p>Default is {@link jakarta.validation.Validation#buildDefaultValidatorFactory()}.
*/
public void setValidatorFactory(ValidatorFactory validatorFactory) {
this.validatorFactory = validatorFactory;

View File

@@ -27,20 +27,20 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.validation.Configuration;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.MessageInterpolator;
import javax.validation.ParameterNameProvider;
import javax.validation.TraversableResolver;
import javax.validation.Validation;
import javax.validation.ValidationException;
import javax.validation.ValidationProviderResolver;
import javax.validation.Validator;
import javax.validation.ValidatorContext;
import javax.validation.ValidatorFactory;
import javax.validation.bootstrap.GenericBootstrap;
import javax.validation.bootstrap.ProviderSpecificBootstrap;
import jakarta.validation.ClockProvider;
import jakarta.validation.Configuration;
import jakarta.validation.ConstraintValidatorFactory;
import jakarta.validation.MessageInterpolator;
import jakarta.validation.ParameterNameProvider;
import jakarta.validation.TraversableResolver;
import jakarta.validation.Validation;
import jakarta.validation.ValidationException;
import jakarta.validation.ValidationProviderResolver;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorContext;
import jakarta.validation.ValidatorFactory;
import jakarta.validation.bootstrap.GenericBootstrap;
import jakarta.validation.bootstrap.ProviderSpecificBootstrap;
import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
import org.springframework.beans.factory.DisposableBean;
@@ -57,11 +57,11 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
/**
* This is the central class for {@code javax.validation} (JSR-303) setup in a Spring
* application context: It bootstraps a {@code javax.validation.ValidationFactory} and
* This is the central class for {@code jakarta.validation} (JSR-303) setup in a Spring
* application context: It bootstraps a {@code jakarta.validation.ValidationFactory} and
* exposes it through the Spring {@link org.springframework.validation.Validator} interface
* as well as through the JSR-303 {@link javax.validation.Validator} interface and the
* {@link javax.validation.ValidatorFactory} interface itself.
* as well as through the JSR-303 {@link jakarta.validation.Validator} interface and the
* {@link jakarta.validation.ValidatorFactory} interface itself.
*
* <p>When talking to an instance of this bean through the Spring or JSR-303 Validator interfaces,
* you'll be talking to the default Validator of the underlying ValidatorFactory. This is very
@@ -69,22 +69,15 @@ import org.springframework.util.ReflectionUtils;
* you will almost always use the default Validator anyway. This can also be injected directly
* into any target dependency of type {@link org.springframework.validation.Validator}!
*
* <p><b>As of Spring 5.0, this class requires Bean Validation 1.1+, with special support
* for Hibernate Validator 5.x</b> (see {@link #setValidationMessageSource}).
* This class is also runtime-compatible with Bean Validation 2.0 and Hibernate Validator 6.0,
* with one special note: If you'd like to call BV 2.0's {@code getClockProvider()} method,
* obtain the native {@code ValidatorFactory} through {@code #unwrap(ValidatorFactory.class)}
* and call the {@code getClockProvider()} method on the returned native reference there.
*
* <p>This class is also being used by Spring's MVC configuration namespace, in case of the
* {@code javax.validation} API being present but no explicit Validator having been configured.
* {@code jakarta.validation} API being present but no explicit Validator having been configured.
*
* @author Juergen Hoeller
* @since 3.0
* @see javax.validation.ValidatorFactory
* @see javax.validation.Validator
* @see javax.validation.Validation#buildDefaultValidatorFactory()
* @see javax.validation.ValidatorFactory#getValidator()
* @see jakarta.validation.ValidatorFactory
* @see jakarta.validation.Validator
* @see jakarta.validation.Validation#buildDefaultValidatorFactory()
* @see jakarta.validation.ValidatorFactory#getValidator()
*/
public class LocalValidatorFactoryBean extends SpringValidatorAdapter
implements ValidatorFactory, ApplicationContextAware, InitializingBean, DisposableBean {
@@ -123,8 +116,8 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
/**
* Specify the desired provider class, if any.
* <p>If not specified, JSR-303's default search mechanism will be used.
* @see javax.validation.Validation#byProvider(Class)
* @see javax.validation.Validation#byDefaultProvider()
* @see jakarta.validation.Validation#byProvider(Class)
* @see jakarta.validation.Validation#byDefaultProvider()
*/
@SuppressWarnings("rawtypes")
public void setProviderClass(Class providerClass) {
@@ -208,7 +201,7 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
* Specify bean validation properties to be passed to the validation provider.
* <p>Can be populated with a String "value" (parsed via PropertiesEditor)
* or a "props" element in XML bean definitions.
* @see javax.validation.Configuration#addProperty(String, String)
* @see jakarta.validation.Configuration#addProperty(String, String)
*/
public void setValidationProperties(Properties jpaProperties) {
CollectionUtils.mergePropertiesIntoMap(jpaProperties, this.validationPropertyMap);
@@ -217,7 +210,7 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
/**
* Specify bean validation properties to be passed to the validation provider as a Map.
* <p>Can be populated with a "map" or "props" element in XML bean definitions.
* @see javax.validation.Configuration#addProperty(String, String)
* @see jakarta.validation.Configuration#addProperty(String, String)
*/
public void setValidationPropertyMap(@Nullable Map<String, String> validationProperties) {
if (validationProperties != null) {
@@ -400,18 +393,11 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
return this.validatorFactory.getParameterNameProvider();
}
// Bean Validation 2.0: currently not implemented here since it would imply
// a hard dependency on the new javax.validation.ClockProvider interface.
// To be resolved once Spring Framework requires Bean Validation 2.0+.
// Obtain the native ValidatorFactory through unwrap(ValidatorFactory.class)
// instead which will fully support a getClockProvider() call as well.
/*
@Override
public javax.validation.ClockProvider getClockProvider() {
public ClockProvider getClockProvider() {
Assert.notNull(this.validatorFactory, "No target ValidatorFactory set");
return this.validatorFactory.getClockProvider();
}
*/
@Override
@SuppressWarnings("unchecked")

View File

@@ -18,7 +18,7 @@ package org.springframework.validation.beanvalidation;
import java.util.Locale;
import javax.validation.MessageInterpolator;
import jakarta.validation.MessageInterpolator;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.util.Assert;

View File

@@ -19,13 +19,12 @@ package org.springframework.validation.beanvalidation;
import java.lang.reflect.Method;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.executable.ExecutableValidator;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import jakarta.validation.executable.ExecutableValidator;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
@@ -57,7 +56,7 @@ import org.springframework.validation.annotation.Validated;
* @author Juergen Hoeller
* @since 3.1
* @see MethodValidationPostProcessor
* @see javax.validation.executable.ExecutableValidator
* @see jakarta.validation.executable.ExecutableValidator
*/
public class MethodValidationInterceptor implements MethodInterceptor {

View File

@@ -18,9 +18,8 @@ package org.springframework.validation.beanvalidation;
import java.lang.annotation.Annotation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Pointcut;
@@ -55,7 +54,7 @@ import org.springframework.validation.annotation.Validated;
* @author Juergen Hoeller
* @since 3.1
* @see MethodValidationInterceptor
* @see javax.validation.executable.ExecutableValidator
* @see jakarta.validation.executable.ExecutableValidator
*/
@SuppressWarnings("serial")
public class MethodValidationPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor
@@ -101,7 +100,7 @@ public class MethodValidationPostProcessor extends AbstractBeanFactoryAwareAdvis
* Set the JSR-303 ValidatorFactory to delegate to for validating methods,
* using its default Validator.
* <p>Default is the default ValidatorFactory's default Validator.
* @see javax.validation.ValidatorFactory#getValidator()
* @see jakarta.validation.ValidatorFactory#getValidator()
*/
public void setValidatorFactory(ValidatorFactory validatorFactory) {
this.validator = validatorFactory.getValidator();

View File

@@ -16,8 +16,7 @@
package org.springframework.validation.beanvalidation;
import javax.validation.ValidationException;
import jakarta.validation.ValidationException;
import org.apache.commons.logging.LogFactory;
/**
@@ -26,7 +25,7 @@ import org.apache.commons.logging.LogFactory;
* in case of no Bean Validation provider being available.
*
* <p>This is the actual class used by Spring's MVC configuration namespace,
* in case of the {@code javax.validation} API being present but no explicit
* in case of the {@code jakarta.validation} API being present but no explicit
* Validator having been configured.
*
* @author Juergen Hoeller

View File

@@ -16,8 +16,8 @@
package org.springframework.validation.beanvalidation;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorFactory;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.util.Assert;

View File

@@ -25,13 +25,13 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import javax.validation.ConstraintViolation;
import javax.validation.ElementKind;
import javax.validation.Path;
import javax.validation.ValidationException;
import javax.validation.executable.ExecutableValidator;
import javax.validation.metadata.BeanDescriptor;
import javax.validation.metadata.ConstraintDescriptor;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ElementKind;
import jakarta.validation.Path;
import jakarta.validation.ValidationException;
import jakarta.validation.executable.ExecutableValidator;
import jakarta.validation.metadata.BeanDescriptor;
import jakarta.validation.metadata.ConstraintDescriptor;
import org.springframework.beans.NotReadablePropertyException;
import org.springframework.context.MessageSourceResolvable;
@@ -63,7 +63,7 @@ import org.springframework.validation.SmartValidator;
* @see CustomValidatorBean
* @see LocalValidatorFactoryBean
*/
public class SpringValidatorAdapter implements SmartValidator, javax.validation.Validator {
public class SpringValidatorAdapter implements SmartValidator, jakarta.validation.Validator {
private static final Set<String> internalAnnotationAttributes = new HashSet<>(4);
@@ -74,14 +74,14 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation.
}
@Nullable
private javax.validation.Validator targetValidator;
private jakarta.validation.Validator targetValidator;
/**
* Create a new SpringValidatorAdapter for the given JSR-303 Validator.
* @param targetValidator the JSR-303 Validator to wrap
*/
public SpringValidatorAdapter(javax.validation.Validator targetValidator) {
public SpringValidatorAdapter(jakarta.validation.Validator targetValidator) {
Assert.notNull(targetValidator, "Target Validator must not be null");
this.targetValidator = targetValidator;
}
@@ -89,7 +89,7 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation.
SpringValidatorAdapter() {
}
void setTargetValidator(javax.validation.Validator targetValidator) {
void setTargetValidator(jakarta.validation.Validator targetValidator) {
this.targetValidator = targetValidator;
}
@@ -199,7 +199,7 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation.
* @param violation the current JSR-303 ConstraintViolation
* @return the Spring-reported field (for use with {@link Errors})
* @since 4.2
* @see javax.validation.ConstraintViolation#getPropertyPath()
* @see jakarta.validation.ConstraintViolation#getPropertyPath()
* @see org.springframework.validation.FieldError#getField()
*/
protected String determineField(ConstraintViolation<Object> violation) {
@@ -239,7 +239,7 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation.
* @param descriptor the JSR-303 ConstraintDescriptor for the current violation
* @return a corresponding error code (for use with {@link Errors})
* @since 4.2
* @see javax.validation.metadata.ConstraintDescriptor#getAnnotation()
* @see jakarta.validation.metadata.ConstraintDescriptor#getAnnotation()
* @see org.springframework.validation.MessageCodesResolver
*/
protected String determineErrorCode(ConstraintDescriptor<?> descriptor) {
@@ -305,7 +305,7 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation.
* which contains the current field's value
* @return the invalid value to expose as part of the field error
* @since 4.2
* @see javax.validation.ConstraintViolation#getInvalidValue()
* @see jakarta.validation.ConstraintViolation#getInvalidValue()
* @see org.springframework.validation.FieldError#getRejectedValue()
*/
@Nullable
@@ -387,7 +387,7 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation.
}
catch (ValidationException ex) {
// Ignore if just being asked for plain JSR-303 Validator
if (javax.validation.Validator.class == type) {
if (jakarta.validation.Validator.class == type) {
return (T) this.targetValidator;
}
throw ex;