java.lang.IllegalArgumentException: Environment must not be null - spring

I try to setup a basic SolrRepository app and Have this error during ApplicationContext load :
Caused by: java.lang.IllegalArgumentException: Environment must not be null!
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.data.repository.config.RepositoryConfigurationSourceSupport.<init>(RepositoryConfigurationSourceSupport.java:50)
at org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource.<init>(AnnotationRepositoryConfigurationSource.java:74)
at org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport.registerBeanDefinitions(RepositoryBeanDefinitionRegistrarSupport.java:74)
at org.springframework.context.annotation.ConfigurationClassParser.processImport(ConfigurationClassParser.java:394)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:204)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:163)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:138)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:284)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:225)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:630)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:461)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:120)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:248)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
... 28 more
Here is my ConfigClass :
#Configuration
#PropertySource("classpath:sandbox.properties")
#ComponentScan("sandbox.solr")
#EnableSolrRepositories(basePackages = { "sandbox.solr.repository" }, multicoreSupport = true)
public class StreamingSolrConf {
#Resource
private Environment env;
#Bean
public SolrServer solrServer() {
return new HttpSolrServer(env.getRequiredProperty("solr.server.url"));
}
#Bean
public SolrTemplate solrTemplate() {
return new SolrTemplate(solrServer());
}
}
And my repository interface :
package sandbox.solr.repository;
import org.springframework.data.solr.repository.SolrCrudRepository;
public interface SandboxRepository extends SolrCrudRepository<Document, String> {
}
Can't figure why the Environment is not injected at the right time inside the spring context.
What did I miss ?
Regards.

Just to solve this Question (see comments on original question):
He was using the spring-data-solr-1.2.1.RELEASE with spring-3.2.8.RELEASE either.
Downgrading to spring-data-solr-1.1.3-RELEASE and stay with spring-3.2.8.RELEASE or upgrade to spring-3.2.9.RELEASE to keep spring-data-solr-1.2.1.RELEASE will solve the issue.

Related

Error upgrading Spring Boot 2.2.7 to Spring Boot 2.3.0

