1

I have a spring boot project that uses actuator that I am testing using karate. I recently attempted to update my project from using spring boot 2.4.5 to 2.5.0. Since making the change my tests are now failing with the following error:

    
    ***************************
    APPLICATION FAILED TO START
    ***************************
    
    Description:
    
    An attempt was made to call a method that does not exist. The attempt was made from the following location:
    
        org.springframework.boot.actuate.autoconfigure.metrics.mongo.MongoMetricsAutoConfiguration$MongoConnectionPoolMetricsConfiguration.mongoMetricsConnectionPoolListener(MongoMetricsAutoConfiguration.java:91)
    
    The following method did not exist:
    
        'void io.micrometer.core.instrument.binder.mongodb.MongoMetricsConnectionPoolListener.<init>(io.micrometer.core.instrument.MeterRegistry, io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider)'
    
    The method's class, io.micrometer.core.instrument.binder.mongodb.MongoMetricsConnectionPoolListener, is available from the following locations:
    
        jar:file:/Users/michaelruocco/.gradle/caches/modules-2/files-2.1/com.intuit.karate/karate-core/1.0.1/3f16197bf259d591cc73df52de7aa0a0fb4f2db6/karate-core-1.0.1.jar!/io/micrometer/core/instrument/binder/mongodb/MongoMetricsConnectionPoolListener.class
        jar:file:/Users/michaelruocco/.gradle/caches/modules-2/files-2.1/io.micrometer/micrometer-core/1.7.0/bc7dc1605f2099dc3c39156b7f62ac889f54fb67/micrometer-core-1.7.0.jar!/io/micrometer/core/instrument/binder/mongodb/MongoMetricsConnectionPoolListener.class
    
    The class hierarchy was loaded from the following locations:
    
        io.micrometer.core.instrument.binder.mongodb.MongoMetricsConnectionPoolListener: file:/Users/michaelruocco/.gradle/caches/modules-2/files-2.1/com.intuit.karate/karate-core/1.0.1/3f16197bf259d591cc73df52de7aa0a0fb4f2db6/karate-core-1.0.1.jar
        com.mongodb.event.ConnectionPoolListenerAdapter: file:/Users/michaelruocco/.gradle/caches/modules-2/files-2.1/org.mongodb/mongo-java-driver/3.12.8/d9e12b2056cea964a3805558382e0d30596444c5/mongo-java-driver-3.12.8.jar
    
    
    Action:
    
    Correct the classpath of your application so that it contains a single, compatible version of io.micrometer.core.instrument.binder.mongodb.MongoMetricsConnectionPoolListener

Looking at the contents of the karate-core-1.0.1.jar it has copies of these micrometer classes shaded inside the jar itself, rather than pulling them as dependencies, this means there is no way for me to exclude this dependency in my gradle file. I can also see these classes are deliberately shaded here: https://github.com/intuit/karate/blob/master/karate-core/pom.xml#L203.

Spring boot 2.4.5 actuator is using micrometer-core version: 1.6.6 Spring boot 2.5.0 actuator is using micrometer-core version: 1.7.0

So I expect the issue is that there is a breaking change between these two versions causing the problem. In order to get karate-core to place nicely with spring-boot 2.5.0 I would require a version of karate-core that is compatible with micrometer-core 1.7.0. I can't see any direct dependencies on micrometer from karate-core itself so I guess maybe it is pulling it in transitively?

I've also tried to exclude the micrometer-core dependency that actuator is pulling in, but this breaks the actuator functionality resulting in:

     Caused by: java.lang.IllegalStateException: @ConditionalOnMissingBean did not specify a bean using type, name or annotation and the attempt to deduce the bean's type failed
        at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.validate(OnBeanCondition.java:487)
        at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.<init>(OnBeanCondition.java:436)
        at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:142)
        at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47)
        ... 113 more
      Caused by: org.springframework.boot.autoconfigure.condition.OnBeanCondition$BeanTypeDeductionException: Failed to deduce bean type for org.springframework.boot.actuate.autoconfigure.metrics.mongo.MongoMetricsAutoConfiguration$MongoConnectionPoolMetricsConfiguration.mongoConnectionPoolTagsProvider
        at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.deducedBeanTypeForBeanMethod(OnBeanCondition.java:517)
        at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.deducedBeanType(OnBeanCondition.java:506)
        at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.<init>(OnBeanCondition.java:429)
        ... 115 more
      Caused by: java.lang.ClassNotFoundException: io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:606)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:468)
        at org.springframework.boot.autoconfigure.condition.FilteringSpringBootCondition.resolve(FilteringSpringBootCondition.java:108)
        at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.getReturnType(OnBeanCondition.java:525)
        at org.springframework.boot.autoconfigure.condition.OnBeanCondition$Spec.deducedBeanTypeForBeanMethod(OnBeanCondition.java:513)
        ... 117 more

Are there any plans to create a version of karate-core that might work with spring boot 2.5.0? Or does anyone have any other suggestions for how I can work around this issue?

1 Answers1

0

Yeah we certainly never anticipated this. We probably have to think about releasing a separate "non-shaded" artifact for teams.

Feel free to open an issue and we'll look into it. Of course if you can contribute, nothing like it.

For the time being can you try this and let me know how it goes. I think you should be able to create your own JAR locally and use maven-shade to remove micrometer from the karate fat-jar. Then use that dependency in your project. I can't think of anything else.

Peter Thomas
  • 54,465
  • 21
  • 84
  • 248
  • Ah yeah thats a good suggestion. I am a bit busy with work this week but ill try and have a look over the weekend. Thanks. – Michael Ruocco May 26 '21 at 20:20
  • @MichaelRuocco I opened an issue and it should be resolved for the next version: https://github.com/intuit/karate/issues/1621 - it would be of great help if you can follow the developer guide and confirm it works in your spring boot project: https://github.com/intuit/karate/wiki/Developer-Guide – Peter Thomas May 27 '21 at 03:32
  • Ah thats brilliant, ill give that a go shortly, I had just pulled the karate repo and built a version with micrometer removed from being shaded and that was working fine, but probably isn't a very neat or future proofed solution. Ill try the above now. – Michael Ruocco May 27 '21 at 06:28
  • 1
    I have just given this a try locally and my project has worked fine. I am not sure if you are probably aware, but just FYI, when I ran a full `mvn clean install` (the first time) the tests for the demo project failed, although I just tried again and the second time everything passed. After I following the guide as you suggested I ran `mvn clean install -P pre-release -pl karate-core,karate-junit5` which worked fine, when I used the built karate-core and karate-junit versions with my project it resolved the issue I was seeing. Ive marked your answer as accepted, thanks for the fast fix! – Michael Ruocco May 27 '21 at 06:42