java.lang.ClassNotFoundException: org.apache.kafka.clients.consumer.ConsumerGroupMetadata - java

I am trying to create a simple Kafka producer. I followed a tutorial since I am new to this topic. I created a config file as recommended in the video. Here is the config file I am using.
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.core.ProducerFactory;
import org.springframework.kafka.support.serializer.JsonSerializer;
import java.util.HashMap;
import java.util.Map;
#Configuration
public class KafkaProducerConfig {
#Bean
public ProducerFactory<String, KafkaProducerModel> producerFactory() {
Map<String, Object> config = new HashMap<>();
config.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "127.0.0.1:9092");
config.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
config.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
return new DefaultKafkaProducerFactory<>(config);
}
#Bean
public KafkaTemplate<String, KafkaProducerModel> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
}
I am getting the following error when I try to run my application.
Caused by: java.lang.ClassNotFoundException: org.apache.kafka.clients.consumer.ConsumerGroupMetadata
at jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) ~[?:?]
at jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[?:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[?:?]
at java.lang.Class.getDeclaredMethods0(Native Method) ~[?:?]
at java.lang.Class.privateGetDeclaredMethods(Class.java:3166) ~[?:?]
at java.lang.Class.getDeclaredMethods(Class.java:2309) ~[?:?]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:463) ~[spring-core-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.util.ReflectionUtils.doWithLocalMethods(ReflectionUtils.java:321) ~[spring-core-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.buildPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:438) ~[spring-orm-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:409) ~[spring-orm-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(PersistenceAnnotationBeanPostProcessor.java:336) ~[spring-orm-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:1094) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569) ~[spring-beans-5.2.5.RELEASE.jar:5.2.5.RELEASE]
... 15 more
Its a gradle project and here is the dependency
implementation 'org.springframework.kafka:spring-kafka:2.5.6.RELEASE'
I did add the dependency after reviewing a stackover flow thread. However it did not resolve the error. Any lead would be helpful.
implementation 'org.apache.tomcat.embed:tomcat-embed-core'

You appear to have the wrong version of kafka-clients on the classpath. spring-kafka 2.5.6 uses kafka-clients 2.5.1. You should not declare the version yourself, Spring Boot will pull in the correct version.
Spring Boot 2.3.4 will pull in this version of spring-kafka and its dependencies. If you are using an older boot, you need to override all the dependencies.

Related

Using #DataJpaTest in Spring Boot 3.0.0 Integration test causes Test discovery error

Whenever I add #DataJpaTest to a test test execution fails with the following error:
import com.owino.paginateddata.entities.Tweet;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.junit.jupiter.SpringExtension;
#DataJpaTest
#ExtendWith(SpringExtension.class)
public class PersistTweetTest {
#Autowired
private TestEntityManager entityManager;
#Test
public void shouldPersistTweetTest(){
var entity = entityManager.persistAndFlush(new Tweet(1L,"#goodvibes #sweetypie", "2022-12-11","11:00PM"));
Assertions.assertThat(entity).isNotNull();
Assertions.assertThat(entity.getId()).isEqualTo(1L);
Assertions.assertThat(entity.getContents()).isEqualTo("#goodvibes #sweetypie");
Assertions.assertThat(entity.getDateString()).isEqualTo("2022-12-11");
Assertions.assertThat(entity.getTimeString()).isEqualTo("11:00PM");
}
}
Internal Error occurred.
org.junit.platform.commons.JUnitException: TestEngine with ID 'junit-jupiter' failed to discover tests
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:160)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:132)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:78)
at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:110)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: org.junit.platform.commons.JUnitException: ClassSelector [className = 'com.owino.paginateddata.persistence_test.PersistTweetTest'] resolution failed
at org.junit.platform.launcher.listeners.discovery.AbortOnFailureLauncherDiscoveryListener.selectorProcessed(AbortOnFailureLauncherDiscoveryListener.java:39)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:103)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:83)
at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:113)
at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:46)
at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:69)
at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:152)
... 13 more
Tests that are not annoted with #DataJpaTest and #ExtendWith(SpringExtension.class) execute smoothly. I have observed this only in Spring Boot 3.0.0, I am running these tests smoothly on 2.7.x.
While Running $ mvn test I noticed maven skips the test.
Running on Intelij 2022.3 leads to the above error being produced.