I was using Spring Boot 2.2.7.RELEASE and everthing was working well.
When i upgraded to Spring Boot 2.3.0.RELEASE, a few issues start to show up, i was able to resolve them except for this.
I have this class:
#Configuration
#EnableCaching
public class CacheConfiguration extends CachingConfigurerSupport {
public static final String PROPERTY_RESOLVING_CACHE_RESOLVER_BEAN_NAME = "propertyResolvingCacheResolver";
#Value("${my.cache.name}")
private String myCacheName;
#Autowired
private Environment environment;
#Bean(PROPERTY_RESOLVING_CACHE_RESOLVER_BEAN_NAME)
#Override
public CacheResolver cacheResolver() {
return new PropertyResolvingCacheResolver(cacheManager(), environment);
}
#Bean
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache(myCacheName)));
return cacheManager;
}
}
and the error i am getting is this:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'environment' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:814)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1282)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:297)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$ShortcutDependencyDescriptor.resolveShortcut(AutowiredAnnotationBeanPostProcessor.java:796)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1238)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1226)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.resolvedCachedArgument(AutowiredAnnotationBeanPostProcessor.java:601)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.access$000(AutowiredAnnotationBeanPostProcessor.java:131)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:631)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
... 66 common frames omitted
I thought it was an issue with the 'life-cycle' of the beans, and i was auto-wiring too early, so i did this:
public class CacheConfiguration extends CachingConfigurerSupport implements EnvironmentAware {
...
private Environment environment;
...
#Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
...
But then, other issues start showing(after doing the above) like:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:814)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1282)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:297)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207)
at org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor.postProcessBeforeInitialization(ConfigurationClassPostProcessor.java:456)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:416)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1788)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595)
... 45 common frames omitted
This is getting out of my league, any help would be much appreciated, thanks!
Edit 1:
After experimenting a bit, the issue is because the creation of this bean #Bean(PROPERTY_RESOLVING_CACHE_RESOLVER_BEAN_NAME) is deferred to a later time.
It used to be created after cacheManager, but in 2.3.0.RELEASE, it's not anymore.
Edit 2:
DataSourceHealthIndicator is in the application context under bean name dbHealthContributor for both 2.2.7.RELEASE & 2.3.0.RELEASE.
This can be seen under /actuator/beans :
"dbHealthContributor": {
"aliases": [],
"scope": "singleton",
"type": "org.springframework.boot.actuate.jdbc.DataSourceHealthIndicator",
"resource": "class path resource [org/springframework/boot/actuate/autoconfigure/jdbc/DataSourceHealthContributorAutoConfiguration.class]",
"dependencies": [
"dataSource"
]
},
A bit late to the game, but I ran into the same problem when upgrading Spring Boot from 2.2.0 to 2.3.0. You could also solve the problem by using Spring's #Lazy annotation. That way the DataSourceHealthIndicator would be autowired later when it actually gets used and by that time the autoconfiguration would make it available for autowiring. And you wouldn't have to define your own bean like you did in your answer.
So instead of
#Autowired
private DataSourceHealthIndicator dataSourceHealthIndicator;
, you would use
#Autowired
#Lazy
private DataSourceHealthIndicator dataSourceHealthIndicator;
By having trace=true in application.properties, i managed to pin-point the issue.
I used to have this working(provided for free by Spring Boot):
#Autowired
private DataSourceHealthIndicator dataSourceHealthIndicator;
But it seems that dataSourceHealthIndicator 's creation has been delayed so that when my bean(that needs it) is being created, it couldn't find it and autowiring failed.
I therefore created it manually:
#Bean
#Primary
public DataSourceHealthIndicator dataSourceHealthIndicator(DataSource dataSource) {
return new DataSourceHealthIndicator(dataSource, "SELECT 1 FROM DUAL");
}
and my error is gone.
I hope to be able to understand what happened to
dataSourceHealthIndicator between 2.2.7.RELEASE and
2.3.0.RELEASE. I do not see anything mention about it in the
Spring-Boot-2.3-Release-Notes
or i have missed it, but i can still see it being "created" - see my Edit 2 in my question.

After migrating to Spring Boot 2.1.7 RELEASE-initializeBean not working

After migrating spring4.1.7 to spring boot2.1.7 Release.Its showing an error for bean creation while initializing application context.
Error Log
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'localConfig' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:771)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1221)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:307)
... 25 more
ServiceConfiguration Class
#Configuration
#Profile(ContextProfileNames.SERVICE)
#EnableWebMvc
#ComponentScan(basePackages = "com.get.services")
#Import(ControllerConfiguration.class)
public class ServiceConfiguration implements InitializingBean
{
#Autowired
private ApplicationContext context;
#Bean(name = "localConfig")
#DependsOn(BeanNames.CONFIGURATION_FACTORY)
#Scope("singleton")
public LocalDataSourceConfiguration getLocalDataSourceConfiguration() throws XEDecryptionException
{
ConfigurationFactory configurationFactory = (ConfigurationFactory) context
.getBean(BeanNames.CONFIGURATION_FACTORY);
LocalDataSourceConfig localDataSourceConfig = configurationFactory.getLocalDataSourceConfiguration();
LocalDataSourceConfiguration localDataSourceConfiguration = new LocalDataSourceConfiguration(
localDataSourceConfig.isMsSqlConfigured(), localDataSourceConfig.isSybaseConfigured(),
localDataSourceConfig.getServiceConfigurationMode(), getLocalDBConfigurationInfo(
localDataSourceConfig.getDbConfigurations().getDbConfigInfo(), configurationFactory));
localDataSourceConfiguration
.setUseRisExamIdAsAccession(Boolean.parseBoolean(localDataSourceConfig.getUseRisExamIdAsAccession()));
localDataSourceConfiguration.setCpacsNameFormat(localDataSourceConfig.getCpacsNameFormat());
localDataSourceConfiguration.setTableCacheRefreshInterval(localDataSourceConfig.getTableCacheRefreshInterval());
localDataSourceConfiguration.setAuthorityMatchingMode(localDataSourceConfig.getAuthorityMatchingMode());
return localDataSourceConfiguration;
}
}
How can i resolve this issue?.did i miss anything?
Added #profile in main class.Issue resolved

