Skip to content

Commit 5989f68

Browse files
Merge pull request #33149 from anjumfatima90/SB4-fixEnvironmentProcessor
Fix EnvironmentProcessor lookup for different Spring Boot versions
2 parents 58d2994 + 65d7d26 commit 5989f68

File tree

15 files changed

+104
-157
lines changed

15 files changed

+104
-157
lines changed

dev/com.ibm.websphere.appserver.features/visibility/private/io.openliberty.springBootHandler-4.0.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ visibility=private
55
com.ibm.websphere.appserver.eeCompatible-11.0
66
-bundles=\
77
com.ibm.ws.app.manager.springboot.jakarta, \
8-
io.openliberty.springboot.support.shutdown.version40, \
8+
com.ibm.ws.springboot.support.shutdown, \
99
com.ibm.ws.springboot.utility
1010
-files=\
1111
bin/tools/ws-springbootutil.jar, \

dev/com.ibm.ws.app.manager.springboot/resources/com/ibm/ws/app/manager/springboot/internal/resources/Messages.nlsprops

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ error.spring.required.20.explanation=The currently configured Spring Boot featur
6262
error.spring.required.20.useraction=Configure a version of the Spring Boot feature that is compatible with application content.
6363

6464
#ADDED for SpringBoot 3.0:
65-
error.spring3.required=CWWKC0273E: The springBoot-3.0 feature must be configured. The springBoot-1.5 or springBoot-2.0 feature is configured and the application has Spring 3.0 content.
65+
error.spring3.required=CWWKC0273E: The {0} feature must be configured in the server.xml file. The {1} feature is configured and the application has Spring Boot {2} content.
6666
error.spring3.required.explanation=The currently configured Spring Boot feature is not compatible with application content.
6767
error.spring3.required.useraction=Configure a version of the Spring Boot feature that is compatible with application content.
6868

dev/com.ibm.ws.springboot.support.shutdown/bnd.bnd

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ instrument.disabled: true
4949
\
5050
com.ibm.ws.logging.core;version=latest, \
5151
com.ibm.ws.ras.instrument;version=latest, \
52-
com.ibm.wsspi.org.osgi.service.component.annotations;version=latest
52+
com.ibm.wsspi.org.osgi.service.component.annotations;version=latest, \
53+
io.openliberty.springboot.support.shutdown.version40;version=latest
5354

5455
-dsannotations: com.ibm.ws.springboot.support.osgi.shutdown.ShutdownSpringBootSupport
5556
-dsannotations-inherit: true
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Bundle-SymbolicName: springBootCloser
2-
Private-Package: com.ibm.ws.springboot.support.shutdown.*
2+
Private-Package: com.ibm.ws.springboot.support.shutdown.*; \
3+
io.openliberty.springboot.support.shutdown
34
Include-Resource: resources/container
45
-maven-dependencies:
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
org.springframework.boot.env.EnvironmentPostProcessor=com.ibm.ws.springboot.support.shutdown.ApplicationContextCloser,\
22
com.ibm.ws.springboot.support.shutdown.FeatureAuditor
3+
org.springframework.boot.EnvironmentPostProcessor=io.openliberty.springboot.support.shutdown.ApplicationContextCloser40,\
4+
io.openliberty.springboot.support.shutdown.FeatureAuditor40