spring-boot upgrade to 2.3.1.RELEASE from 2.2.1.RELEASE (got failing tests.)

while upgrading from spring 2.1.2.RELEASE to 2.3.1.RELEASE was facing issues,
the gist of the complete configuration is.
added
<spring-boot.version>
2.3.1.RELEASE
</spring-boot.version>
and
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-validation
</artifactId>
</dependency>
keeping the rest of the versions and configs same.
cucumber version -3.0.2
Junit version - 4.12
so after change if we try to run the tests they fail.
we are calling repository's deleteAll() method when we see these exceptions in the logs, and if we comment the saveAndFlush() method we dont see exceptions.
though this issue is not due to cucumber it seems after some narrowing down that
Appreciate the help also if more info is needed on my specific case I can add details on suggestions.
the code sample is:
FooRepository.java:
package com.foo.respositories;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import com.foo.entities.FooEntity;
#Transactional
#Repository
public interface FooRepository extends JpaRepository<FooEntity, LocalDate> {
#Modifying
default void create(FooEntity entity) {
this.saveAndFlush(entity);
}
}
FooEntity.java:
package com.foo.entities;
import javax.persistence.Entity;
import javax.persistence.Id;
import lombok.Data;
import org.hibernate.envers.Audited;
#Entity
#Audited
#Data
public class FooEntity {
#Id
private LocalDate date;
private BigDecimal rate;
}
the trace of the log is as below.
org.springframework.dao.InvalidDataAccessApiUsageException: id to load is required for loading; nested exception is java.lang.IllegalArgumentException: id to load is required for loading
at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:374)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:257)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible (AbstractEntityManagerFactoryBean.java :528)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:178)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy282.deleteAll(Unknown Source)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 ( NativeMethodAccessImpl.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.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:205)
at com.sun.proxy.$Proxy158.deleteAll(Unknown Source)
at *.we clear out database
Caused by: java.lang.IllegalArgumentException: id to load is required for loading
at org.hibernate.event.spi.LoadEvent.<init> (LoadEvent.java:96)
at org.hibernate.event.spi.LoadEvent.<init> (LoadEvent.java:64)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.doLoad(SessionImpl.java:2781)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.lambda$load$1 (SessionImpl.java:2765)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.perform(SessionImpl.java:2721)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2765)

SpringRestDocs and mocking MongoDB