Spring boot application does not find placeholder 'spring.embedded.kafka.brokers' for a spock-spring test

I am trying to do an integration test with Spring Boot, Spock-Spring and Embedded Kafka. I followed this guide, where I found "As the embedded broker is started on a random port, we can’t use the fix value in the src/main/resources/application.yml properties file. Luckily the #ClassRule sets a spring.embedded.kafka.brokers system property to the address of the embedded broker(s)." Hence I have
#ContextConfiguration
#SpringBootTest(classes = [Application], webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#DirtiesContext
#Stepwise
#ActiveProfiles("test")
class AnIntegrationTest extends Specification {
#Autowired
private KafkaListenerEndpointRegistry kafkaListenerEndpointRegistry
#ClassRule
public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, "topic")
private KafkaTemplate<String, String> template
def setup() {
Map<String, Object> senderProperties = KafkaTestUtils.senderProps(embeddedKafka.getBrokersAsString())
ProducerFactory<String, String> producerFactory =
new DefaultKafkaProducerFactory<String, String>(senderProperties)
template = new KafkaTemplate<>(producerFactory)
template.setDefaultTopic("topic")
for (MessageListenerContainer messageListenerContainer : kafkaListenerEndpointRegistry
.getListenerContainers()) {
ContainerTestUtils.waitForAssignment(messageListenerContainer, embeddedKafka.getPartitionsPerTopic())
}
}
def "test"() {
given:
template.sendDefault("Hello")
}
}
In application-test.yml I have
kafka:
bootstrapservers: ${spring.embedded.kafka.brokers}
In the application I start a Kafka consumer with spring-kafka.
Stack trace is
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:44)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
at org.spockframework.spring.SpringTestContextManager.prepareTestInstance(SpringTestContextManager.java:50)
at org.spockframework.spring.SpringInterceptor.interceptSetupMethod(SpringInterceptor.java:42)
at org.spockframework.runtime.extension.AbstractMethodInterceptor.intercept(AbstractMethodInterceptor.java:28)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:88)
at org.spockframework.runtime.extension.builtin.AbstractRuleInterceptor$1.evaluate(AbstractRuleInterceptor.java:37)
at org.togglz.junit.TogglzRule$1.evaluate(TogglzRule.java:127)
at org.spockframework.runtime.extension.builtin.TestRuleInterceptor.intercept(TestRuleInterceptor.java:38)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'kafkaListenerContainerFactoryConfiguration': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.embedded.kafka.brokers' in value "${spring.embedded.kafka.brokers}"
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
... 19 more
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.embedded.kafka.brokers' in value "${spring.embedded.kafka.brokers}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:236)
at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210)
at org.springframework.core.env.AbstractPropertyResolver.resolveNestedPlaceholders(AbstractPropertyResolver.java:227)
at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:84)
at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:61)
at org.springframework.core.env.AbstractEnvironment.getProperty(AbstractEnvironment.java:527)
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer$1.getProperty(PropertySourcesPlaceholderConfigurer.java:132)
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer$1.getProperty(PropertySourcesPlaceholderConfigurer.java:129)
at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:81)
at org.springframework.core.env.PropertySourcesPropertyResolver.getPropertyAsRawString(PropertySourcesPropertyResolver.java:71)
at org.springframework.core.env.AbstractPropertyResolver$1.resolvePlaceholder(AbstractPropertyResolver.java:239)
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:147)
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:236)
at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210)
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer$2.resolveStringValue(PropertySourcesPlaceholderConfigurer.java:172)
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:831)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1086)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
... 36 more
Does anyone have a clue?
Ensure that in each of your integration test you setup both #SpringBootTest and #EmbeddedKafka.
This is common mistake when you run multiple integration tests at once with #SpringBootTest annotation. Since you have registered DefaultKafkaConsumerFactory and DefaultKafkaProducerFactory in your application configurator bean and probably you also use #Value("${spring.kafka.bootstrap-servers}") somewhere there, you are obligated to setup #EmbeddedKafka(partitions = 1, topics = {"topic"}) everywhere you call spring-boot application to run on test server container. #EmbeddedKafka is responsible to call EmbeddedKafkaContextCustomizer to register all environment variables (among others spring.embedded.kafka.brokers) needed by kafka engine.
Without #EmbeddedKafka in your Integration Test spring runs your application on server but there is no mechanism to set up environments used by kafka engine.
I invoked embeddedKafka.before() in setup(). Then the spring.embedded.kafka.brokers got set and available.
I am not sure, but the problem seems like Spock Spring specific.
I am not familiar with Spock but a simple Java JUnit test works fine...
#SpringBootApplication
public class So47172973Application {
public static void main(String[] args) {
SpringApplication.run(So47172973Application.class, args);
}
#KafkaListener(topics = "foo")
public void in(String in) {
System.out.println(in);
}
}
and
spring:
kafka:
bootstrap-servers:
- ${spring.embedded.kafka.brokers}
consumer:
group-id: embedded1
auto-offset-reset: earliest
and
#RunWith(SpringRunner.class)
#SpringBootTest
public class So47172973ApplicationTests {
#ClassRule
public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, "foo");
#Autowired
private KafkaTemplate<String, String> template;
#Test
public void test() throws InterruptedException {
template.send("foo", "bar");
Thread.sleep(10_000);
}
}
A couple of things to try:
Use the annotation instead...
#RunWith(SpringRunner.class)
#SpringBootTest
#EmbeddedKafka(controlledShutdown = true, topics = "foo")
public class So47172973ApplicationTests {
#Autowired
private KafkaTemplate<String, String> template;
#Test
public void test() throws InterruptedException {
template.send("foo", "bar");
Thread.sleep(10_000);
}
}
declare the broker as a #Bean...
#RunWith(SpringRunner.class)
#SpringBootTest(classes = {So47172973ApplicationTests.Config.class, So47172973Application.class})
public class So47172973ApplicationTests {
#Autowired
private KafkaTemplate<String, String> template;
#Test
public void test() throws InterruptedException {
template.send("foo", "bar");
Thread.sleep(10_000);
}
#Configuration
public static class Config {
#Bean
public KafkaEmbedded embeddedKafka() {
return new KafkaEmbedded(1, true, "foo");
}
}
}
Got the similar issue and #taro's answer didn't resolve my issue.
I fixed this issue by removing static from EmbeddedKafka object and replacing #ClassRule with #Rule annotation.
#Rule
public KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, "topic")