dev/com.ibm.ws.springboot.support.shutdown/src/com/ibm/ws/springboot/support/shutdown/ApplicationContextCloser.java

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* are made available under the terms of the Eclipse Public License 2.0
55
* which accompanies this distribution, and is available at
66
* http://www.eclipse.org/legal/epl-2.0/
7-
*
7+
*
88
* SPDX-License-Identifier: EPL-2.0
99
*
1010
* Contributors:
@@ -24,8 +24,56 @@ public class ApplicationContextCloser implements EnvironmentPostProcessor {
2424
private static final Object token = new Object() {
2525
};
2626

27+
/**
28+
* Generate the resource name for a specified class.
29+
*
30+
* Convert '.' into '/' and append '.class'.
31+
*
32+
* Note: This will not work for inner classes, which convert one or
33+
* more '.' into '$' instead of '/'.
34+
*
35+
* @param className A fully qualified non-inner class name.
36+
*
37+
* @return The name of the resource of the class.
38+
*/
39+
protected static String asResourceName(String className) {
40+
return className.replace('.', '/') + ".class";
41+
}
42+
43+
/**
44+
* Tell if a class is available in the current classloading environment.
45+
*
46+
* That is, tell if the resource of the class is available using this class's
47+
* classloader.
48+
*
49+
* Note: This does not work for inner classes. See {@link #asResourceName(String)}.
50+
*
51+
* @param className The name of the class which is to be located.
52+
*
53+
* @return True or false telling if the class resource was located.
54+
*/
55+
protected static boolean isClassAvailable(String className) {
56+
ClassLoader classLoader = FeatureAuditor.class.getClassLoader();
57+
String resourceName = asResourceName(className);
58+
boolean foundClass = (classLoader.getResource(resourceName) != null);
59+
60+
// System.out.println("FeatureAuditor: Found [ " + foundClass + " ] class [ " + className + " ] as [ " + resourceName + " ]");
61+
// System.out.println("FeatureAuditor: Using [ " + classLoader + " ]");
62+
63+
return foundClass;
64+
}
65+
2766
@Override
2867
public void postProcessEnvironment(ConfigurableEnvironment env, SpringApplication app) {
68+
boolean updatedEnvironmentProcessorAvailable = isClassAvailable("org.springframework.boot.EnvironmentPostProcessor");
69+
// org.springframework.boot.EnvironmentPostProcessor was added in Spring Boot version 4.0.0-M3.
70+
// They decided to keep the lagacy org.springframework.boot.env.EnvironmentPostProcessor from Spring Boot versions 4.0.0-RC1 until 4.2.0 (See https://github.com/spring-projects/spring-boot/issues/47272)
71+
// Once the legacy org.springframework.boot.env.EnvironmentPostProcessor is removed, this class (com.ibm.ws.springboot.support.shutdown.ApplicationContextCloser) will no longer be looked up by the spring code.
72+
// And the class which implements the org.springframework.boot.EnvironmentPostProcessor will only be looked up.
73+
if (updatedEnvironmentProcessorAvailable) {
74+
return;
75+
}
76+
2977
if (env.getPropertySources().contains("bootstrap")) {
3078
return;
3179
}

dev/com.ibm.ws.springboot.support.shutdown/src/com/ibm/ws/springboot/support/shutdown/FeatureAuditor.java

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,18 @@ protected static void warning(Type msgId, Object...parms) {
9292
*/
9393
@Override
9494
public void postProcessEnvironment(ConfigurableEnvironment env, SpringApplication app) {
95+
boolean updatedEnvironmentProcessorAvailable =
96+
isClassAvailable("org.springframework.boot.EnvironmentPostProcessor");
97+
98+
// org.springframework.boot.EnvironmentPostProcessor was added in Spring Boot version 4.0.0-M3.
99+
// They decided to keep the lagacy org.springframework.boot.env.EnvironmentPostProcessor from Spring Boot versions 4.0.0-RC1 until 4.2.0 (See https://github.com/spring-projects/spring-boot/issues/47272)
100+
// Once the legacy org.springframework.boot.env.EnvironmentPostProcessor is removed, this class (com.ibm.ws.springboot.support.shutdown.FeatureAuditor) will no longer be looked up by the spring code.
101+
// And the class which implements the org.springframework.boot.EnvironmentPostProcessor will only be looked up.
102+
if (updatedEnvironmentProcessorAvailable) {
103+
return;
104+
}
95105
String appSpringBootVersion = SpringBootVersion.getVersion();
96-
boolean appHasSpring40 = ( appSpringBootVersion.compareTo("4.0.0") >= 0 );
97-
boolean appHasSpring30 = ( !appHasSpring40 && appSpringBootVersion.compareTo("3.0.0") >= 0 );
106+
boolean appHasSpring30 = ( appSpringBootVersion.compareTo("3.0.0") >= 0 );
98107
boolean appHasSpring20 = ( !appHasSpring30 && appSpringBootVersion.compareTo("2.0.0") >= 0 );
99108
boolean appHasSpring15 = ( appSpringBootVersion.compareTo("2.0.0") < 0 );
100109

@@ -217,7 +226,7 @@ public void postProcessEnvironment(ConfigurableEnvironment env, SpringApplicatio
217226
if ( appHasSpring20 ) {
218227
requiredJavaVersion = 8;
219228
requiredVersionText = "JavaSE-1.8";
220-
} else { // ( appHasSpring30 or appHasSpring40)
229+
} else { // ( appHasSpring30 )
221230
requiredJavaVersion = 17;
222231
requiredVersionText = "JavaSE-17.0";
223232
}
@@ -272,26 +281,10 @@ public void postProcessEnvironment(ConfigurableEnvironment env, SpringApplicatio
272281
//
273282
// Match the liberty spring version to the application content!
274283

275-
if ( appHasSpring40 ) {
276-
// Don't test '!libertyHasSpring40'; that may not be set.
277-
if ( libertyHasSpring15 || libertyHasSpring20 || libertyHasSpring30) {
278-
ApplicationTr.error("error.spring4.required", "springBoot-4.0", libertySpringFeature, "4.0");
279-
// "CWWKC0276E: Error: Feature springBoot-4.0 must be provisioned:
280-
// Feature springBoot-1.5 or springBoot-2.0 or springBoot-3.0 is provisioned
281-
// and the application has Spring 4.0 content."
282-
} else if ( appUsesServlets && !libertyHasJakartaServlets ) {
283-
ApplicationTr.error("error.spring4.requires.servlet61.or.later.application");
284-
// "CWWKC0277E: Error: Feature servlet-6.1 or later must be provisioned:
285-
// Feature springBoot-4.0 is provisioned and the application uses Servlets."
286-
} else if ( appUsesWebsockets && !libertyHasJakartaWebsockets ) {
287-
ApplicationTr.error("error.spring4.requires.websocket22.or.later.application");
288-
// "CWWKC0278E: Error: Feature websocket-2.2 or later must be provisioned:
289-
// Feature springBoot-4.0 is provisioned and the application uses WebSockets."
290-
}
291-
} else if ( appHasSpring30 ) {
284+
if ( appHasSpring30 ) {
292285
// Don't test '!libertyHasSpring30'; that may not be set.
293-
if ( libertyHasSpring15 || libertyHasSpring20 ) {
294-
ApplicationTr.error("error.spring3.required");
286+
if ( libertyHasSpring15 || libertyHasSpring20 || libertyHasSpring40) {
287+
ApplicationTr.error("error.spring3.required", "springBoot-3.0", libertySpringFeature, "3.0");
295288
// "CWWKC0273E: Error: Feature springBoot-3.0 must be provisioned:
296289
// Feature springBoot-1.5 or springBoot-2.0 is provisioned
297290
// and the application has Spring 3.0 content."
@@ -307,13 +300,13 @@ public void postProcessEnvironment(ConfigurableEnvironment env, SpringApplicatio
307300

308301
} else {
309302
// Don't test '!libertyHasSpring20'; that may not be set.
310-
if ( appHasSpring20 && (libertyHasSpring15 || libertyHasSpring30) ) {
303+
if ( appHasSpring20 && (libertyHasSpring15 || libertyHasSpring30 || libertyHasSpring40) ) {
311304
ApplicationTr.error("error.spring.required.20", "springBoot-2.0", libertySpringFeature, "2.0");
312305
// "CWWKC0253E: Error: Feature {0} must be provisioned:
313306
// Feature {1} is provisioned and the application has Spring {2} content.
314307

315308
// Don't test '!libertyHasSpring15'; that may not be set.
316-
} else if ( appHasSpring15 && (libertyHasSpring20 || libertyHasSpring30) ) {
309+
} else if ( appHasSpring15 && (libertyHasSpring20 || libertyHasSpring30 || libertyHasSpring40) ) {
317310
ApplicationTr.error("error.spring.required.15", "springBoot-1.5", libertySpringFeature, "1.5");
318311
// "CWWKC0252E: Error: Feature {0} must be provisioned:
319312
// Feature {1} is provisioned and the application has Spring {2} content.

dev/io.openliberty.springboot.fat40_fat/fat/src/com/ibm/ws/springboot/support/fat/FATSuite.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
MissingSslFeatureTests40.class,
3535
SSLTests40.class,
3636
SSLMutualAuthTests40.class,
37-
//NeedSpringBootFeatureTests40.class, // Disabling reason: See class for comments
37+
NeedSpringBootFeatureTests40.class,
3838
MultipleApplicationsNotSupported40.class,
3939
NonZipExtensionFilesInBootInfLibTests40.class,
4040
PreThinnedSpringBootTests40.class,

dev/io.openliberty.springboot.fat40_fat/fat/src/com/ibm/ws/springboot/support/fat/NeedSpringBootFeatureTests40.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ public void testNeedSpringBootFeature40() throws Exception {
4242
stopServer(true, "CWWKC0276E", "CWWKZ0002E");
4343
}
4444

45-
/*
46-
* Temporarily disable the test till com.ibm.ws.springboot.support.shutdown.FeatureAuditor class is fixed.
47-
*
48-
*/
4945
@Override
5046
public Set<String> getFeatures() {
5147
return new HashSet<>(Arrays.asList("springBoot-3.0", "servlet-6.0"));

dev/io.openliberty.springboot.support.shutdown.version40/bnd.bnd

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ Include-Resource: springBoot40Closer.jar
3131

3232
Provide-Capability: spring.boot.support; jars:List<String>=springBoot40Closer.jar; version:Version=1.0
3333

34+
Export-Package: io.openliberty.springboot.support.shutdown
35+
3436
instrument.disabled: true
3537

3638
// 'com.ibm.ws.logging.core' and 'com.ibm.ws.ras.instrument' are present to avoid BND warnings,
@@ -54,7 +56,9 @@ instrument.disabled: true
5456
\
5557
com.ibm.ws.logging.core;version=latest, \
5658
com.ibm.ws.ras.instrument;version=latest, \
57-
com.ibm.wsspi.org.osgi.service.component.annotations;version=latest
59+
com.ibm.wsspi.org.osgi.service.component.annotations;version=latest, \
60+
com.ibm.ws.org.osgi.annotation.versioning;version=latest
61+
5862

5963
-dsannotations: io.openliberty.springboot.support.osgi.shutdown.ShutdownSpringBootSupport
6064
-dsannotations-inherit: true

0 commit comments

Comments
 (0)