Restore outdated local/remote-slsb attributes for declaration compatibility
Legacy EJB attributes are ignored since 6.0 due to being bound to a plain JndiObjectFactoryBean - but can still be declared now, e.g. when validating against the common versions of spring-jee.xsd out there. Closes gh-31627
This commit is contained in:
parent
54f87f1ff7
commit
695559879e
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -18,12 +18,13 @@ package org.springframework.ejb.config;
|
||||||
|
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.jndi.JndiObjectFactoryBean;
|
import org.springframework.jndi.JndiObjectFactoryBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser}
|
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser}
|
||||||
* implementation for parsing '{@code local-slsb}' tags and
|
* implementation for parsing '{@code local-slsb}' tags and
|
||||||
* creating plain {@link JndiObjectFactoryBean} definitions.
|
* creating plain {@link JndiObjectFactoryBean} definitions on 6.0.
|
||||||
*
|
*
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
|
@ -36,4 +37,10 @@ class LocalStatelessSessionBeanDefinitionParser extends AbstractJndiLocatingBean
|
||||||
return JndiObjectFactoryBean.class;
|
return JndiObjectFactoryBean.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isEligibleAttribute(String attributeName) {
|
||||||
|
return (super.isEligibleAttribute(attributeName) &&
|
||||||
|
BeanUtils.getPropertyDescriptor(JndiObjectFactoryBean.class, extractPropertyName(attributeName)) != null);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -18,12 +18,13 @@ package org.springframework.ejb.config;
|
||||||
|
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.jndi.JndiObjectFactoryBean;
|
import org.springframework.jndi.JndiObjectFactoryBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser}
|
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser}
|
||||||
* implementation for parsing '{@code remote-slsb}' tags and
|
* implementation for parsing '{@code remote-slsb}' tags and
|
||||||
* creating plain {@link JndiObjectFactoryBean} definitions.
|
* creating plain {@link JndiObjectFactoryBean} definitions as of 6.0.
|
||||||
*
|
*
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
|
@ -36,4 +37,10 @@ class RemoteStatelessSessionBeanDefinitionParser extends AbstractJndiLocatingBea
|
||||||
return JndiObjectFactoryBean.class;
|
return JndiObjectFactoryBean.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isEligibleAttribute(String attributeName) {
|
||||||
|
return (super.isEligibleAttribute(attributeName) &&
|
||||||
|
BeanUtils.getPropertyDescriptor(JndiObjectFactoryBean.class, extractPropertyName(attributeName)) != null);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
|
|
||||||
<xsd:element name="local-slsb" type="jndiLocatingType">
|
<xsd:element name="local-slsb" type="ejbType">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation source="java:org.springframework.jndi.JndiObjectFactoryBean"><![CDATA[
|
<xsd:documentation source="java:org.springframework.jndi.JndiObjectFactoryBean"><![CDATA[
|
||||||
Exposes a reference to a local EJB Stateless SessionBean.
|
Exposes a reference to a local EJB Stateless SessionBean.
|
||||||
|
|
@ -103,15 +103,56 @@
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
|
|
||||||
<xsd:element name="remote-slsb" type="jndiLocatingType">
|
<xsd:element name="remote-slsb">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation source="java:org.springframework.jndi.JndiObjectFactoryBean"><![CDATA[
|
<xsd:documentation source="java:org.springframework.jndi.JndiObjectFactoryBean"><![CDATA[
|
||||||
Exposes a reference to a remote EJB Stateless SessionBean.
|
Exposes a reference to a remote EJB Stateless SessionBean.
|
||||||
]]></xsd:documentation>
|
]]></xsd:documentation>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:complexContent>
|
||||||
|
<xsd:extension base="ejbType">
|
||||||
|
<xsd:attribute name="home-interface" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation source="java:java.lang.Class"><![CDATA[
|
||||||
|
The home interface that will be narrowed to before performing the
|
||||||
|
parameterless SLSB create() call that returns the actual SLSB proxy.
|
||||||
|
NOTE: Effectively ignored as of 6.0 in favor of plain JNDI lookups.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="refresh-home-on-connect-failure" type="xsd:boolean" default="false">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
Controls whether to refresh the EJB home on connect failure.
|
||||||
|
NOTE: Effectively ignored as of 6.0 in favor of plain JNDI lookups.
|
||||||
|
|
||||||
|
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.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="cache-session-bean" type="xsd:boolean" default="false">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
Controls whether to cache the actual session bean object.
|
||||||
|
NOTE: Effectively ignored as of 6.0 in favor of plain JNDI lookups.
|
||||||
|
|
||||||
|
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.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
</xsd:extension>
|
||||||
|
</xsd:complexContent>
|
||||||
|
</xsd:complexType>
|
||||||
</xsd:element>
|
</xsd:element>
|
||||||
|
|
||||||
<xsd:complexType name="jndiLocatingType">
|
<!-- base types -->
|
||||||
|
<xsd:complexType name="jndiLocatingType" abstract="true">
|
||||||
<xsd:complexContent>
|
<xsd:complexContent>
|
||||||
<xsd:extension base="beans:identifiedType">
|
<xsd:extension base="beans:identifiedType">
|
||||||
<xsd:sequence>
|
<xsd:sequence>
|
||||||
|
|
@ -183,6 +224,40 @@
|
||||||
</xsd:complexContent>
|
</xsd:complexContent>
|
||||||
</xsd:complexType>
|
</xsd:complexType>
|
||||||
|
|
||||||
|
<xsd:complexType name="ejbType">
|
||||||
|
<xsd:complexContent>
|
||||||
|
<xsd:extension base="jndiLocatingType">
|
||||||
|
<xsd:attribute name="lookup-home-on-startup" type="xsd:boolean" default="true">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
Controls whether the lookup of the EJB home object is performed
|
||||||
|
immediately on startup (if true, the default), or on first access
|
||||||
|
(if false).
|
||||||
|
NOTE: Effectively ignored as of 6.0 in favor of plain JNDI lookups.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="cache-home" type="xsd:boolean" default="true">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
Controls whether the EJB home object is cached once it has been located.
|
||||||
|
On by default; turn this flag off to always reobtain fresh home objects.
|
||||||
|
NOTE: Effectively ignored as of 6.0 in favor of plain JNDI lookups.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="business-interface" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation source="java:java.lang.Class"><![CDATA[
|
||||||
|
The business interface of the EJB being proxied.
|
||||||
|
NOTE: Effectively ignored as of 6.0 in favor of plain JNDI lookups.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
</xsd:extension>
|
||||||
|
</xsd:complexContent>
|
||||||
|
</xsd:complexType>
|
||||||
|
|
||||||
<xsd:simpleType name="environmentRefType">
|
<xsd:simpleType name="environmentRefType">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:appinfo>
|
<xsd:appinfo>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -16,9 +16,12 @@
|
||||||
|
|
||||||
package org.springframework.ejb.config;
|
package org.springframework.ejb.config;
|
||||||
|
|
||||||
|
import javax.naming.NoInitialContextException;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||||
|
|
@ -29,6 +32,7 @@ import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.jndi.JndiObjectFactoryBean;
|
import org.springframework.jndi.JndiObjectFactoryBean;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
|
|
@ -93,6 +97,10 @@ public class JeeNamespaceHandlerTests {
|
||||||
BeanDefinition beanDefinition = this.beanFactory.getMergedBeanDefinition("simpleLocalEjb");
|
BeanDefinition beanDefinition = this.beanFactory.getMergedBeanDefinition("simpleLocalEjb");
|
||||||
assertThat(beanDefinition.getBeanClassName()).isEqualTo(JndiObjectFactoryBean.class.getName());
|
assertThat(beanDefinition.getBeanClassName()).isEqualTo(JndiObjectFactoryBean.class.getName());
|
||||||
assertPropertyValue(beanDefinition, "jndiName", "ejb/MyLocalBean");
|
assertPropertyValue(beanDefinition, "jndiName", "ejb/MyLocalBean");
|
||||||
|
|
||||||
|
assertThatExceptionOfType(BeanCreationException.class)
|
||||||
|
.isThrownBy(() -> this.beanFactory.getBean("simpleLocalEjb"))
|
||||||
|
.withCauseInstanceOf(NoInitialContextException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -100,6 +108,32 @@ public class JeeNamespaceHandlerTests {
|
||||||
BeanDefinition beanDefinition = this.beanFactory.getMergedBeanDefinition("simpleRemoteEjb");
|
BeanDefinition beanDefinition = this.beanFactory.getMergedBeanDefinition("simpleRemoteEjb");
|
||||||
assertThat(beanDefinition.getBeanClassName()).isEqualTo(JndiObjectFactoryBean.class.getName());
|
assertThat(beanDefinition.getBeanClassName()).isEqualTo(JndiObjectFactoryBean.class.getName());
|
||||||
assertPropertyValue(beanDefinition, "jndiName", "ejb/MyRemoteBean");
|
assertPropertyValue(beanDefinition, "jndiName", "ejb/MyRemoteBean");
|
||||||
|
|
||||||
|
assertThatExceptionOfType(BeanCreationException.class)
|
||||||
|
.isThrownBy(() -> this.beanFactory.getBean("simpleRemoteEjb"))
|
||||||
|
.withCauseInstanceOf(NoInitialContextException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testComplexLocalSlsb() {
|
||||||
|
BeanDefinition beanDefinition = this.beanFactory.getMergedBeanDefinition("complexLocalEjb");
|
||||||
|
assertThat(beanDefinition.getBeanClassName()).isEqualTo(JndiObjectFactoryBean.class.getName());
|
||||||
|
assertPropertyValue(beanDefinition, "jndiName", "ejb/MyLocalBean");
|
||||||
|
|
||||||
|
assertThatExceptionOfType(BeanCreationException.class)
|
||||||
|
.isThrownBy(() -> this.beanFactory.getBean("complexLocalEjb"))
|
||||||
|
.withCauseInstanceOf(NoInitialContextException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testComplexRemoteSlsb() {
|
||||||
|
BeanDefinition beanDefinition = this.beanFactory.getMergedBeanDefinition("complexRemoteEjb");
|
||||||
|
assertThat(beanDefinition.getBeanClassName()).isEqualTo(JndiObjectFactoryBean.class.getName());
|
||||||
|
assertPropertyValue(beanDefinition, "jndiName", "ejb/MyRemoteBean");
|
||||||
|
|
||||||
|
assertThatExceptionOfType(BeanCreationException.class)
|
||||||
|
.isThrownBy(() -> this.beanFactory.getBean("complexRemoteEjb"))
|
||||||
|
.withCauseInstanceOf(NoInitialContextException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -40,14 +40,41 @@
|
||||||
</util:properties>
|
</util:properties>
|
||||||
|
|
||||||
<!-- Local EJB Tests -->
|
<!-- Local EJB Tests -->
|
||||||
<jee:local-slsb id="simpleLocalEjb" jndi-name="ejb/MyLocalBean"/>
|
<jee:local-slsb id="simpleLocalEjb" jndi-name="ejb/MyLocalBean"
|
||||||
|
business-interface="org.springframework.beans.testfixture.beans.ITestBean"/>
|
||||||
|
|
||||||
|
<jee:local-slsb id="complexLocalEjb"
|
||||||
|
jndi-name="ejb/MyLocalBean"
|
||||||
|
business-interface="org.springframework.beans.testfixture.beans.ITestBean"
|
||||||
|
cache-home="true"
|
||||||
|
lookup-home-on-startup="true"
|
||||||
|
resource-ref="true">
|
||||||
|
<jee:environment>foo=bar</jee:environment>
|
||||||
|
</jee:local-slsb>
|
||||||
|
|
||||||
<!-- Remote EJB Tests -->
|
<!-- Remote EJB Tests -->
|
||||||
<jee:remote-slsb id="simpleRemoteEjb" jndi-name="ejb/MyRemoteBean"/>
|
<jee:remote-slsb id="simpleRemoteEjb" jndi-name="ejb/MyRemoteBean"
|
||||||
|
business-interface="org.springframework.beans.testfixture.beans.ITestBean"/>
|
||||||
|
|
||||||
<!-- Lazy beans Tests-->
|
<jee:remote-slsb id="complexRemoteEjb"
|
||||||
|
jndi-name="ejb/MyRemoteBean"
|
||||||
|
business-interface="org.springframework.beans.testfixture.beans.ITestBean"
|
||||||
|
cache-home="true"
|
||||||
|
lookup-home-on-startup="true"
|
||||||
|
resource-ref="true"
|
||||||
|
home-interface="org.springframework.beans.testfixture.beans.ITestBean"
|
||||||
|
refresh-home-on-connect-failure="true"
|
||||||
|
cache-session-bean="true">
|
||||||
|
<jee:environment>foo=bar</jee:environment>
|
||||||
|
</jee:remote-slsb>
|
||||||
|
|
||||||
|
<!-- Lazy Lookup Tests-->
|
||||||
<jee:jndi-lookup id="lazyDataSource" jndi-name="jdbc/MyDataSource" lazy-init="true"/>
|
<jee:jndi-lookup id="lazyDataSource" jndi-name="jdbc/MyDataSource" lazy-init="true"/>
|
||||||
<jee:local-slsb id="lazyLocalBean" jndi-name="ejb/MyLocalBean" lazy-init="true"/>
|
|
||||||
<jee:remote-slsb id="lazyRemoteBean" jndi-name="ejb/MyRemoteBean" lazy-init="true"/>
|
<jee:local-slsb id="lazyLocalBean" jndi-name="ejb/MyLocalBean"
|
||||||
|
business-interface="org.springframework.beans.testfixture.beans.ITestBean" lazy-init="true"/>
|
||||||
|
|
||||||
|
<jee:remote-slsb id="lazyRemoteBean" jndi-name="ejb/MyRemoteBean"
|
||||||
|
business-interface="org.springframework.beans.testfixture.beans.ITestBean" lazy-init="true"/>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue