Upgrading from Spring 4 to Spring 5 - NoClassDefFoundError: org/springframework/core/JdkVersion

Viewed 1184

I am upgrading my Spring project from version 4.3.23 to version 5.2.13

I have the following code in my ldap.xml file in the project which was working fine in 4.3.23 but erroring out in 5.2.13:

<bean id="contextSourceReadTarget" class="org.springframework.ldap.core.support.LdapContextSource">
        <property name="urls" value="ldap://localhost:12345" />
        <property name="base" value="dc=memorynotfound,dc=com" />
        <property name="userDn" value="uid=admin" />
        <property name="password" value="secret" />
        <property name="dirObjectFactory"
            value="org.springframework.ldap.core.support.DefaultDirObjectFactory" />
        <property name="pooled" value="false" />
        <property name="referral" value="follow" />
</bean>

But when running the code I am getting java.lang.NoClassDefFoundError: org/springframework/core/JdkVersion

After searching I found that JdkVersion is removed in Spring 5.x

I would like to know how I can fix my code to work fine with Spring 5.x.

Here is the complete stacktrace of the error:

java.lang.NoClassDefFoundError: org/springframework/core/JdkVersion
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1799)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:401)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:292)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
        at weblogic.servlet.internal.EventsManager$FireContextListenerAction.run(EventsManager.java:719)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:344)
        at weblogic.security.service.SecurityManager.runAsForUserCode(SecurityManager.java:197)
        at weblogic.servlet.provider.WlsSecurityProvider.runAsForUserCode(WlsSecurityProvider.java:203)
        at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.java:71)
        at weblogic.servlet.internal.EventsManager.executeContextListener(EventsManager.java:251)
        at weblogic.servlet.internal.EventsManager.notifyContextCreatedEvent(EventsManager.java:204)
        at weblogic.servlet.internal.EventsManager.notifyContextCreatedEvent(EventsManager.java:189)
        at weblogic.servlet.internal.WebAppServletContext.preloadResources(WebAppServletContext.java:1929)
        at weblogic.servlet.internal.WebAppServletContext.start(WebAppServletContext.java:3191)
        at weblogic.servlet.internal.WebAppModule.startContexts(WebAppModule.java:1864)
        at weblogic.servlet.internal.WebAppModule.start(WebAppModule.java:919)
        at weblogic.application.internal.ExtensibleModuleWrapper$StartStateChange.next(ExtensibleModuleWrapper.java:360)
        at weblogic.application.internal.ExtensibleModuleWrapper$StartStateChange.next(ExtensibleModuleWrapper.java:356)
        at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45)
        at weblogic.application.internal.ExtensibleModuleWrapper.start(ExtensibleModuleWrapper.java:138)
        at weblogic.application.internal.flow.ModuleListenerInvoker.start(ModuleListenerInvoker.java:124)
        at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:233)
        at weblogic.application.internal.flow.ModuleStateDriver$3.next(ModuleStateDriver.java:228)
        at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45)
        at weblogic.application.internal.flow.ModuleStateDriver.start(ModuleStateDriver.java:78)
        at weblogic.application.internal.flow.StartModulesFlow.activate(StartModulesFlow.java:52)
        at weblogic.application.internal.BaseDeployment$2.next(BaseDeployment.java:752)
        at weblogic.application.utils.StateMachineDriver.nextState(StateMachineDriver.java:45)
        at weblogic.application.internal.BaseDeployment.activate(BaseDeployment.java:262)
        at weblogic.application.internal.EarDeployment.activate(EarDeployment.java:66)
        at weblogic.application.internal.DeploymentStateChecker.activate(DeploymentStateChecker.java:165)
        at weblogic.deploy.internal.targetserver.AppContainerInvoker.activate(AppContainerInvoker.java:90)
        at weblogic.deploy.internal.targetserver.BasicDeployment.activate(BasicDeployment.java:274)
        at weblogic.deploy.internal.targetserver.BasicDeployment.activateFromServerLifecycle(BasicDeployment.java:507)
        at weblogic.management.deploy.internal.DeploymentAdapter$1.doActivate(DeploymentAdapter.java:53)
        at weblogic.management.deploy.internal.DeploymentAdapter.activate(DeploymentAdapter.java:202)
        at weblogic.management.deploy.internal.AppTransition$2.transitionAppInternal(AppTransition.java:53)
        at weblogic.management.deploy.internal.AppTransition.transitionApp(AppTransition.java:138)
        at weblogic.management.deploy.internal.ConfiguredDeployments$2.doItem(ConfiguredDeployments.java:741)
        at weblogic.management.deploy.internal.parallel.BucketInvoker$2.run(BucketInvoker.java:95)
        at weblogic.work.ContextWrap.run(ContextWrap.java:46)
        at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:681)
        at weblogic.invocation.ComponentInvocationContextManager._runAs(ComponentInvocationContextManager.java:352)
        at weblogic.invocation.ComponentInvocationContextManager.runAs(ComponentInvocationContextManager.java:337)
        at weblogic.work.LivePartitionUtility.doRunWorkUnderContext(LivePartitionUtility.java:57)
        at weblogic.work.PartitionUtility.runWorkUnderContext(PartitionUtility.java:41)
        at weblogic.work.SelfTuningWorkManagerImpl.runWorkUnderContext(SelfTuningWorkManagerImpl.java:655)
        at weblogic.work.ExecuteThread.execute(ExecuteThread.java:420)
        at weblogic.work.ExecuteThread.run(ExecuteThread.java:360)
Caused by: java.lang.NoClassDefFoundError: org/springframework/core/JdkVersion
        at org.springframework.ldap.core.support.AbstractContextSource.getJdkVersion(AbstractContextSource.java:485)
        at org.springframework.ldap.core.support.AbstractContextSource.afterPropertiesSet(AbstractContextSource.java:342)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1858)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1795)
        ... 57 more

Thanks in advance!

3 Answers

I assume you’re not using Spring boot and we’re talking about the “plain spring” application.

Obviously the code within spring framework that tries to use the missing class belongs to spring 4 ecosystem (otherwise any application that depends on Spring 5 and uses ldap integration would have failed and spring team would have had a major bug on that)

Assuming there is no major bug on that, there must be some spring 4 jar in the class path of your application

So I suggest doing the following:

  1. Check the class path. Since I assume, you’re compiling a WAR - open up the artifact with WinRar or something and see the content of WEB-INF/lib folder. If you see something that belongs to spring 4 - fix your pom.xml with correct dependencies. If you compile EAR - it might have many modules that should be checked but basically the procedure is the same, I’m sure you’ve got the point

  2. Weblogic might have some “shared” jars (including spring) in some shared folder. I’m not really familiar with this application server, but the chances are that these jars belong to spring 4 ecosystem and they might “find their way” to the class path of your application in runtime. Maven won’t obviously show that.

spring-ldap.jar was used to interact with LDAP in Spring 4 but this jar is not compatible with Spring 5 and leads to NoClassDefFoundError: org/springframework/core/JdkVersion

As JdkVersion class is removed from spring-core jar in Spring 5

If you require Spring for LDAP in Spring 5 use spring-ldap-core dependency

<dependency>
   <groupId>org.springframework.ldap</groupId>
   <artifactId>spring-ldap-core</artifactId>
   <version>2.3.4.RELEASE</version>
</dependency>

Also check if there are any other older spring jars.

you should update all your spring dependencies together (in this case, spring ldap), check if all your spring dependencies are updated to spring 5, because spring is a very modular framework, it's always helpful to define a variable regarding version management of it's modules

Related