After upgrading spring boot from 3.3.5 to 3.4.2 in microservices , Spring Boot JUnits are failing with below error

Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.test.web.client.TestRestTemplate': java.io.IOException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext)

Caused by: java.io.IOException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext)
    ... 112 common frames omitted
Caused by: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext)
    at java.base/java.security.Provider$Service.newInstance(Provider.java:1868) ~[na:na]
    at java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:236) ~[na:na]
    at java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:164) ~[na:na]
    at java.base/javax.net.ssl.SSLContext.getInstance(SSLContext.java:185) ~[na:na]
    at java.base/javax.net.ssl.SSLContext.getDefault(SSLContext.java:110) ~[na:na]
    at java.net.http/jdk.internal.net.http.HttpClientImpl.<init>(HttpClientImpl.java:283) ~[java.net.http:na]
    ... 111 common frames omitted
Caused by: java.security.KeyManagementException: problem accessing trust store
    at java.base/sun.security.ssl.SSLContextImpl$DefaultManagersHolder.<clinit>(SSLContextImpl.java:942) ~[na:na]
    at java.base/sun.security.ssl.SSLContextImpl$DefaultSSLContext.<init>(SSLContextImpl.java:1111) ~[na:na]
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]

application-test.properties

spring.ssl.bundle.jks.kafka.truststore.location=classpath:client-truststore.jks
spring.ssl.bundle.jks.kafka.truststore.password=password
spring.ssl.bundle.jks.kafka.keystore.location=classpath:client-keystore.jks
spring.ssl.bundle.jks.kafka.keystore.password=password

Comment From: Niserga

Junit looks something like below

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@TestPropertySource(
    value = "classpath:application-test.properties",
    properties = {
        "commons.kafka.stream.core.system.cert.configuration.enabled=true"
    })
public class KafkaSslConfigEnabledTest {

    @Inject
    private ApplicationContext applicationContext;

    @Test
    public void kafkaSslConfigBeanShouldExist() {
        applicationContext.getBean(KafkaSslConfig.class);
    }
}

Bean Class

@Slf4j
@Configuration
@ConditionalOnProperty(prefix = "commons.kafka.stream.core.system.cert.configuration", name = "enabled", matchIfMissing = true)
public class KafkaSslConfig {

    @Value("${spring.ssl.bundle.jks.kafka.keystore.location}")
    private String keystoreLocation;

    @Value("${spring.ssl.bundle.jks.kafka.keystore.password}")
    private String keystorePassword;

    @Value("${spring.ssl.bundle.jks.kafka.truststore.location}")
    private String truststoreLocation;

    @Value("${spring.ssl.bundle.jks.kafka.truststore.password}")
    private String truststorePassword;

    @PostConstruct
    public void setSslSystemProperty() {
        log.info(
            "setup kafka ssl-->start for keystore={}, truststore={}",
            this.keystoreLocation,
            this.truststoreLocation);
        System.setProperty("javax.net.ssl.keyStore", this.keystoreLocation);
        System.setProperty("javax.net.ssl.keyStorePassword", this.keystorePassword);
        System.setProperty("javax.net.ssl.trustStore", this.truststoreLocation);
        System.setProperty("javax.net.ssl.trustStorePassword", this.truststorePassword);
    }

}

Comment From: philwebb

I've edited your comment to improve the formatting. You might want to check out this Mastering Markdown guide for future reference.

Comment From: philwebb

From the snippets provided, it seems that you have a very unusual setup where you're trying to use @Value annotations with our spring.ssl.bundle properties. The stacktrace also don't appear to have any Spring Boot classes in it.

As such, I suspect the problem isn't in Spring Boot but rather something specific to your application. I think you would be better trying asking a question on Stack Overflow. When you do so, I would suggest providing a minimal, reproducible example that recreates the problem.

Comment From: Niserga

Thanks for the reply.

@Value("${spring.ssl.bundle.jks.kafka.keystore.location}") --> it is just variable name to hold keystore and truststore details set in a application-test.properties.

I have modified to another name. Still same issue.

Pleas find below modified application-test.properties

commons.kafka.stream.core.system.cert.configuration.enabled=false

spring.cloud.stream.kafka.streams.binder.configuration.ssl.truststore.location=classpath:client-truststore.jks
spring.cloud.stream.kafka.streams.binder.configuration.ssl.truststore.password=password
spring.cloud.stream.kafka.streams.binder.configuration.ssl.keystore.location=classpath:client-keystore.jks
spring.cloud.stream.kafka.streams.binder.configuration.ssl.keystore.password=password

and also bean KafkaSslConfig.java

@Slf4j
@Configuration
@ConditionalOnProperty(prefix = "commons.kafka.stream.core.system.cert.configuration", name = "enabled", matchIfMissing = true)
public class KafkaSslConfig {