I'm trying to generate API documentation using SpringRestDocs and SpringBootTest and MockMVC.
Our service uses MongoDB as storage and we have various services that talk to MongoDB using repositories.
In my test I'm mocking the services to not rely on MongoDB or data.
Though my tests run fine only if I've a local mongo running on my machine, otherwise tests fail because org.mongodb.driver.cluster is not able to connect.
Here is the error I get:
018-03-06 11:42:05.620 INFO 56095 --- [localhost:27017] org.mongodb.driver.cluster : Exception in monitor thread while connecting to server localhost:27017
com.mongodb.MongoSocketOpenException: Exception opening socket
at com.mongodb.connection.SocketStream.open(SocketStream.java:63) ~[mongodb-driver-core-3.4.3.jar:na]
at com.mongodb.connection.InternalStreamConnection.open(InternalStreamConnection.java:115) ~[mongodb-driver-core-3.4.3.jar:na]
at com.mongodb.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:113) ~[mongodb-driver-core-3.4.3.jar:na]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_144]
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_144]
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_144]
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_144]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_144]
at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_144]
at com.mongodb.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:57) ~[mongodb-driver-core-3.4.3.jar:na]
at com.mongodb.connection.SocketStream.open(SocketStream.java:58) ~[mongodb-driver-core-3.4.3.jar:na]
... 3 common frames omitted
2018-03-06 11:42:05.724 INFO 56095 --- [ main] org.mongodb.driver.cluster : No server chosen by WritableServerSelector from cluster description ClusterDescription{type=UNKNOWN, connectionMode=SINGLE, serverDescriptions=[ServerDescription{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused (Connection refused)}}]}. Waiting for 30000 ms before timing out
I would like to totally bypass MongoDB because I don't need it to build my documentation.
I've tried to use #MockBean on all the repositories that use Mongo and disable autoconfiguration, but still not working properly
Any suggestion on what shoudl I do to mock the MongoDB client/template?
Here is my ApiDocumentation.java class, without
package uk.ac.ebi.biosamples.docs;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.data.domain.*;
import org.springframework.hateoas.MediaTypes;
import org.springframework.http.MediaType;
import org.springframework.restdocs.JUnitRestDocumentation;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import uk.ac.ebi.biosamples.model.Curation;
import uk.ac.ebi.biosamples.model.CurationLink;
import uk.ac.ebi.biosamples.model.Sample;
import uk.ac.ebi.biosamples.model.filter.Filter;
import uk.ac.ebi.biosamples.service.*;
import java.util.Collections;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.mockito.Matchers.*;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.*;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.requestParameters;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#RunWith(SpringRunner.class)
#SpringBootTest
public class ApiDocumentation {
#Rule
public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("target/generated-snippets");
#Autowired
private WebApplicationContext context;
private ObjectMapper mapper;
#MockBean
private SamplePageService samplePageService;
#MockBean
private SampleService sampleService;
#MockBean
CurationPersistService curationPersistService;
#MockBean
CurationReadService curationReadService;
#MockBean
private BioSamplesAapService aapService;
private DocumentationHelper faker;
private MockMvc mockMvc;
#Before
public void setUp() {
this.faker = new DocumentationHelper();
this.mapper = new ObjectMapper();
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
.apply(documentationConfiguration(this.restDocumentation).uris()
.withScheme("https")
.withHost("www.myhost.com")
.withPort(443)
)
.build();
}
/**
* Generate the snippets for the API root
* #throws Exception
*/
#Test
public void getIndex() throws Exception {
this.mockMvc.perform(get("/").accept(MediaTypes.HAL_JSON))
.andExpect(status().isOk())
.andDo(document("get-index", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())));
}
/* Bunch of other similar tests */
}
I was able to solve my issue using an embedded mongodb instance.
For my specific needs this was sufficient to solve my issues with autoconfiguration.
In my pom I've added a dependence to de.flapdoodle.embed.mongo
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<scope>test</scope>
</dependency>
and add a plugin to start/stop the embedded mongodb before/after mvn build
<plugin>
<groupId>com.github.joelittlejohn.embedmongo</groupId>
<artifactId>embedmongo-maven-plugin</artifactId>
<version>0.3.5</version>
<executions>
<execution>
<id>start</id>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop</id>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>

Failing JUnit tests for embedded Fongo DB

