I am new to Kafka and spring cloud stream. Now, I have a problem with start a Kafka project for sending message. It is show Null Pointer exception when first running my application.
log
java.lang.NullPointerException: null
at java.base/java.util.HashMap.putMapEntries(HashMap.java:497) ~[na:na]
at java.base/java.util.LinkedHashMap.<init>(LinkedHashMap.java:385) ~[na:na]
at org.springframework.core.annotation.MapAnnotationAttributeExtractor.enrichAndValidateAttributes(MapAnnotationAttributeExtractor.java:93) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.core.annotation.MapAnnotationAttributeExtractor.<init>(MapAnnotationAttributeExtractor.java:58) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.core.annotation.AnnotationUtils.synthesizeAnnotation(AnnotationUtils.java:1609) ~[spring-core-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.cloud.stream.config.BindingBeansRegistrar.collectClasses(BindingBeansRegistrar.java:56) ~[spring-cloud-stream-3.0.8.RELEASE.jar:3.0.8.RELEASE]
at org.springframework.cloud.stream.config.BindingBeansRegistrar.registerBeanDefinitions(BindingBeansRegistrar.java:43) ~[spring-cloud-stream-3.0.8.RELEASE.jar:3.0.8.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.lambda$loadBeanDefinitionsFromRegistrars$1(ConfigurationClassBeanDefinitionReader.java:364) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:723) ~[na:na]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromRegistrars(ConfigurationClassBeanDefinitionReader.java:363) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:145) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:117) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:327) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:232) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:705) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531) ~[spring-context-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204) ~[spring-boot-2.1.8.RELEASE.jar:2.1.8.RELEASE]
at stream.websokect.demo.DemoApplication.main(DemoApplication.java:15) ~[classes/:na]
application.properties
spring.cloud.stream.bindings.output.destination= meetUpTopic
spring.cloud.stream.bindings.output.producer.partition-count= 1
spring.cloud.stream.bindings.output.content-type= text/plain
spring.cloud.stream.bindings.output.producer.header-mode= raw
DemoApplication
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.socket.client.WebSocketClient;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
#SpringBootApplication
public class DemoApplication {
public static String MEET_UP_STREAM = "ws://stream.meetup.com/2/rsvps";
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Bean
public ApplicationRunner initializeConnection(RsvpWebSocketHandler rsvpWebSocketHandler) {
System.out.println("Hello=============");
return args -> {
WebSocketClient webSocketClient = new StandardWebSocketClient();
webSocketClient.doHandshake(rsvpWebSocketHandler, MEET_UP_STREAM);
};
}
}
RsvpKafkaProducer
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketMessage;
#Component
#EnableBinding(Source.class)
public class RsvpKafkaProducer {
private final Source source;
public RsvpKafkaProducer(Source source) {
this.source = source;
}
public void sendRsvpMessage(WebSocketMessage<?> message) {
source.output()
.send(MessageBuilder.withPayload(message.getPayload()).build(), 10000);
}
}
RsvpWebSocketHandler
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
#Component
public class RsvpWebSocketHandler extends AbstractWebSocketHandler {
private final RsvpKafkaProducer rsvpKafkaProducer;
public RsvpWebSocketHandler(RsvpKafkaProducer rsvpKafkaProducer) {
this.rsvpKafkaProducer = rsvpKafkaProducer;
}
#Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
System.out.println(message.getPayload() + "================/n");
rsvpKafkaProducer.sendRsvpMessage(message);
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>stream.websokect</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-stream -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<version>3.0.8.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-stream-binder-kafka -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-kafka</artifactId>
<version>3.0.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
BindingBeansRegistrar.collectClasses It's some problem with an #EnableBinding annotation; what version are you using?
I tried to reproduce it with another #EnableBinding with no classes, but it still loaded ok.
You could set a breakpoint in BindingBeansRegistrar.collectClasses to see what attributes it is trying to synthesize an annotation from.
I copied your producer to a new Spring Boot app and it worked without any problems; if you can post a stripped-down application someplace (without the websocket stuff) I can take a look to see what's wrong.
Related
I have created a Kinesis Analytics Streaming Application in SpringBoot which will consume messages from the AmazonKinesis input stream and will do some operations on top of it using the Apache Flink DataStream library.
When, I am uploading the application jar to S3 and trying to run this application on Streaming App it is throwing ClassNotFoundException for one of the files which is the ApplicationConfiguration file. Also, when I am running this application locally, it is running fine without any errors and I am able to consume the messages.
Below are some of the code files.
ApplicationConfiguration.java
import java.util.Properties;
import org.apache.flink.api.common.serialization.SimpleStringSchema;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.connectors.kinesis.FlinkKinesisConsumer;
import org.apache.flink.streaming.connectors.kinesis.FlinkKinesisProducer;
import org.apache.flink.streaming.connectors.kinesis.config.ConsumerConfigConstants;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class ApplicationConfiguration {
#Value("${oe.metric.input.stream}")
private String inputStreamName;
#Value("${oe.metric.output.stream}")
private String outputStreamName;
#Value("${aws.region}")
private String region;
#Value("${stream.initial.position}")
private String position;
#Bean
public FlinkKinesisProducer<String> createSinkFromStaticConfig() {
Properties outputProperties = new Properties();
outputProperties.setProperty(ConsumerConfigConstants.AWS_REGION, region);
outputProperties.setProperty("AggregationEnabled", "false");
FlinkKinesisProducer<String> sink = new FlinkKinesisProducer<>(new SimpleStringSchema(),
outputProperties);
sink.setDefaultStream(outputStreamName);
sink.setDefaultPartition("0");
return sink;
}
#Bean
public DataStream<String> createSourceFromConfig() {
Properties inputProperties = new Properties();
inputProperties.setProperty(ConsumerConfigConstants.AWS_REGION, region);
inputProperties.setProperty(ConsumerConfigConstants.STREAM_INITIAL_POSITION, position);
return ApplicationConstants.streamExecutionEnvironment.addSource(
new FlinkKinesisConsumer<>(inputStreamName, new SimpleStringSchema(), inputProperties));
}
Error:
Caused by: java.lang.IllegalStateException: Cannot load configuration class: com.pkg.config.ApplicationConfiguration
at org.springframework.context.annotation.ConfigurationClassPostProcessor.enhanceConfigurationClasses(ConfigurationClassPostProcessor.java:415)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanFactory(ConfigurationClassPostProcessor.java:268)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:325)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:147)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
at com.pkg.KinesisConsumerApplication.main(KinesisConsumerApplication.java:18)
... 25 more
Caused by: java.lang.ClassNotFoundException: com.pkg.config.ApplicationConfiguration
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:476)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151)
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:398)
KinesisConsumerApplication.java
#SpringBootApplication
#EnableAutoConfiguration
#ComponentScan(basePackages = "com.pkg")
public class KinesisConsumerApplication implements CommandLineRunner {
#Autowired
ApplicationContext ctx;
public static void main(String[] args) {
SpringApplication.run(KinesisConsumerApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
GetKinesisRecords getKinesisRecords = ctx.getBean(GetKinesisRecords.class);
getKinesisRecords.getDataFromStream();
}
}
Maven pom.xml file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<artifactId>kinesis-consumer</artifactId>
<build>
<plugins>
<plugin>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<artifactId>lombok</artifactId>
<groupId>org.projectlombok</groupId>
</exclude>
</excludes>
</configuration>
<groupId>org.springframework.boot</groupId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<artifactId>spring-boot-starter</artifactId>
<groupId>org.springframework.boot</groupId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<artifactId>flink-connector-kinesis_${scala.binary.version}</artifactId>
<groupId>org.apache.flink</groupId>
<version>1.13.2</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-java_${scala.binary.version}</artifactId>
<version>1.13.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<artifactId>flink-core</artifactId>
<groupId>org.apache.flink</groupId>
<version>1.13.2</version>
</dependency>
<dependency>
<artifactId>jackson-datatype-jsr310</artifactId>
<groupId>com.fasterxml.jackson.datatype</groupId>
</dependency>
<dependency>
<artifactId>spring-boot-starter-test</artifactId>
<groupId>org.springframework.boot</groupId>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>junit</artifactId>
<groupId>junit</groupId>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>ssai-common</artifactId>
<groupId>com.adsparx.phoenix</groupId>
<version>1.2.0</version>
</dependency>
<dependency>
<artifactId>flink-clients</artifactId>
<groupId>org.apache.flink</groupId>
<version>1.15.0</version>
</dependency>
<dependency>
<artifactId>jakarta.xml.bind-api</artifactId>
<groupId>jakarta.xml.bind</groupId>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</dependency>
</dependencies>
<description>Apache Kinesis Consumer</description>
<groupId>com.pkg</groupId>
<modelVersion>4.0.0</modelVersion>
<name>kinesis-consumer</name>
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<relativePath/>
<version>2.4.0</version>
</parent>
<properties>
<java.version>11</java.version>
<scala.binary.version>2.12</scala.binary.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<version>0.0.1-SNAPSHOT</version>
</project>
Things that I have tried on my end:
Clean build the project a couple of times.
Checked Java and Spring version in pom, as suggested in one of the
StackOverflow post.
Downgraded SpringBoot version from "2.7.0" to "2.4.0".
Added ComponentScan annotation in main class.
Tried changing the annotation from #Configuration to #Component.
Last but not least, tried google and stackoverflow.
Can someone please help me identify the error?
Is this because you're attempting to use dependencies for flink 1.15? AFAIK, 1.13 is the latest version supported. You need to choose which flink version you intend to use when creating the streaming application.
I am currently learning spring boot but i have a small issue concerning the running of my server
below is the code
My springJPA Application class
#Configuration
public class SpringJpaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringJpaApplication.class, args);
}
}
This is my controller*
#Controller
public class IssuesController {
#Autowired
IssueRepository repo;
#RequestMapping("/home")
public String home() {
return "home.jsp";
}
#RequestMapping("/addIssue")
public ModelAndView addIssue(Issues issue) {
ModelAndView mv = new ModelAndView();
mv.addObject("obj", issue);
mv.setViewName("home");
repo.save(issue);
return mv;
}
}
this are the application properties i made in order to be able to use SQLite in my demo application
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url = jdbc:sqlite:sqlitesample.db
spring.datasource.driver-class-name = org.sqlite.JDBC
spring.datasource.username = admin
spring.datasource.password = admin
spring.sql.init.mode = always
Lastly, these are some of the dependencies i added
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demoApplication</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springJPA</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>9.0.48</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
However, I keep on getting this error when I try to run the application
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:163) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577) ~[spring-context-5.3.8.jar:5.3.8]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:338) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) ~[spring-boot-2.5.1.jar:2.5.1]
at com.example.demo.SpringJpaApplication.main(SpringJpaApplication.java:11) ~[classes/:na]
Caused by: org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean.
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getWebServerFactory(ServletWebServerApplicationContext.java:210) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:180) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:160) ~[spring-boot-2.5.1.jar:2.5.1]
... 8 common frames omitted
What am i missing?
Refer to ApplicationContextException: Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean, seems you're missing the annotation #SpringBootApplication
#SpringBootApplication
public class SpringJpaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringJpaApplication.class, args);
}
}
https://github.com/hardikSinghBehl/jokes-app
The Project Structure
Pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.hardik</groupId>
<artifactId>chuck-norris-jokes-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Spring-Boot-chuck-norris-jokes-app</name>
<description>Project using spring boot and actuator to create a jokes application</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>guru.springframework</groupId>
<artifactId>chuck-norris-for-actuator</artifactId>
<version>0.0.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Controller class
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.hardik.chucknorrisjokesapp.services.JokeService;
#Controller
public class JokeController {
private JokeService jokeService;
public JokeController() {
super();
}
#Autowired
public JokeController(JokeService jokeService) {
super();
this.jokeService = jokeService;
}
#RequestMapping({"/",""})
public String showJoke(Model model){
model.addAttribute("joke", jokeService.getJoke());
return "chucknorris";
}
}
Service class
import org.springframework.stereotype.Service;
import guru.springframework.norris.chuck.ChuckNorrisQuotes;
#Service
public class ChuckNorrisJokeService implements JokeService{
private ChuckNorrisQuotes chuckNorrisQuotes;
public ChuckNorrisJokeService() {
super();
this.chuckNorrisQuotes = new ChuckNorrisQuotes();
}
public ChuckNorrisJokeService(ChuckNorrisQuotes chuckNorrisQuotes) {
super();
this.chuckNorrisQuotes = chuckNorrisQuotes;
}
#Override
public String getJoke(){
return chuckNorrisQuotes.getRandomQuote();
}
}
code works fine, i don't get any error, but when i go to localhost, the 404 error message is displayed
ChuckNorrisQuotes class is available in jar file added in dependencies
have attatched my git repository for this project, have tried everything and i am stuck, tried getMapping annotation, tried #getParam
when i am using #RestComponent, then local host is returning "chucknorris" as a String on screen rather than the html file in resources/templates
I tried to configure EhCache programmatically, but I have some problems... Firstly, I tried to use the newest version, where I just created config class with just one method and then I get the error java.lang.ClassNotFoundException: com.google.common.cache.CacheBuilderSpec.
I tried with lower version, which is 2.10.4, which is already in Spring Boot, but now I'm getting an error that CacheManager must not be null and I have no idea what is the problem... Probably I'm missing something, but I don't know what...
Current code with Ehcache 2.X:
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.interceptor.SimpleCacheErrorHandler;
import org.springframework.cache.interceptor.SimpleCacheResolver;
import org.springframework.cache.interceptor.SimpleKeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import net.sf.ehcache.config.CacheConfiguration;
#Configuration
#EnableCaching
public class EhCacheConfiguration implements CachingConfigurer {
#Bean(destroyMethod = "shutdown")
public net.sf.ehcache.CacheManager ehCacheManager() {
CacheConfiguration cacheConfiguration = new CacheConfiguration();
cacheConfiguration.setName("myCacheName");
cacheConfiguration.setMemoryStoreEvictionPolicy("LRU");
cacheConfiguration.setMaxEntriesLocalHeap(1000);
net.sf.ehcache.config.Configuration config = new net.sf.ehcache.config.Configuration();
config.addCache(cacheConfiguration);
return net.sf.ehcache.CacheManager.newInstance(config);
}
#Bean
#Override
public CacheManager cacheManager() {
return new EhCacheCacheManager(ehCacheManager());
}
#Bean
#Override
public KeyGenerator keyGenerator() {
return new SimpleKeyGenerator();
}
#Bean
#Override
public CacheResolver cacheResolver() {
return new SimpleCacheResolver();
}
#Bean
#Override
public CacheErrorHandler errorHandler() {
return new SimpleCacheErrorHandler();
}
}
Previous version of code with Ehcache 3.X:
import static org.ehcache.config.builders.CacheConfigurationBuilder.newCacheConfigurationBuilder;
import static org.ehcache.config.builders.CacheManagerBuilder.newCacheManagerBuilder;
import static org.ehcache.config.builders.ResourcePoolsBuilder.newResourcePoolsBuilder;
import java.util.concurrent.TimeUnit;
import org.ehcache.CacheManager;
import org.ehcache.config.units.EntryUnit;
import org.ehcache.config.units.MemoryUnit;
import org.ehcache.expiry.Duration;
import org.ehcache.expiry.Expirations;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
#EnableCaching
public class EhCacheConfiguration {
private static final Logger log = LoggerFactory.getLogger(EhCacheConfiguration.class);
#Bean
public CacheManager ehCacheManager() {
log.info("Creating cache manager programmatically");
try (CacheManager cacheManager = newCacheManagerBuilder()
.withCache("sessionCache",
newCacheConfigurationBuilder(Long.class, String.class,
newResourcePoolsBuilder().heap(2000, EntryUnit.ENTRIES).offheap(1, MemoryUnit.GB))
.withExpiry(Expirations.timeToLiveExpiration(Duration.of(30, TimeUnit.MINUTES)))
.withExpiry(Expirations.timeToIdleExpiration(Duration.of(5, TimeUnit.MINUTES))))
.build(true)) {
return cacheManager;
}
}
The class is in the subpackage of package where is the MyApplication class.
MyApplication class:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.web.WebApplicationInitializer;
#SpringBootApplication
#EnableJpaRepositories
public class MyApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Application is using Spring Boot and is running on WebLogic server...
Edit:
Added pom.xml:
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<groupId>com.app.lui.serviceweb</groupId>
<artifactId>lui-serviceWeb</artifactId>
<packaging>war</packaging>
<name>lui-serviceWeb</name>
<description>Lui Project</description>
<dependencies>
<dependency>
<groupId>com.app.lui.drools</groupId>
<artifactId>lui-drools</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- Apache CXF -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.1.11</version>
</dependency>
<!-- DB -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- Ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
</dependencies>
<build>
<finalName>lui-serviceWeb</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<archive>
<manifest>
<addDefaultImplementationEntries>false</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
EDIT 2:
Added project:
Ehcache project
Logs:
Ehcache 2.X stack trace
Ehcache 3.X stack trace
You need the cacheResolver to know the cacheManager.
So, in your current code, just replace the cacheResolver bean with:
#Bean
#Override
public CacheResolver cacheResolver() {
return new SimpleCacheResolver(cacheManager());
}
And it is done. Might be the same for EhCache 3.X but I didn't test it.
Hope it helps.
We will need a fully working project to answer wit certainty. Right now, I tried your code and had to hack around to make it compile. CacheBuilderSpec is indeed a guava thing. So it seems Spring is picking Guava as its cache implementation, not Ehcache.
You might want to debug CacheAutoConfiguration and GuavaCacheConfiguration. The latter will be initialized at some point by Spring.
Basically, what I want in the end, is that an object in some piece of code is wired up with my Spring Component, although that object is not created / managed by Spring.
The object in question is:
package demo;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
#Configurable(autowire= Autowire.BY_TYPE)
public class NotSoSpring {
SpringComponent springComponent;
public NotSoSpring() {
springComponent.test();
}
#Autowired
public void setSpringComponent(SpringComponent springComponent) {
this.springComponent = springComponent;
}
public void test() {
springComponent.test();
}
}
And the component is as simple as that:
package demo;
import org.springframework.stereotype.Component;
#Component
public class SpringComponent {
public void test() {
System.out.println("Hello. Wow, this works!");
}
}
The Spring configuration is done by the following piece of code:
package demo;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.EnableLoadTimeWeaving;
import org.springframework.context.annotation.aspectj.EnableSpringConfigured;
#SpringBootApplication
#EnableSpringConfigured
#EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
#EnableAspectJAutoProxy
#ComponentScan(basePackages = "demo")
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Override
public void run(String... strings) throws Exception {
NotSoSpring spring = new NotSoSpring();
spring.test();
}
}
And here's the project's configuration:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.test</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.5.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
That's all the files, and here's the JVM command line option I used:
-javaagent:c:/.m2/repository/org/springframework/spring-instrument/4.1.5.RELEASE/spring-instrument-4.1.5.RELEASE.jar
So this results in
Exception in thread "main" java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:675)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:690)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
at demo.DemoApplication.main(DemoApplication.java:19)
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 com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.NullPointerException
at demo.NotSoSpring.<init>(NotSoSpring.java:13)
at demo.DemoApplication.run(DemoApplication.java:24)
at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:672)
... 10 more
I looked through other SO questions, the Spring Documentation and a lot of blogs, but unfortunately they usually refer to Spring 3 and to XML based configurations.
Might be related to this question which has no solution either.