Should Scheduled Task start a Spring application each time it is executed? - spring

I'm running a spring boot application with a scheduled task. It is divided into two maven projects, lets call them 'lib' and 'app'.
The class whose method is annotated with #Scheduled is located in 'lib' project. It does not contain any classes annotated with #SpringBootApplication, or any classes that start a spring application. Here's what Scheduled bean looks like:
#Component
public class Refresher {
#Scheduled(fixedRate = 30000)
public void refresh() {
...
}
The 'lib' project also has a simple SchedulingConfigurer implementation that tells Spring to use ThreadPoolTaskScheduler with its Scheduled tasks.
The 'app' project, on the other hand, has a dependency on 'lib' and has a class annotated with #SpringBootApplication, and starts it as usual:
#SpringBootApplication(scanBasePackages = {"x.y", "x.y.z"})
#EnableScheduling
public class ExampleService {
public static void main(String[] args) {
SpringApplication.run(ExampleService.class, args);
}
}
Both maven projects have this:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/>
</parent>
So, when ExampleService starts I see it finds Refresher and executes its refresh method once every 30 sec alright, but something strange appears in the logs. When Example service starts, it prints:
2019-01-11 18:18:27.647 INFO 6428 --- [ main] x.y.z.ExampleService : Started ExampleService in 32.613 seconds (JVM running for 40.37)
This is great, it tells me that main application has started. But then I get the following lines every 30 seconds, every time Refresher gets executed:
2019-01-11 18:18:58.596 INFO 6428 --- [nio-8080-exec-3] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#66e31414: startup date [Fri Jan 11 18:18:58 MSK 2019]; root of context hierarchy
2019-01-11 18:18:58.637 INFO 6428 --- [nio-8080-exec-3] trationDelegate$BeanPostProcessorChecker : Bean 'configurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$7c355e31] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
... some logging from the refresh() method
2019-01-11 18:19:01.020 INFO 6428 --- [nio-8080-exec-3] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#1262db58: startup date [Fri Jan 11 18:19:01 MSK 2019]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext#66e31414
2019-01-11 18:19:01.035 INFO 6428 --- [nio-8080-exec-3] o.s.boot.SpringApplication : Started application in 3.585 seconds (JVM running for 73.771)
2019-01-11 18:19:01.035 INFO 6428 --- [nio-8080-exec-3] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#1262db58: startup date [Fri Jan 11 18:19:01 MSK 2019]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext#66e31414
2019-01-11 18:19:01.035 INFO 6428 --- [nio-8080-exec-3] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#66e31414: startup date [Fri Jan 11 18:18:58 MSK 2019]; root of context hierarchy
Notice 'Started application in 3.585 seconds (JVM running for 73.771)'. This happens every 30 seconds. It looks like in order to run the Scheduled bean Spring runs a new separate Spring application every time. Why would it do that, and can this be avoided? Can Scheduled bean run as part of currently started Spring Boot app?

Related

Resolving Singletons in Spring Boot Rest Controllers with Kotlin

I am new to Spring and Spring Boot and I played around with different ways how to resolve Beans. In my example I've got a Bean that should always be a singleton. What surprises me is that there seems to be a way where this bean is resolved as, I assume, "prototype".
Could anyone explain to me why it's not a singleton when it is resolved in the signature of the method showSingletonBeans?
#SpringBootApplication
class DemoApplication
fun main(args: Array<String>) {
runApplication<DemoApplication>(*args)
}
#Service("stackSingletonBean")
// #Scope("singleton")
class MySingletonBean {
init {
println("Created MySingletonBean " + this.hashCode())
}
}
#RestController
class MyController {
#Autowired
// #Qualifier("singletonBean")
lateinit var memberSingletonBean: MySingletonBean
#Autowired
lateinit var singeltonFactory: ObjectFactory<MySingletonBean>
fun buildSingleton() : MySingletonBean {
return singeltonFactory.`object`
}
#Lookup
fun getSingletonInstance() : MySingletonBean? {
return null
}
#GetMapping("/")
fun showSingletonBeans(#Autowired stackSingletonBean: MySingletonBean) {
println("member " + memberSingletonBean.hashCode() )
println("stack " + stackSingletonBean.hashCode())
println("lookup:" + getSingletonInstance().hashCode())
println("factory: " + buildSingleton().hashCode())
}
}
The log looks like that:
2020-08-13 18:44:32.604 INFO 172175 --- [ main] com.example.demo.DemoApplicationKt : No active profile set, falling back to default profiles: default
2020-08-13 18:44:33.118 INFO 172175 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-08-13 18:44:33.124 INFO 172175 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-08-13 18:44:33.124 INFO 172175 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.37]
2020-08-13 18:44:33.164 INFO 172175 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-08-13 18:44:33.164 INFO 172175 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 528 ms
Created MySingletonBean 1747702724
2020-08-13 18:44:33.286 INFO 172175 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-08-13 18:44:33.372 INFO 172175 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2020-08-13 18:44:33.379 INFO 172175 --- [ main] com.example.demo.DemoApplicationKt : Started DemoApplicationKt in 1.011 seconds (JVM running for 1.24)
2020-08-13 18:44:37.341 INFO 172175 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-08-13 18:44:37.341 INFO 172175 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-08-13 18:44:37.344 INFO 172175 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 3 ms
Created MySingletonBean 562566586
member 1747702724
stack 562566586
lookup:1747702724
factory: 1747702724
Created MySingletonBean 389331797
member 1747702724
stack 389331797
lookup:1747702724
factory: 1747702724
Resolving controller method parameters is actually quite different mechanism. It has nothing to do with dependency injection and the #Autowired annotation: the annotation can be removed and it won't change the behavior.
Although #Autowired can technically be declared on individual method or constructor parameters since Spring Framework 5.0, most parts of the framework ignore such declarations. The only part of the core Spring Framework that actively supports autowired parameters is the JUnit Jupiter support in the spring-test module (see the TestContext framework reference documentation for details).
https://docs.spring.io/
In your case, the stackSingletonBean is instantiated by the ModelAttributeMethodArgumentResolver. It's not aware of the #Service annotation nor of its scope: it simply uses the default constructor on each request.
Model attributes are sourced from the model, or created using a default constructor and then added to the model.
Note that use of #ModelAttribute is optional — for example, to set its attributes. By default, any argument that is not a simple value type( as determined by BeanUtils#isSimpleProperty) and is not resolved by any other argument resolver is treated as if it were annotated with #ModelAttribute. Web on Reactive Stack