Clarification about #EnableMongoRepositories

I'm trying to use #EnableMongoRepositories for using two separate mongo repositories like:
#Configuration
#EnableMongoRepositories(mongoTemplateRef = "mongoBOTemplate", basePackages = "sandbox.dao.bo")
public class BOMongoConfig {
#Value("#{mongo.hostBO}")
private String hostBO;
#Value("#{mongo.databaseBO}")
private String databaseBO;
#Bean
public MongoDbFactory mongoBODbFactory() throws Exception {
return new SimpleMongoDbFactory(new MongoClient(hostBO), databaseBO);
}
#Bean
public MongoTemplate mongoBOTemplate() throws Exception {
return new MongoTemplate(mongoBODbFactory());
}
}
and
#Configuration
#EnableMongoRepositories(mongoTemplateRef = "mongoTemplate", basePackages = "sandbox.dao.sandbox")
public class SandboxMongoConfig {
#Value("#{mongo.host}")
private String host;
#Value("#{mongo.database}")
private String database;
#Bean
public MongoDbFactory mongoDbFactory() throws Exception {
return new SimpleMongoDbFactory(new MongoClient(host), database);
}
#Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongoDbFactory());
}
}
but I'm confused because of this error:
710 [RMI TCP Connection(2)-127.0.0.1] ERROR org.springframework.web.servlet.DispatcherServlet - Context initialization failed
java.lang.IllegalArgumentException: Environment must not be null!
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.data.repository.config.RepositoryConfigurationSourceSupport.<init>(RepositoryConfigurationSourceSupport.java:50)
at org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource.<init>(AnnotationRepositoryConfigurationSource.java:74)
at org.springframework.data.repository.config.RepositoryBeanDefinitionRegistrarSupport.registerBeanDefinitions(RepositoryBeanDefinitionRegistrarSupport.java:74)
at org.springframework.context.annotation.ConfigurationClassParser.processImport(ConfigurationClassParser.java:340)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:233)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:154)
at org.springframework.context.annotation.ConfigurationClassParser.processImport(ConfigurationClassParser.java:349)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:233)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:154)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:140)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:282)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:223)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:630)
As I understood there is only one option to fix it is using #Profile. I'm using maven to profile management and not sure why I need hardcore profiles in code...
Could anyone help me with misunderstanding?
Thanks.
Well, you have to somehow show spring which of those configurations to use for particular case. Otherwise how would it be possible decide which MongoDbFactory instance to create? So yes, use #Profile above both #Configuration classes.
Also please note that maven profiles are not spring profiles. Might be that you dont have to mix maven into that ( if maven profile is only use to set spring one ). I such case you can add -Dspring.profiles.active=profile while running your app.

