I'm trying to Deploying a spring boot app using 2.6.2 on IBM Websphere 8.5.5.20 (Using java 8)
To test out the Issue I have tried to deploy a simple Hello World restcontroller and facing the issues noted below. I'm able to deploy the application using Spring Boot 1.5 on Websphere 8.5.5.20, but facing difficulty when moving to spring-boot 2.6.2.
Please note I have tried with the javax.servlet and jakarta.servlet (version as per spring boot dependencies). I have followed this Link [https://stackoverflow.com/questions/48156126/websphere-8-5-with-spring-5], Deploy Spring Boot 2.x apps on WebSphere 8.5.5
I get the following error based on how I have the classloader for my app by setting it from Enterprise Applications > simple-boot > Manage Modules > simple-boot.war
Parent Last
Error:
[1/7/22 16:39:57:407 EST] 00000001 ContainerHelp E WSVR0501E: Error creating component com.ibm.ws.runtime.component.CompositionUnitMgrImpl@c412fa58
com.ibm.ws.exception.RuntimeWarning: com.ibm.ws.exception.RuntimeWarning: com.ibm.ws.webcontainer.exception.WebAppNotLoadedException: Failed to load webapp: Failed to load webapp: javax.servlet.ServletContainerInitializer: Provider ch.qos.logback.classic.servlet.LogbackServletContainerInitializer not a subtype
Parent First
Error:
[1/7/22 16:42:17:173 EST] 00000047 SystemOut O 2022-01-07 16:42:17.173 WARN 31546 --- [ver.startup : 1] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultValidator' defined in class path resource [org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javax/validation/Configuration.getDefaultParameterNameProvider()Ljavax/validation/ParameterNameProvider; (loaded from file:/xxxxxxx/was/INSTANCE1/plugins/javax.j2ee.validation.jar by org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@25be5b0d) called from class org.springframework.validation.beanvalidation.LocalValidatorFactoryBean (loaded from file:xxxx/simple-boot.ear/simple-boot.war/WEB-INF/lib/spring-context-5.3.14.jar by
com.ibm.ws.classloader.CompoundClassLoader@24768f5e[war:simple-boot/simple-boot.war]
My pom.xml
Note: In this pom.xml I have javax.servlet using 3.1.0 for testing but as noted above tried with default version as per the spring boot dependencies also with same result.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.my.testApp</groupId>
<artifactId>simple-webapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>simple-boot</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<exclusions>
<exclusion>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<build>
<finalName>simple-boot</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Based on the error message, the parent-last version looks like it's failing because there is a copy of the Servlet API packaged in your application. This is not a usable configuration, because the container will link to its own copy of the API, and as a result it wouldn't be able to successfully cast application artifacts that link to their own API instance. There are some APIs for which you can bring your own version in the app, but Servlet is not among them.
For the parent-first failure, it looks like Spring is expecting a newer version of the javax.validation package than is provided by the server - it's calling a method that doesn't exist in the server's version. WebSphere 8.5.5 implements Java EE 6, which includes Bean Validation 1.0, and that method wasn't added until Bean Validation 1.1. You'll need a version of Spring that works with Java EE 6 or is configurable to avoid higher-version dependencies. It might also be possible to resolve this by running parent-last and including a separate implementation along with the API (obviously, removing the Servlet API as referenced in the previous paragraph), although I'm not familiar enough with the Bean Validation API to know whether that would cause a conflict with the server runtime in the same way as Servlet.