lukas-krecan / ShedLock

Distributed lock for your scheduled tasks
Apache License 2.0
3.58k stars 508 forks source link

Spring transitive dependencies conflict #352

Closed alxsimo closed 3 years ago

alxsimo commented 3 years ago

Describe the bug Seems that the version included by shedlock clashes with spring-boot already in my project.

  1. Which version do you use: 4.15.1
  2. Which Lock Provider: shedlock-provider-jdbc-template
  3. ShedLock configuration:

Application.kt

@EnableScheduling
@EnableSchedulerLock(defaultLockAtMostFor = "10m")
class Application

fun main() {
  runApplication<Application>()
}

ShedLockConfiguration.kt


import net.javacrumbs.shedlock.core.LockProvider
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.jdbc.core.JdbcTemplate
import java.util.TimeZone
import javax.sql.DataSource

@Configuration
class ShedlockConfiguration {

  @Bean
  fun lockProvider(dataSource: DataSource): LockProvider =
    JdbcTemplateLockProvider(
      JdbcTemplateLockProvider.Configuration.builder()
        .withJdbcTemplate(JdbcTemplate(dataSource))
        .withTimeZone(TimeZone.getTimeZone("Europe/Madrid"))
        .build()
    )
}
  1. ShedLock logs
    
    2020-11-17 14:57:53.522  WARN 568 --- [           main] o.a.c.loader.WebappClassLoaderBase       : The web application [ROOT] appears to have started a thread named [RxIoScheduler-1 (Evictor)] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
    java.base@11.0.2/jdk.internal.misc.Unsafe.park(Native Method)
    java.base@11.0.2/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)
    java.base@11.0.2/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2123)
    java.base@11.0.2/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1182)
    java.base@11.0.2/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
    java.base@11.0.2/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1054)
    java.base@11.0.2/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1114)
    java.base@11.0.2/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    java.base@11.0.2/java.lang.Thread.run(Thread.java:834)
    2020-11-17 14:57:53.535  INFO 568 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2020-11-17 14:57:53.541 ERROR 568 --- [ main] o.s.boot.SpringApplication : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'functionCatalog' defined in class path resource [org/springframework/cloud/function/context/config/ContextFunctionCatalogAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.function.context.FunctionRegistry]: Factory method 'functionCatalog' threw exception; nested exception is java.lang.IllegalStateException: No bean class specified on bean definition at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:635) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:893) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391) at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) at com.schibsted.msmaauctions.infrastructure.framework.ApplicationKt.main(Application.kt:25) at com.schibsted.msmaauctions.infrastructure.framework.ApplicationKt.main(Application.kt) Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.function.context.FunctionRegistry]: Factory method 'functionCatalog' threw exception; nested exception is java.lang.IllegalStateException: No bean class specified on bean definition at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:650) ... 20 common frames omitted Caused by: java.lang.IllegalStateException: No bean class specified on bean definition at org.springframework.beans.factory.support.AbstractBeanDefinition.getBeanClass(AbstractBeanDefinition.java:436) at org.springframework.cloud.function.context.config.FunctionContextUtils.findType(FunctionContextUtils.java:70) at org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration$ContextFunctionRegistry.findType(ContextFunctionCatalogAutoConfiguration.java:582) at org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration$ContextFunctionRegistry.wrap(ContextFunctionCatalogAutoConfiguration.java:455) at org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration$ContextFunctionRegistry.lambda$merge$6(ContextFunctionCatalogAutoConfiguration.java:433) at java.base/java.lang.Iterable.forEach(Iterable.java:75) at org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration$ContextFunctionRegistry.merge(ContextFunctionCatalogAutoConfiguration.java:433) at org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration.functionCatalog(ContextFunctionCatalogAutoConfiguration.java:110) at org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration$$EnhancerBySpringCGLIB$$39195e05.CGLIB$functionCatalog$0() at org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration$$EnhancerBySpringCGLIB$$39195e05$$FastClassBySpringCGLIB$$fc25915e.invoke() at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) at org.springframework.cloud.function.context.config.ContextFunctionCatalogAutoConfiguration$$EnhancerBySpringCGLIB$$39195e05.functionCatalog() at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ... 21 common frames omitted

Process finished with exit code 1


**Expected behavior**
Should not give any exceptions.

**Actual behavior**
It fails because the library already imports transitively spring dependencies.

**Temporal fix**
In your `build.gradle`:

```gradle
    // Shedlock
    def shedlockVersion = "4.15.1"
    implementation("net.javacrumbs.shedlock:shedlock-spring:$shedlockVersion") {
      exclude group: "org.springframework", module: "spring-context"
    }
    implementation("net.javacrumbs.shedlock:shedlock-provider-jdbc-template:$shedlockVersion") {
      exclude group: "org.springframework", module: "spring-jdbc"
    }
lukas-krecan commented 3 years ago

Hi, thanks for feedback. There is not much I can do about it. If you have Spring version configured in your project (either directly or through dependency management plugin), it should override any transitive dependency including the one provided by ShedLock. If your Spring version is specified by another transitive dependency then the one specified in ShedLock may win.