Spring Boot controller returns 404 for all api endpoints

I am new to Spring's ecosystem. And I am stuck with this particular situation. My application server responds with 404 for all of my API endpoints.
This is my controller
package com.example.controllers;
import com.example.models.Movie;
import com.example.services.MovieService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
#RestController
public class MovieController {
#Autowired
private MovieService movieService;
#RequestMapping(value = "/movies", method = RequestMethod.GET)
#ResponseBody
public List<Movie> getAllMovies(){
return movieService.getAllMovies();
}
#RequestMapping(value = "/movies", method = RequestMethod.POST)
#ResponseBody
public Movie addNewMovie(#RequestBody Movie movie){
System.out.println("Hello World");
return movieService.addMovie(movie);
}
#RequestMapping(value = "/movies/{id}", method = RequestMethod.GET)
#ResponseBody
public Optional<Movie> getMovieById(#PathVariable String id){
return movieService.getMovieById(id);
}
#RequestMapping(value = "/movies", method = RequestMethod.PUT)
#ResponseBody
public Movie updateMovie(#RequestBody Movie movie){
return movieService.updateMovie(movie);
}
#RequestMapping(value = "/movies/{id}", method = RequestMethod.DELETE)
public void removeMovieById(#PathVariable String id){
movieService.deleteMovie(id);
}
}
And this my main class
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#EnableAutoConfiguration
#ComponentScan
#SpringBootApplication
public class LearnSpringApplication{
public static void main(String[] args) {
SpringApplication.run(LearnSpringApplication.class, args);
}
}
I am running it on localhost and port is 8080. I did set up a small app prior to this one, and that worked as expected. However, I am guessing that it's because the controller is in a different package since in the previous app, the main class and the controller were in the same package.
Edit Here's my pom.xml file:
<?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>com.example</groupId>
<artifactId>learn_spring</artifactId>
<version>0.0.1</version>
<packaging>jar</packaging>
<name>learn_spring</name>
<description>Project to learn Spring</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>10</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</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>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
EDIT My Spring-Boot startup logs are
2018-05-03 17:16:44.937 INFO 14017 --- [ main] com.example.LearnSpringApplication : Starting LearnSpringApplication v0.0.1 on tfc with PID 14017 (/home/ayush/Workspace/learn_spring/target/learn_spring-0.0.1.jar started by ayush in /home/ayush/Workspace/learn_spring)
2018-05-03 17:16:44.940 INFO 14017 --- [ main] com.example.LearnSpringApplication : No active profile set, falling back to default profiles: default
2018-05-03 17:16:45.045 INFO 14017 --- [ main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#6aba2b86: startup date [Thu May 03 17:16:45 IST 2018]; root of context hierarchy
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$1 (jar:file:/home/ayush/Workspace/learn_spring/target/learn_spring-0.0.1.jar!/BOOT-INF/lib/spring-core-5.0.5.RELEASE.jar!/) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
2018-05-03 17:16:46.113 INFO 14017 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2018-05-03 17:16:46.138 INFO 14017 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2018-05-03 17:16:46.139 INFO 14017 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.29
2018-05-03 17:16:46.151 INFO 14017 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib]
2018-05-03 17:16:46.218 INFO 14017 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-05-03 17:16:46.218 INFO 14017 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1186 ms
2018-05-03 17:16:46.336 INFO 14017 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
2018-05-03 17:16:46.339 INFO 14017 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-05-03 17:16:46.340 INFO 14017 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-05-03 17:16:46.340 INFO 14017 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-05-03 17:16:46.340 INFO 14017 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-05-03 17:16:46.455 INFO 14017 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-05-03 17:16:46.720 INFO 14017 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for #ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#6aba2b86: startup date [Thu May 03 17:16:45 IST 2018]; root of context hierarchy
2018-05-03 17:16:46.786 INFO 14017 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-05-03 17:16:46.787 INFO 14017 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-05-03 17:16:46.817 INFO 14017 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-05-03 17:16:46.817 INFO 14017 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-05-03 17:16:47.060 INFO 14017 --- [ main] org.mongodb.driver.cluster : Cluster created with settings {hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
2018-05-03 17:16:47.151 INFO 14017 --- [localhost:27017] org.mongodb.driver.connection : Opened connection [connectionId{localValue:1, serverValue:12}] to localhost:27017
2018-05-03 17:16:47.155 INFO 14017 --- [localhost:27017] org.mongodb.driver.cluster : Monitor thread successfully connected to server with description ServerDescription{address=localhost:27017, type=STANDALONE, state=CONNECTED, ok=true, version=ServerVersion{versionList=[3, 6, 3]}, minWireVersion=0, maxWireVersion=6, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=null, roundTripTimeNanos=2192957}
2018-05-03 17:16:47.323 INFO 14017 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-05-03 17:16:47.392 INFO 14017 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2018-05-03 17:16:47.395 INFO 14017 --- [ main] com.example.LearnSpringApplication : Started LearnSpringApplication in 2.89 seconds (JVM running for 3.296)
Sometimes is because of your package structure. Always make sure your controllers are in same package or sub-package level as the #SpringBootApplication class.
For example:
If application class is at com.a.b then controllers should be at com.a.b or com.a.b.c or com.a.b.c.d etc. You don't always have to add #ComponentScan to get them registered.
You're using IntelliJ IDEA community version, which does not support the Spring Framework:
see https://www.jetbrains.com/idea/features/editions_comparison_matrix.html for reference
Update
Since you're using the command line, then the above does not apply. I'll leave it here as a reference, though.
In the comments, you have specified that when running mvn clean package followed by java -jar target/whatever-your-project-name-is.jar, you get the following error:
Field movieService in com.example.controllers.MovieController required a bean of type 'com.example.services.MovieService' that could not be found.
Please make sure that:
you have a class MovieService in the package services
that class is annotated with the #Service annotation
Update 2
Since the above did not work, try replacing
#ComponentScan
by
#ComponentScan({"com.example.services", "com.example.controllers"})
in your LearnSpringApplication class.
Include all other packages that have classes annotated with #Component, #Service, #Controller, #RestController, or #Repository.
Note that this is a workaround. Normally, having #ComponentScan alone should be sufficient -- or as #DarrenForsythe mentionned in the comment, even just #SpringBootApplication should be sufficient for your case.
I had the same problem today and tried the simple solution provided above by #Daniel Moshi. It worked fine. Thanks.
Other option is using like below:
#SpringBootApplication(scanBasePackages = "com.example")
...with this the Controller can stay in any sub-package of com.example and works good even without explicit usage of #ComponentScan.

Spring boot start up failing

I am newbie to Spring, I have written a spring application. when I try to start the application its giving me below logs but application being shutdown.
could you please help me anyone if i am doing something wrong here ?
2017-06-01 16:39:27.187 INFO 6040 --- [ main] com.slb.sims.flows.Application : Starting Application on SLB-25QDSY1 with PID 6040 (D:\SLB\SpringPOCs\prjSpringJDBCWS\target\classes started by LTangirala in D:\SLB\SpringPOCs\prjSpringJDBCWS)
2017-06-01 16:39:27.191 INFO 6040 --- [ main] com.slb.sims.flows.Application : No active profile set, falling back to default profiles: default
2017-06-01 16:39:27.313 INFO 6040 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#2c34f934: startup date [Thu Jun 01 16:39:27 CDT 2017]; root of context hierarchy
2017-06-01 16:39:28.448 INFO 6040 --- [ main] o.s.c.s.ClassPathXmlApplicationContext : Refreshing org.springframework.context.support.ClassPathXmlApplicationContext#2f16c6b3: startup date [Thu Jun 01 16:39:28 CDT 2017]; root of context hierarchy
2017-06-01 16:39:28.452 INFO 6040 --- [ main] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [applicationContext.xml]
2017-06-01 16:39:28.592 INFO 6040 --- [ main] o.s.j.d.DriverManagerDataSource : Loaded JDBC driver: com.mysql.jdbc.Driver
2017-06-01 16:39:29.080 INFO 6040 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2017-06-01 16:39:29.095 INFO 6040 --- [ main] com.slb.sims.flows.Application : Started Application in 2.342 seconds (JVM running for 3.083)
2017-06-01 16:39:29.096 INFO 6040 --- [ Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#2c34f934: startup date [Thu Jun 01 16:39:27 CDT 2017]; root of context hierarchy
2017-06-01 16:39:29.098 INFO 6040 --- [ Thread-2] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
Picked up _JAVA_OPTIONS: -Xmx1024M
it doesn't have an embedded server like Tomcat in classpath. add it and it will fix the issue
for MAVEN add this dependancy in pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
for Gradle (build.gradle) add
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
}
You need to add this dependency to your pom.xml.
After that it should work.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

Spring boot doesn't wait for request

Yesterday I got very strange spring boot behaviour
For example: i'm trying to start server using ./gradlew bootRun:
...
:findMainClass
:bootRun
:: Spring Boot :: (v1.3.1.RELEASE)
2016-01-19 16:37:15.315 INFO 6118 --- [ main] c.e.server.Application$Companion : Starting Application.Companion on fake with PID 6118 (/home/user/code/xproject/server/build/classes/main started by user in /home/user/code/xproject/server)
2016-01-19 16:37:15.320 INFO 6118 --- [ main] c.e.server.Application$Companion : No active profile set, falling back to default profiles: default
2016-01-19 16:37:15.400 INFO 6118 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#a3ec6b: startup date [Tue Jan 19 16:37:15 GMT 2016]; root of context hierarchy
2016-01-19 16:37:17.908 INFO 6118 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2016-01-19 16:37:17.923 INFO 6118 --- [ main] c.e.server.Application$Companion : Started Application.Companion in 3.048 seconds (JVM running for 3.421)
2016-01-19 16:37:17.924 INFO 6118 --- [ Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#a3ec6b: startup date [Tue Jan 19 16:37:15 GMT 2016]; root of context hierarchy
2016-01-19 16:37:17.930 INFO 6118 --- [ Thread-2] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
BUILD SUCCESSFUL
Total time: 23.756 secs
So it doesn't wait for requests as it always did. I thought there are some problems with classpath, so I put few annotated methods as #PostConstruct in Controllers and Services and can confirm that they are called and all dependencies are injected at that point.
Here is my gradle.build:
buildscript {
ext.kotlin_version = '1.0.0-beta-4584'
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.3.1.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'spring-boot'
apply plugin: 'kotlin'
jar {
baseName = 'xproject'
version = '0.1.0'
}
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-tomcat")
compile("org.springframework.boot:spring-boot-devtools")
compile 'org.springframework.data:spring-data-mongodb:1.8.2.RELEASE'
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile "com.restfb:restfb:1.18.1"
testCompile("junit:junit")
testCompile("org.springframework.boot:spring-boot-starter-test")
}
sourceSets {
main {
java.srcDirs += ['java', 'kotlin']
}
test {
java.srcDirs += 'test'
}
}
UPD#1
Here is Application class(I haven't touch it from the beginning).
#SpringBootApplication
open class Application {
companion object {
#JvmStatic fun main(args: Array<String>) {
SpringApplication.run(Application::class.java, *args)
}
}
}
UPD#2
Small self-contained code
#RestController
#SpringBootApplication
#ComponentScan
public class GreetingController {
public static void main(String[] a) {
SpringApplication.run(GreetingController.class, a);
}
#PostConstruct
public void postConstruct() {
System.out.println("!! Post construct called");
}
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
#RequestMapping("/greeting")
public Greeting greeting(#RequestParam(value="name", defaultValue="World") String name) {
return new Greeting(counter.incrementAndGet(),
String.format(template, name));
}
}
Gives me almost the same result
:: Spring Boot :: (v1.3.1.RELEASE)
2016-01-19 17:18:19.790 INFO 8230 --- [ restartedMain] hello.GreetingController : Starting GreetingController on fake with PID 8230 (/home/user/code/xproject/server/build/classes/main started by user in /home/user/code/xproject/server)
2016-01-19 17:18:19.814 INFO 8230 --- [ restartedMain] hello.GreetingController : No active profile set, falling back to default profiles: default
2016-01-19 17:18:19.918 INFO 8230 --- [ restartedMain] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#71ceb8: startup date [Tue Jan 19 17:18:19 GMT 2016]; root of context hierarchy
!! Post construct called
2016-01-19 17:18:22.860 INFO 8230 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2016-01-19 17:18:22.905 INFO 8230 --- [ restartedMain] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2016-01-19 17:18:22.922 INFO 8230 --- [ restartedMain] hello.GreetingController : Started GreetingController in 4.022 seconds (JVM running for 4.949)
2016-01-19 17:18:22.924 INFO 8230 --- [ Thread-8] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#71ceb8: startup date [Tue Jan 19 17:18:19 GMT 2016]; root of context hierarchy
2016-01-19 17:18:22.930 INFO 8230 --- [ Thread-8] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
Process finished with exit code 1
I was having exactly the same issue you just described and in my case, I had forgotten to add spring-boot-starter-web as dependency. I had copy/pasted the dependencies from a basic example just having spring-boot-starter and I misread it.
Once I added it, the container was started normally and I got a regular web app listening at the 8080 port.
It is my first very basic test so it just has spring-boot-starter-web, kotlin-stdlib and kotlin-reflect as dependencies and class that looks like this:
#SpringBootApplication
class Application {
private val log = LoggerFactory.getLogger(Application::class.java)
}
fun main(args: Array<String>) {
SpringApplication.run(Application::class.java, *args)
}
From what I see in your code, the only thing I can think of is that you might require kotlin-reflect as well. I got the idea of including it from this blog post and this sample project also uses it so...
Good luck!

Spring Integration - MQTT subscription issue

I am trying to implement Spring integration with MQTT. I am using Mosquitto as MQTT broker. with the reference to docs provided in the following link. I have created a project and added all the required jar files. when i execute MQTTJavaApplication.
public class MqttJavaApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(MqttJavaApplication.class)
.web(false)
.run(args);
}
#Bean
public MessageChannel mqttInputChannel() {
return new DirectChannel();
}
#Bean
public MqttPahoMessageDrivenChannelAdapter inbound() {
MqttPahoMessageDrivenChannelAdapter adapter =
new MqttPahoMessageDrivenChannelAdapter("tcp://localhost:1883", "test",
"sample");
adapter.setCompletionTimeout(5000);
adapter.setConverter(new DefaultPahoMessageConverter());
adapter.setQos(1);
adapter.setOutputChannel(mqttInputChannel());
return adapter;
}
#Bean
#ServiceActivator(inputChannel = "mqttInputChannel")
public MessageHandler handler() {
return new MessageHandler() {
#Override
public void handleMessage(Message<?> message) {
System.out.println("Test##########"+message.getPayload());
}
};
}
}
I am getting following error when i publish a message via MQTT broker.
[2015-11-23 10:08:19.545] boot - 8100 INFO [main] --- AnnotationConfigApplicationContext: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#2d0e1c: startup date [Mon Nov 23 10:08:19 IST 2015]; root of context hierarchy
[2015-11-23 10:08:19.831] boot - 8100 INFO [main] --- PropertiesFactoryBean: Loading properties file from URL [jar:file:/D:/IoTWorkspace/MQTTTest/WebContent/WEB-INF/lib/spring-integration-core-4.2.1.RELEASE.jar!/META-INF/spring.integration.default.properties]
[2015-11-23 10:08:20.001] boot - 8100 INFO [main] --- DefaultLifecycleProcessor: Starting beans in phase 1073741823
[2015-11-23 10:08:20.104] boot - 8100 INFO [main] --- MqttPahoMessageDrivenChannelAdapter: started inbound
[2015-11-23 10:08:20.112] boot - 8100 INFO [main] --- MqttJavaApplication: Started MqttJavaApplication in 1.602 seconds (JVM running for 2.155)
[2015-11-23 10:13:04.564] boot - 8100 ERROR [MQTT Call: test] --- MqttPahoMessageDrivenChannelAdapter: Unhandled exception for GenericMessage [payload=Testing Subscription, headers={timestamp=1448253784563, id=cd5be974-3b19-8317-47eb-1c139725be24, mqtt_qos=0, mqtt_topic=sample, mqtt_retained=false, mqtt_duplicate=false}]
org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'unknown.channel.name'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:81)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:442)
at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:392)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:115)
at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:45)
at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:105)
at org.springframework.integration.endpoint.MessageProducerSupport.sendMessage(MessageProducerSupport.java:105)
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter.messageArrived(MqttPahoMessageDrivenChannelAdapter.java:262)
at org.eclipse.paho.client.mqttv3.internal.CommsCallback.handleMessage(CommsCallback.java:336)
at org.eclipse.paho.client.mqttv3.internal.CommsCallback.run(CommsCallback.java:148)
at java.lang.Thread.run(Thread.java:722)
Caused by: org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:153)
at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:120)
at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
... 10 more
[2015-11-23 10:13:04.613] boot - 8100 ERROR [MQTT Call: test] --- MqttPahoMessageDrivenChannelAdapter: Lost connection:MqttException; retrying...
[2015-11-23 10:13:04.614] boot - 8100 ERROR [MQTT Call: test] --- MqttPahoMessageDrivenChannelAdapter: Failed to schedule reconnect
java.lang.NullPointerException
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter.scheduleReconnect(MqttPahoMessageDrivenChannelAdapter.java:228)
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter.connectionLost(MqttPahoMessageDrivenChannelAdapter.java:255)
at org.eclipse.paho.client.mqttv3.internal.CommsCallback.connectionLost(CommsCallback.java:229)
at org.eclipse.paho.client.mqttv3.internal.ClientComms.shutdownConnection(ClientComms.java:339)
at org.eclipse.paho.client.mqttv3.internal.CommsCallback.run(CommsCallback.java:171)
at java.lang.Thread.run(Thread.java:722)
[2015-11-23 10:13:04.617] boot - 8100 INFO [Thread-0] --- AnnotationConfigApplicationContext: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#2d0e1c: startup date [Mon Nov 23 10:08:19 IST 2015]; root of context hierarchy
[2015-11-23 10:13:04.619] boot - 8100 INFO [Thread-0] --- DefaultLifecycleProcessor: Stopping beans in phase 1073741823
[2015-11-23 10:13:04.622] boot - 8100 ERROR [Thread-0] --- MqttPahoMessageDrivenChannelAdapter: Exception while unsubscribing
Client is not connected (32104)
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:27)
at org.eclipse.paho.client.mqttv3.internal.ClientComms.sendNoWait(ClientComms.java:132)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.unsubscribe(MqttAsyncClient.java:707)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.unsubscribe(MqttAsyncClient.java:682)
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter.doStop(MqttPahoMessageDrivenChannelAdapter.java:124)
at org.springframework.integration.endpoint.AbstractEndpoint.doStop(AbstractEndpoint.java:145)
at org.springframework.integration.endpoint.AbstractEndpoint.stop(AbstractEndpoint.java:128)
at org.springframework.context.support.DefaultLifecycleProcessor.doStop(DefaultLifecycleProcessor.java:229)
at org.springframework.context.support.DefaultLifecycleProcessor.access$300(DefaultLifecycleProcessor.java:51)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.stop(DefaultLifecycleProcessor.java:363)
at org.springframework.context.support.DefaultLifecycleProcessor.stopBeans(DefaultLifecycleProcessor.java:202)
at org.springframework.context.support.DefaultLifecycleProcessor.onClose(DefaultLifecycleProcessor.java:118)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:966)
at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:893)
[2015-11-23 10:13:04.623] boot - 8100 ERROR [Thread-0] --- MqttPahoMessageDrivenChannelAdapter: Exception while disconnecting
Client is disconnected (32101)
at org.eclipse.paho.client.mqttv3.internal.ExceptionHelper.createMqttException(ExceptionHelper.java:27)
at org.eclipse.paho.client.mqttv3.internal.ClientComms.disconnect(ClientComms.java:405)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.disconnect(MqttAsyncClient.java:524)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.disconnect(MqttAsyncClient.java:493)
at org.eclipse.paho.client.mqttv3.MqttAsyncClient.disconnect(MqttAsyncClient.java:500)
at org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter.doStop(MqttPahoMessageDrivenChannelAdapter.java:131)
at org.springframework.integration.endpoint.AbstractEndpoint.doStop(AbstractEndpoint.java:145)
at org.springframework.integration.endpoint.AbstractEndpoint.stop(AbstractEndpoint.java:128)
at org.springframework.context.support.DefaultLifecycleProcessor.doStop(DefaultLifecycleProcessor.java:229)
at org.springframework.context.support.DefaultLifecycleProcessor.access$300(DefaultLifecycleProcessor.java:51)
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.stop(DefaultLifecycleProcessor.java:363)
at org.springframework.context.support.DefaultLifecycleProcessor.stopBeans(DefaultLifecycleProcessor.java:202)
at org.springframework.context.support.DefaultLifecycleProcessor.onClose(DefaultLifecycleProcessor.java:118)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:966)
at org.springframework.context.support.AbstractApplicationContext$1.run(AbstractApplicationContext.java:893)
[2015-11-23 10:13:04.624] boot - 8100 INFO [Thread-0] --- MqttPahoMessageDrivenChannelAdapter: stopped inbound
Please find below stack trace after adding #SpringBootApplication Annotation
[2015-11-26 10:55:46.571] boot - 5524 INFO [main] --- AnnotationConfigApplicationContext: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext#562d4b: startup date [Thu Nov 26 10:55:46 IST 2015]; root of context hierarchy
[2015-11-26 10:55:46.572] boot - 5524 WARN [main] --- AnnotationConfigApplicationContext: Exception thrown from ApplicationListener handling ContextClosedEvent
java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.context.annotation.AnnotationConfigApplicationContext#562d4b: startup date [Thu Nov 26 10:55:46 IST 2015]; root of context hierarchy
at org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:337)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:324)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1025)
at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:988)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:329)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:130)
at com.igate.MqttJavaApplication.main(MqttJavaApplication.java:32)
[2015-11-26 10:55:46.594] boot - 5524 WARN [main] --- AnnotationConfigApplicationContext: Exception thrown from LifecycleProcessor on context close
java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via the context: org.springframework.context.annotation.AnnotationConfigApplicationContext#562d4b: startup date [Thu Nov 26 10:55:46 IST 2015]; root of context hierarchy
at org.springframework.context.support.AbstractApplicationContext.getLifecycleProcessor(AbstractApplicationContext.java:350)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:1033)
at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:988)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:329)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:130)
at com.igate.MqttJavaApplication.main(MqttJavaApplication.java:32)
Exception in thread "main" java.lang.IllegalStateException: At least one base package must be specified
at org.springframework.context.annotation.ComponentScanAnnotationParser.parse(ComponentScanAnnotationParser.java:121)
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:214)
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:149)
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:135)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:260)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:203)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:617)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:446)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:648)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:130)
at com.igate.MqttJavaApplication.main(MqttJavaApplication.java:32)
Yep! That's true. Without #SpringBootApplication I have the same StackTrace.
The Spring Boot stuff includes IntegrationAutoConfiguration who is responsible for subscribers and TaskScheduler bean population.
Probably too late to answer but hope it might help some beginner.
Few Things:-
Declare #SpringBootApplication in your main class to let the project know its a spring boot application
For the 2nd Error, Define base package of the project where spring boot will refer for configuration files etc. To do so, add #ComponentScan({"package-name"}) at class level.
Sample Example:-
#SpringBootApplication
#ComponentScan({"package-name"})
public class Main {
...
}

Resources