Spring #EnableCaching with #Inject/#Autowired issue

I found an issue when using #EnableCaching annotation together with #Inject/#Autowired in #Configuration class:
Simple example to reproduce:
Configuration class:
#Configuration
#EnableCaching
public class CacheConfig {
#Inject
private DataSource dataSource;
#Bean
public CacheManager cacheManager(){
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("books")));
return cacheManager;
}
#Configuration
static class DevProfileConfig {
#Bean(destroyMethod = "shutdown")
public DataSource dataSource() {
EmbeddedDatabaseFactory factory = new EmbeddedDatabaseFactory();
factory.setDatabaseType(EmbeddedDatabaseType.HSQL);
return factory.getDatabase();
}
}
}
Application context launcher:
public class CacheConfigLauncher {
public static void main(String args[]){
ApplicationContext springAppContext = new AnnotationConfigApplicationContext(CacheConfig.class);
}
}
Error:
Caused by:
org.springframework.beans.factory.BeanDefinitionStoreException:
Factory method [public org.springframework.cache.CacheManager
spring.samples.config.CacheConfig.cacheManager()] threw exception;
nested exception is java.lang.IllegalArgumentException: Object of
class [null] must be an instance of interface
org.springframework.beans.factory.config.ConfigurableBeanFactory at
org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:188)
at
org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:573)
... 76 more
Caused by: java.lang.IllegalArgumentException: Object of class [null]
must be an instance of interface
org.springframework.beans.factory.config.ConfigurableBeanFactory at
org.springframework.util.Assert.isInstanceOf(Assert.java:339) at
org.springframework.util.Assert.isInstanceOf(Assert.java:319) at
org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.getBeanFactory(ConfigurationClassEnhancer.java:414)
at
org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:289)
at
spring.samples.config.CacheConfig$$EnhancerByCGLIB$$f6ceccea.cacheManager()
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:491) at
org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
... 77 more
However if you comment out either #Inject'ed field or #EnableCaching annotation configuration will be bootstraped without errors!!!
It seams like a bug for me. Have someone faced the same issue or probably I'm missing smth?
Thank you,
Oleg
Issue has been fixed in Spring v4.0.0.M2!

Resources