Если spring-cloud-stream находится в classpath, автоконфигурация spring-boot ищет связыватель по умолчанию - PullRequest
0 голосов
/ 20 марта 2020

Я работаю над мультимодульным приложением с пружинной загрузкой, где мы создаем один нестандартный жирный jar-файл для привязки всех сторонних зависимостей. Spring cloud stream также является частью этой жирной банки. Наше приложение работало на spring-cloud-stream версии 2.1.3.RELEASE (spring-boot 2.1.6.RELEASE), и мы обновляем его до 3.0.2.RELEASE (spring-boot 2.2.4.RELEASE). Мы испытываем здесь проблему. Если конкретный модуль, в котором нет использования spring-cloud-stream, но spring-cloud-stream, находится на пути к классам, то подпружиненный загрузчик auto-configuration ищет default binder.

{"mdc":{},"timestamp":"2020-03-20 12:53:04.150","level":"ERROR","logger":"org.springframework.boot.SpringApplication",
"message":"Application run failed", "exception":"\r\norg.springframework.context.ApplicationContextException: 
Failed to start bean 'outputBindingLifecycle'; 
nested exception is java.lang.IllegalArgumentException: <b>A default binder has been requested, but there is no binder available</b>\r\n\
 org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:185)\r\n\
 org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:53)\r\n\
 org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:360)\r\n\
 org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:158)\r\n\
 org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:122)\r\n\
 org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:894)\r\n\
 org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:162)\r\n\
 org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553)\r\n\
 org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)\r\n\
 org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)\r\n\
 org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)\r\n\
 org.springframework.boot.SpringApplication.run(SpringApplication.java:315)\r\n\
 org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:126)\r\n\
 org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal
 (DefaultCacheAwareContextLoaderDelegate.java:99)\r\n\
 org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)\r\n\
 org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123)\r\n\
 org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.outputConditionEvaluationReport
 (SpringBootDependencyInjectionTestExecutionListener.java:53)\r\n\
 org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance
 (SpringBootDependencyInjectionTestExecutionListener.java:46)\r\n\
 org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244)\r\n\
 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)\r\n\
 org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)\r\n\
 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)\r\n\
 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)\r\n\
 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)\r\n\
 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)\r\n\
 org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)\r\n\
 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)\r\n\
 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)\r\n\
 org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)\r\n\
 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)\r\n\
 org.springframework.test.context.junit4.s
ements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)\r\n\
 org.springframework.test.context.junit4.s
ements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)\r\n\
 org.junit.runners.ParentRunner.run(ParentRunner.java:363)\r\n\
 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)\r\n\
 org.junit.runner.JUnitCore.run(JUnitCore.java:137)\r\n\
 org.junit.runner.JUnitCore.run(JUnitCore.java:115)\r\n\
 org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:40)\r\n\
 java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)\r\n\
 java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)\r\n\
 java.util.Iterator.forEachRemaining(Unknown Source)\r\n\
 java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)\r\n\
 java.util.stream.AbstractPipeline.copyInto(Unknown Source)\r\n\
 java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)\r\n\
 java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)\r\n\
 java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)\r\n\
 java.util.stream.AbstractPipeline.evaluate(Unknown Source)\r\n\
 java.util.stream.ReferencePipeline.forEach(Unknown Source)\r\n\
 org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:80)\r\n\
 org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:71)\r\n\
 org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)\r\n\
 org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)\r\n\
 org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)\r\n\
 org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)\r\n\
 org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:137)\r\n\
 org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:89)\r\n\
 org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)\r\n\
 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)\r\n\
 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)\r\n\
 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)\r\n\
 org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)\r\nCaused by: 
 java.lang.IllegalArgumentException: A default binder has been requested, but there is no binder 
 available\r\n\
 org.springframework.util.Assert.notEmpty(Assert.java:549)\r\n\
 org.springframework.cloud.stream.binder.DefaultBinderFactory.doGetBinder(DefaultBinderFactory.java:144)\r\n\
 org.springframework.cloud.stream.binder.DefaultBinderFactory.getBinder(DefaultBinderFactory.java:134)\r\n\
 org.springframework.cloud.stream.binding.BindingService.getBinder(BindingService.java:362)\r\n\
 org.springframework.cloud.stream.binding.BindingService.bindProducer(BindingService.java:257)\r\n\
 org.springframework.cloud.stream.binding.AbstractBindableProxyFactory.createAndBindOutputs(AbstractBindableProxyFactory.java:136)\r\n\
 org.springframework.cloud.stream.binding.OutputBindingLifecycle.doStartWithBindable(OutputBindingLifecycle.java:58)\r\n\
 java.util.LinkedHashMap$LinkedValues.forEach(Unknown Source)\r\n\
 org.springframework.cloud.stream.binding.AbstractBindingLifecycle.start(AbstractBindingLifecycle.java:57)\r\n\
 org.springframework.cloud.stream.binding.OutputBindingLifecycle.start(OutputBindingLifecycle.java:34)\r\n\
 org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:182)\r\n\t... 59 common frames omitted\r\n\r\n"}

. мы можем использовать два подхода: -

  • Нет смысла использовать spring-cloud-stream, поэтому я могу исключить spring-cloud-stream из этой жирной банки, чтобы он не искал связующего.
  • Приведенная ниже зависимость предоставляет связыватель тестов, поэтому без реализации реального связывателя мы можем протестировать наше приложение, используя его.
<dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-stream-test-support</artifactId>
       <version>3.0.2.RELEASE</version>
       <scope>test</scope>
   </dependency>

Я бы хотелось бы знать, есть ли какой-либо другой метод или настраиваемое свойство, которое я могу использовать в приложении, чтобы я мог прекратить поиск связующего по умолчанию.

1 Ответ

1 голос
/ 20 марта 2020

Я думаю, что вы идете вразрез с принципами весенней загрузки с таким подходом и, следовательно, создаете очень большие электронные JAR-файлы, которые содержат зависимости, которые никогда не используются. Конечно, вы можете использовать exclude атрибут @SpringBootApplication и исключить некоторые классы автоконфигурации. Но я на самом деле спрашиваю, почему на пути к классам есть что-то, что никогда не используется, независимо от того, является ли JAR с автоматической настройкой или просто библиотечным JAR? Более того, существуют временные зависимости, поэтому с s- c -stream вы привносите много других JAR-файлов, которые могут фактически создать конфликт с вещами, которые вы намереваетесь использовать.

...