I have a Spring Boot application which use MongoDB. I would like to use the embedded FongoDB for my JUnit tests. I follow some articles, for example:
http://dontpanic.42.nl/2015/02/in-memory-mongodb-for-unit-and.html
My Fongo test configuration looks like
package com.myproject.rest;
import com.github.fakemongo.Fongo;
import com.mongodb.Mongo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
#Profile("test")
#ComponentScan(basePackages = "com.myproject.service.data")
#EnableMongoRepositories(basePackages = "com.myproject.service.data.repository")
#Configuration
public class MongoTestConfig extends AbstractMongoConfiguration {
#Override
protected String getDatabaseName() {
return "demo-test";
}
#Bean
#Override
public Mongo mongo() {
return new Fongo("mongo-test").getMongo();
}
}
I have this dependency for that:
<dependency>
<groupId>com.github.fakemongo</groupId>
<artifactId>fongo</artifactId>
<version>2.1.0</version>
<scope>test</scope>
</dependency>
I would like to test my services which autowired a repository interface which extends MongoRepository
package com.myproject.service.data.repository;
import com.myproject.service.data.entity.JournalData;
import org.springframework.data.mongodb.repository.MongoRepository;
import java.util.List;
public interface JournalRepository extends MongoRepository<JournalData, String> {
#Override
public List<JournalData> findAll(Iterable<String> ids);
}
My tests class are inherited from the class below:
package com.myproject.rest;
import com.lordofthejars.nosqlunit.mongodb.MongoDbRule;
import cz.csas.services.commons.api.RequestMetadata;
import org.junit.Before;
import org.junit.Rule;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static com.lordofthejars.nosqlunit.mongodb.MongoDbRule.MongoDbRuleBuilder.newMongoDbRule;
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
#SpringBootTest
#AutoConfigureMockMvc
#PowerMockIgnore({"javax.xml.*", "org.xml.*", "org.w3c.*", "javax.management.*", "javax.net.ssl.*"})
#PrepareForTest({RequestMetadata.class})
#ActiveProfiles("test")
public class EndpointTestContext {
#Autowired
protected MockMvc mockMvc;
//#Rule
//public MongoDbRule mongoDbRule = newMongoDbRule().defaultSpringMongoDb("demo-test");
#Before
public void setup() {
mockStatic(RequestMetadata.class);
when(RequestMetadata.builder()).thenCallRealMethod();
RequestMetadata m = RequestMetadata.builder()
.workingMode("TEST")
.build();
when(RequestMetadata.getMetadata()).thenReturn(m);
}
}
But when I run the Maven tests I recieve the following:
Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.mongodb.MongoClientOptions
at com.mongodb.MockMongoClient.create(MockMongoClient.java:42)
at com.github.fakemongo.Fongo.createMongo(Fongo.java:175)
at com.github.fakemongo.Fongo.<init>(Fongo.java:88)
at com.github.fakemongo.Fongo.<init>(Fongo.java:75)
at com.github.fakemongo.Fongo.<init>(Fongo.java:67)
at com.myproject.rest.MongoTestConfig.mongo(MongoTestConfig.java:30)
at com.myproject.rest.MongoTestConfig$$EnhancerBySpringCGLIB$$bf18b1d4.CGLIB$mongo$1(<generated>)
at com.myproject.rest.MongoTestConfig$$EnhancerBySpringCGLIB$$bf18b1d4$$FastClassBySpringCGLIB$$3ab8bfd7.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358)
at com.myproject.rest.MongoTestConfig$$EnhancerBySpringCGLIB$$bf18b1d4.mongo(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
... 115 common frames omitted
Can anyone suggest how to fix it? Thank you in advance.
Fongo can't find class from mongo-java-driver artifact. It declares
<!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.4.2</version>
</dependency>
as provided dependency. You should have mongo-java-driver on your test classpath. Most probably
<scope>runtime</scope>
or test will be enough for you.
Check if you have multiple version of mongo java driver (version conflicts). To check this, you can use mvn dependency tree to trace the path from where each jar is coming to your project.
mvn dependency:tree
Just need to find out the right version on mongo java driver and make sure you are not having version conflicts. I have used spring data and used fongo to write in-memory test case for mongodb queries.
<fongo-version>1.6.3</fongo-version>
<spring-data-mongodb-version>1.7.2.RELEASE</spring-data-mongodb-version>
<spring-framework-version>4.1.5.RELEASE</spring-framework-version>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>${spring-data-mongodb-version}</version>
</dependency>
<dependency>
<groupId>com.github.fakemongo</groupId>
<artifactId>fongo</artifactId>
<version>${fongo-version}</version>
<scope>test</scope>
</dependency>
Version conflict can come from may source (can confirm using above mvc dependency:tree command, one such source is mongobee, so if you are using it, please exclude mongo-java-drive by using exclusion
<dependency>
<groupId>com.github.mongobee</groupId>
<artifactId>mongobee</artifactId>
<version>${mongobee-version}</version>
<exclusions>
<exclusion>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
</exclusion>
</exclusions>
</dependency>

get java.lang.ArrayStoreException on Springboot and ehcache

I have a method that calls a webservice and for same input arguments, I want the result to be cached. So, here is what i did so far:
The main class:
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.web.SpringBootServletInitializer;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.io.ClassPathResource;
#EnableCaching
#ComponentScan
#SpringBootApplication
public class AccServer extends SpringBootServletInitializer {
#Bean
public CacheManager cacheManager() {
return new EhCacheCacheManager(ehCacheCacheManager().getObject());
}
#Bean
public EhCacheManagerFactoryBean ehCacheCacheManager() {
EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean();
cmfb.setConfigLocation(new ClassPathResource("ehcache.xml"));
cmfb.setShared(true);
return cmfb;
}
}
Method to cache:
import java.util.List;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
#Service
public class SomeClass implements ISomeClass {
#Override
#Cacheable("acc")
public List<Integer> trs() {
return webSrv.trs();
}
}
ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false">
<diskStore path="java.io.tmpdir" />
<cache name="acc" maxElementsInMemory="100" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />
</ehcache>
And I get:
Caused by: java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
at sun.reflect.annotation.AnnotationParser.parseClassArray(Unknown Source)
at sun.reflect.annotation.AnnotationParser.parseArray(Unknown Source)
at sun.reflect.annotation.AnnotationParser.parseMemberValue(Unknown Source)
at sun.reflect.annotation.AnnotationParser.parseAnnotation2(Unknown Source)
at sun.reflect.annotation.AnnotationParser.parseAnnotations2(Unknown Source)
at sun.reflect.annotation.AnnotationParser.parseAnnotations(Unknown Source)
at java.lang.Class.createAnnotationData(Unknown Source)
at java.lang.Class.annotationData(Unknown Source)
at java.lang.Class.createAnnotationData(Unknown Source)
at java.lang.Class.annotationData(Unknown Source)
at java.lang.Class.getAnnotation(Unknown Source)
at org.springframework.cache.annotation.SpringCacheAnnotationParser.getAnnotations(SpringCacheAnnotationParser.java:201)
at org.springframework.cache.annotation.SpringCacheAnnotationParser.parseCacheAnnotations(SpringCacheAnnotationParser.java:64)
at org.springframework.cache.annotation.SpringCacheAnnotationParser.parseCacheAnnotations(SpringCacheAnnotationParser.java:52)
at org.springframework.cache.annotation.AnnotationCacheOperationSource$1.getCacheOperations(AnnotationCacheOperationSource.java:113)
at org.springframework.cache.annotation.AnnotationCacheOperationSource.determineCacheOperations(AnnotationCacheOperationSource.java:142)
at org.springframework.cache.annotation.AnnotationCacheOperationSource.findCacheOperations(AnnotationCacheOperationSource.java:110)
at org.springframework.cache.interceptor.AbstractFallbackCacheOperationSource.computeCacheOperations(AbstractFallbackCacheOperationSource.java:142)
at org.springframework.cache.interceptor.AbstractFallbackCacheOperationSource.getCacheOperations(AbstractFallbackCacheOperationSource.java:97)
at org.springframework.cache.interceptor.CacheOperationSourcePointcut.matches(CacheOperationSourcePointcut.java:39)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:211)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:248)
at org.springframework.aop.support.AopUtils.findAdvisorsThatCanApply(AopUtils.java:280)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply(AbstractAdvisorAutoProxyCreator.java:118)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findEligibleAdvisors(AbstractAdvisorAutoProxyCreator.java:88)
at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean(AbstractAdvisorAutoProxyCreator.java:69)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:346)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:298)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
... 135 more
I also use #Cacheable("acc") annotation for the method which should be cached for the result.
Any answers would be appreciated.
The issue is with the #Cacheable trs() method (of your #Service SomeClass class) which is NOT returning List<Integer> object because of which you are getting sun.reflect.annotation.TypeNotPresentExceptionProxy exception.
You need to ensure that trs() is returning the List<Integer> object.
Thanks to fellows how contributed on this question, finally after long time of debugging, I just found that there is need for excluding two dependencies from project, so that it becomes:
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</exclusion>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</exclusion>
That exception means something attempted to do a lookup on an annotation that's not present on the classpath. Unfortunately, the JDK isn't telling us much about it but I think we've improved the error message in recent version of the framework (and therefore boot).
You could also add a breakpoint in the faulty code and it will tell you what it's trying to resolve. That should give you a hint of what the missing annotation is. Most of the time, this isn't strictly related to the component that does the lookup (i.e. it might very well be unrelated to caching). If you share a sample app, we could easily figure it out.

Categories