    @Value("${spring.cloud.stream.kafka.streams.binder.configuration.ssl.keystore.location}")
    private String keystoreLocation;

    @Value("${spring.cloud.stream.kafka.streams.binder.configuration.ssl.keystore.password}")
    private String keystorePassword;

    @Value("${spring.cloud.stream.kafka.streams.binder.configuration.ssl.truststore.location}")
    private String truststoreLocation;

    @Value("${spring.cloud.stream.kafka.streams.binder.configuration.ssl.truststore.password}")
    private String truststorePassword;

    @PostConstruct
    public void setSslSystemProperty() {
        log.info(
            "setup kafka ssl-->start for keystore={}, truststore={}",
            this.keystoreLocation,
            this.truststoreLocation);
        System.setProperty("javax.net.ssl.keyStore", this.keystoreLocation);
        System.setProperty("javax.net.ssl.keyStorePassword", this.keystorePassword);
        System.setProperty("javax.net.ssl.trustStore", this.truststoreLocation);
        System.setProperty("javax.net.ssl.trustStorePassword", this.truststorePassword);
    }

}

Comment From: Niserga

and When i did debug mode error (Caused by: java.security.KeyManagementException: problem accessing trust store) is coming from ,SSLContextImpl->getTrustManagers(). Null being passed for keystore for provider "SunJSSE"

private static TrustManager[] getTrustManagers() throws Exception {
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(
                    TrustManagerFactory.getDefaultAlgorithm());
            if ("SunJSSE".equals(tmf.getProvider().getName())) {
                // The implementation will load the default KeyStore
                // automatically.  Cached trust materials may be used
                // for performance improvement.
                tmf.init((KeyStore)null);
            } else {
                // Use the explicitly specified KeyStore for third party's
                // TrustManagerFactory implementation.
                KeyStore ks = TrustStoreManager.getTrustedKeyStore();
                tmf.init(ks);
            }

            return tmf.getTrustManagers();
        }

But in case of Springboot 3.3.5,we dont have any issue and also in debug mode with Springboot 3.3.5 ,control would not go to SSLContextImpl->getTrustManagers().Test cases runs successfull...

The issue seems to be related to the SSL configuration when the TestRestTemplate is initialized or @SpringBootTest

could you please guide on this.

Comment From: Niserga

as per the error trace,Error creating bean TestRestTemplate

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.test.web.client.TestRestTemplate': java.io.IOException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext)

Comment From: Niserga

As per this https://docs.spring.io/spring-boot//api/java/org/springframework/boot/test/web/client/TestRestTemplate.html

If you are using the @SpringBootTest annotation with an embedded server, a TestRestTemplate is automatically available.

may be while initializing TestRestTemplate bean,getting java.security.NoSuchAlgorithmException Caused by: java.security.KeyManagementException: problem accessing trust store

Comment From: philwebb

Each comment that you add to this issue causes a notification for folks watching the repository so it's best if you can consolidate your thoughts before posting. It's still not clear that this is a Spring Boot issue, and we're not going to be able to determine what is causing the exception without a sample application that reproduces the problem.

Comment From: Niserga

Since my junit had @SpringBootTest, internally it might be trying to create the bean TestRestTemplate .On that time below error was

Caused by: org.springframework.beans.factory.BeanCreationException: **Error creating bean with name 'org.springframework.boot.test.web.client.TestRestTemplate': java.io.IOException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext)**

 Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext)
    ... 112 common frames omitted
Caused by: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext)
    at java.base/java.security.Provider$Service.newInstance(Provider.java:1868) ~[na:na]
    at java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:236) ~[na:na]
    at java.base/sun.security.jca.GetInstance.getInstance(GetInstance.java:164) ~[na:na]
    at java.base/javax.net.ssl.SSLContext.getInstance(SSLContext.java:185) ~[na:na]
    at java.base/javax.net.ssl.SSLContext.getDefault(SSLContext.java:110) ~[na:na]
    at java.net.http/jdk.internal.net.http.HttpClientImpl.<init>(HttpClientImpl.java:283) ~[java.net.http:na]
    ... 111 common frames omitted
**Caused by: java.security.KeyManagementException: problem accessing trust store**
    at java.base/sun.security.ssl.SSLContextImpl$DefaultManagersHolder.<clinit>(SSLContextImpl.java:942) ~[na:na]
    at java.base/sun.security.ssl.SSLContextImpl$DefaultSSLContext.<init>(SSLContextImpl.java:1111) ~[na:na]
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:na]

Keystore was tampered with, or password was incorrect

Comment From: Niserga

Image Stack trace from spring boot

Comment From: philwebb

@Niserga As I've already asked, please stop adding so many comments to this issue. If you think you've found a bug, you need to provide a sample application as a GitHub project or zip file that we can run. If you're looking for general help then please ask on stackoverflow.com.