Spring ServletRegistrationBean not loaded in JUnit Test - spring-mvc

I'm trying to test a Rest Service in my Spring Boot Application.
I can do ir successfully when I run or debug the whole application. Spring Bott start shows the following lines, among others:
2015-07-02 17:04:10.654 INFO 3084 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.0.20
2015-07-02 17:04:10.769 INFO 3084 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2015-07-02 17:04:10.769 INFO 3084 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 2449 ms
2015-07-02 17:04:11.219 INFO 3084 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2015-07-02 17:04:11.224 INFO 3084 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2015-07-02 17:04:11.224 INFO 3084 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
However, when I run my JUnit test, everything works fine, request mappings work, etc, except that the servlet is not initialized. Indeed, those lines above do not appear.
That's strange, because I'm running the test using the same Application.class which I use to run the whole application. This is Application.class:
#ImportResource("classpath:/META-INF/spring/integration/spring-integration-context.xml")
#SpringBootApplication
#WebAppConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
And from my JUnit test:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = Application.class)
public class CatalogRestControllerTests extends AbstractTransactionalJUnit4SpringContextTests {
...
#Test
public void someTest() {...}
}
I've been trying to fix the problem from servlet-context.xml and web.xml configuration files. But I don't think the problem is there, since it works for Application.class
Any idea?
Thank you!

Found it.
So it seems I was missing #WebIntegrationTest annotation on my JUnit class. This is what documentation says about #WebIntegrationTest:
Test class annotation signifying that the tests are "web integration
tests" and therefore require full startup in the same way as a
production application (listening on normal ports). Normally used in
conjunction with #SpringApplicationConfiguration,
This annotation can be used as an alternative to #IntegrationTest and
#WebAppConfiguration.

Related

Spring cloud stream handling poison pills with Kafka DLT

spring-boot 2.5.2
spring-cloud Hoxton.SR12
spring-kafka 2.6.7 (downgraded due to issue: https://github.com/spring-cloud/spring-cloud-stream-binder-kafka/issues/1079)
I'm following this recipe to handle deserialisation errors: https://github.com/spring-cloud/spring-cloud-stream-samples/blob/main/recipes/recipe-3-handling-deserialization-errors-dlq-kafka.adoc
I created the beans mentioned in the recipe above as:
Configuration
#Slf4j
public class ErrorHandlingConfig {
#Bean
public ListenerContainerCustomizer<AbstractMessageListenerContainer<byte[], byte[]>> customizer(SeekToCurrentErrorHandler errorHandler) {
return (container, dest, group) -> {
container.setErrorHandler(errorHandler);
};
}
#Bean
public SeekToCurrentErrorHandler errorHandler(DeadLetterPublishingRecoverer deadLetterPublishingRecoverer) {
return new SeekToCurrentErrorHandler(deadLetterPublishingRecoverer);
}
#Bean
public DeadLetterPublishingRecoverer publisher(KafkaOperations bytesTemplate) {
return new DeadLetterPublishingRecoverer(bytesTemplate);
}
}
configuration file:
spring:
cloud:
stream:
default:
producer:
useNativeEncoding: true
consumer:
useNativeDecoding: true
bindings:
myInboundRoute:
destination: some-destination.1
group: a-custom-group
myOutboundRoute:
destination: some-destination.2
kafka:
binder:
brokers: localhost
defaultBrokerPort: 9092
configuration:
application:
security: PLAINTEXT
bindings:
myInboundRoute:
consumer:
autoCommitOffset: true
startOffset: latest
enableDlq: true
dlqName: my-dql.poison
dlqProducerProperties:
configuration:
value.serializer: myapp.serde.MyCustomSerializer
configuration:
value.deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer
spring.deserializer.value.delegate.class: myapp.serde.MyCustomSerializer
myOutboundRoute:
producer:
configuration:
key.serializer: org.apache.kafka.common.serialization.StringSerializer
value.serializer: myapp.serde.MyCustomSerializer
I was expecting the DLT to be called my-dql.poison. This topic is in fact created fine, however I also get a second topic auto created called some-destination.1.DLT
Why does it create this as well as the one I have named in the config with dlqName ?
What am I doing wrong? When I poll for messages, the message is in the auto created some-destination.1.DLT and not my dlqName
You should not configure dlt processing in the binding if you configure the STCEH in the container. Also set maxAttempts=1 to disable retries there.
You need to configure a destination resolver in the DLPR to use a different name.
/**
* Create an instance with the provided template and destination resolving function,
* that receives the failed consumer record and the exception and returns a
* {#link TopicPartition}. If the partition in the {#link TopicPartition} is less than
* 0, no partition is set when publishing to the topic.
* #param template the {#link KafkaOperations} to use for publishing.
* #param destinationResolver the resolving function.
*/
public DeadLetterPublishingRecoverer(KafkaOperations<? extends Object, ? extends Object> template,
BiFunction<ConsumerRecord<?, ?>, Exception, TopicPartition> destinationResolver) {
this(Collections.singletonMap(Object.class, template), destinationResolver);
}
See https://docs.spring.io/spring-kafka/docs/current/reference/html/#dead-letters
There is an open issue to configure the DLPR with the binding's DLT name.
https://github.com/spring-cloud/spring-cloud-stream-binder-kafka/issues/1031

use #ControllerAdvice and #ExceptionHandler but still also allow for the default exception mapping

When i use a #ControllerAdvice with the #ExceptionHandler annotation then none of the normal exception handling works anymore. All results in a HTML page with the title "HTTP Status 500 – Internal Server Error" and nothing is logged in the console.
I've created a simple #ControllerAdvice as below, when this didn't work as expected i started trying with the basePackages and extending from ResponseEntityExceptionHandler.
#ControllerAdvice(basePackages = "nl.xxxx.events")
public class EventExceptionHandler extends ResponseEntityExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(EventExceptionHandler.class);
#ResponseStatus(HttpStatus.NOT_FOUND)
#ExceptionHandler(EventNotFoundException.class)
public void handlePersonNotFound(RuntimeException ex) {
logger.error("error", ex);
}
}
In the service i throw the exception using:
public Event findById(Long id) {
return this.eventRepository.findById(id).orElseThrow(() -> new EventNotFoundException(id));
}
I've tried to compare the flow of code with and without #ControllerAdvice but there are numerous things that are different. For example without the #ControllerAdvice the value attribute of the HttpEntityMethodProcessor is set with the an object describing the exception. But with the #ControllerAdvice this attribute is always null.
I expected the code above to not interfere with the normal exception handling.
As a example i'd like to use the "could not initialize proxy - no Session" error because this is easy for me to reproduce.
Before i added the #ControllerAdvice spring gave the following json result:
{"timestamp":"2019-06-02T19:17:14.223+0000","status":500,"error":"Internal Server Error","message":"Could not write JSON: failed to lazily initialize a collection of role: (truncated)....","path":"/events/find"}
and with debug logging:
2019-06-02 21:18:29.723 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : GET "/events/find?page=1&size=10", parameters={masked}
2019-06-02 21:18:29.724 DEBUG 1588 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.data.domain.Page<nl.xxxx.events.Event> nl.xxxx.events.EventController.findPersons(java.lang.String,java.lang.Integer,java.lang.Integer)
2019-06-02 21:18:29.728 DEBUG 1588 --- [nio-8080-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [application/json, text/plain, */*] and supported [application/json, application/*+json, application/json, application/*+json]
2019-06-02 21:18:29.728 DEBUG 1588 --- [nio-8080-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Writing [Page 1 of 19 containing nl.xxxx.events.Event instances]
2019-06-02 21:18:29.729 WARN 1588 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session (through reference chain: org.springframework.data.domain.PageImpl["content"]->java.util.Collections$UnmodifiableRandomAccessList[0]->nl.xxxx.events.Event["schedule"])]
2019-06-02 21:18:29.729 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed 500 INTERNAL_SERVER_ERROR
2019-06-02 21:18:29.729 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/error?page=1&size=10", parameters={masked}
2019-06-02 21:18:29.730 DEBUG 1588 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to 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)
2019-06-02 21:18:29.731 DEBUG 1588 --- [nio-8080-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [application/json, text/plain, */*] and supported [application/json, application/*+json, application/json, application/*+json]
2019-06-02 21:18:29.731 DEBUG 1588 --- [nio-8080-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [{timestamp=Sun Jun 02 21:18:29 CEST 2019, status=500, error=Internal Server Error, message=Could not (truncated)...]
2019-06-02 21:18:29.732 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 500
But now it returns:
<!doctype html><html lang="en"><head><title>HTTP Status 500 – Internal Server Error</title><style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 500 – Internal Server Error</h1></body></html>
And with debug logging:
2019-06-02 21:20:33.682 DEBUG 22308 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/events/find?page=1&size=10", parameters={masked}
2019-06-02 21:20:33.688 DEBUG 22308 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.data.domain.Page<nl.xxxx.events.Event> nl.xxxx.events.EventController.findPersons(java.lang.String,java.lang.Integer,java.lang.Integer)
2019-06-02 21:20:33.760 INFO 22308 --- [nio-8080-exec-1] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
2019-06-02 21:20:33.900 DEBUG 22308 --- [nio-8080-exec-1] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [application/json, text/plain, */*] and supported [application/json, application/*+json, application/json, application/*+json]
2019-06-02 21:20:33.901 DEBUG 22308 --- [nio-8080-exec-1] m.m.a.RequestResponseBodyMethodProcessor : Writing [Page 1 of 19 containing nl.xxxx.events.Event instances]
2019-06-02 21:20:33.923 DEBUG 22308 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Using #ExceptionHandler public final org.springframework.http.ResponseEntity<java.lang.Object> org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest) throws java.lang.Exception
2019-06-02 21:20:33.925 DEBUG 22308 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : No match for [application/json, text/plain, */*], supported: []
2019-06-02 21:20:33.926 DEBUG 22308 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session (through reference chain: org.springframework.data.domain.PageImpl["content"]->java.util.Collections$UnmodifiableRandomAccessList[0]->nl.xxxx.events.Event["schedule"])]
2019-06-02 21:20:33.926 DEBUG 22308 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 500 INTERNAL_SERVER_ERROR
So, at some point it just says No match for [application/json, text/plain, */*], supported: [] and wont return a nice JSON exception anymore.
Any ideas at what i'm doing wrong? initially is just want EventNotFoundException to result in a 404 instead of a 500. Propably in the future i'd like to add content aswell.
The problem is that you try to handle RuntimeException which is too general. public void handlePersonNotFound(RuntimeException ex) You also don't need to extend from ResponseEntityExceptionHandler.
If you write an ExceptionHandler that should handle a specific exception, the handleException method needs to accept that specific exception as parameter. Also you would probably want some sort of repsonse.
#ControllerAdvice
public class EventExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(getClass());
#ResponseBody
#ResponseStatus(HttpStatus.NOT_FOUND)
#ExceptionHandler(EventNotFoundException.class)
public String handlePersonNotFound(EventNotFoundException ex) {
logger.error("error", ex);
return ex.getMessage();
}
}
This will give a basic reponse body with the exception message and error code.

Spring Rest Controller method not invoked with path variable and http request as arguments

This is my controller method
#RestController
public class ProfileController {
#GetMapping("/quiz/{quizId}/identifyfromsixjson")
#ResponseBody
UserProfileQuestion playIdentifyFromSix(#PathVariable String quizId, HttpServletRequest request) {
... Calling service method ... here
}
}
application.properties
server.contextPath=/myproject
spring.h2.console.enabled=true
spring.jpa.hibernate.ddl-auto=update
So when I make a GET request to http://localhost:8080/myproject/identifyfromsixjson/test, this is the response I see in Postman.
{
"timestamp": "2018-10-08T02:42:14.387+0000",
"status": 405,
"error": "Method Not Allowed",
"message": "Request method 'GET' not supported",
"path": "/myproject/quiz/test/identifyfromsixjson"
}
Startup logs
018-10-08 01:59:32.603 WARN 46035 --- [ main] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2018-10-08 01:59:32.641 INFO 46035 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/quiz/{quizId}/identifyfromsixjson]}" onto public org.springframework.http.ResponseEntity<com.myproject.model.UserProfileQuestion> com.myproject.controller.ProfileController.fetchUserProfileAndHeadShot(java.lang.String,javax.servlet.http.HttpServletRequest)
2018-10-08 01:59:32.644 INFO 46035 --- [ 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-10-08 01:59:32.644 INFO 46035 --- [ 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-10-08 01:59:32.672 INFO 46035 --- [ main] o.s.w.s.h.BeanNameUrlHandlerMapping : Mapped URL path [/myproject] onto handler '/myproject'
2018-10-08 01:59:32.678 INFO 46035 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-10-08 01:59:32.678 INFO 46035 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
What am I doing wrong?
This is the path you've defined:
/quiz/{quizId}/identifyfromsixjson
and this is the path you're testing with
/identifyfromsixjson/test
It should be apparent that they don't match, which is why you're getting that error.
You can do the following:
1. Test with the path that you've defined:
http://localhost:8080/myproject/quiz/test/identifyfromsixjson
2. Update your path definition
#GetMapping("/identifyfromsixjson/{quizId}")
#ResponseBody
UserProfileQuestion playIdentifyFromSix(#PathVariable String quizId,HttpServletRequest request) {
... Calling service method ... here
}
and then test with
http://localhost:8080/myproject/identifyfromsixjson/test
Looks like you want to write a RestController. Annotate your controller with #RestController
#RestController
public class QuizController {
#GetMapping("/identifyfromsixjson/{quizId}")
#ResponseBody
UserProfileQuestion playIdentifyFromSix(#PathVariable String quizId, HttpServletRequest request) {
... Calling service method ... here
}
}

Spring filters cannot see status codes for requests to static pages

I'm running a Spring Boot Web MVC app which has some pages handled by controllers, and others (static content) configured using a ResourceHandler. I've got my own error handling for the controller methods. I'm running it under standalone Tomcat.
I want to log every HTTP request and its response, and the HTTP status codes of the responses. Using Tomcat access logs isn't an option because there is a context for each request (client has an active session) and I want to correlate sessions with pages requested.
I've tried logging using both filters and interceptors. The problem is that I can't make interceptors see any requests to static resources - I think they only work for pages that are handled by controllers - and the filters will log requests to static resources but they always log the response as 200, even when it's a 404. I haven't got my own default error page set up (and I'm not that interested in setting one, I just need to set the status) so when I request a static resource that doesn't exist I'll see something like this in my logs:
2015-03-26 16:02:46.770 INFO 26576 --- [http-bio-8080-exec-3] a.c.u.app.config.RequestLoggingFilter : CONTEXT=unknown; Type=request; Method=GET; resource=/resources/missing.html
2015-03-26 16:02:46.770 INFO 26576 --- [http-bio-8080-exec-3] a.c.u.app.config.RequestLoggingFilter : CONTEXT=unknown; Type=response; Status=200; Length=unknown; resource=/resources/missing.html
2015-03-26 16:02:46.788 INFO 26576 --- [http-bio-8080-exec-3] a.c.u.app.config.RequestLoggingFilter : CONTEXT=unknown; Type=request; Method=GET; resource=/error
2015-03-26 16:02:46.788 INFO 26576 --- [http-bio-8080-exec-3] a.c.u.app.config.RequestLoggingFilter : CONTEXT=unknown; Type=response; Status=404; Length=unknown; resource=/error
2015-03-26 16:02:46.811 INFO 26576 --- [http-bio-8080-exec-3] a.c.u.a.c.RequestLoggingInterceptor : CONTEXT=unknown; Type=request; Method=GET; resource=/error
2015-03-26 16:02:46.839 INFO 26576 --- [http-bio-8080-exec-3] a.c.u.a.c.RequestLoggingInterceptor : CONTEXT=unknown; Type=response; Status=404; Length=unknown; resource=/error
As you can see, only the filter picks up any request/response for a static resource, but both filter and interceptor later pick up the request and response for my missing /error page.
Note that I have this issue, but as far as I know it's only affecting DeferredResults - it shouldn't be affecting the appearance of the status in the filter chain for a static page request.
How can I log the real response status for requests to missing static resources? I don't really mind how this is accomplished - through filters or using interceptors or by overriding the controller for /error.
Here's my AppConfiguration which adds the static resource handlers and the interceptors:
#Configuration
#EnableConfigurationProperties
#EnableWebMvc
public class AppConfiguration extends WebMvcConfigurerAdapter {
#Autowired
private MyAppProperties properties;
#Autowired
SessionDataArgumentResolver sessionDataArgumentResolver;
// Serve up static files directly from the external directory
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations(
properties.getExternalDirectoryURI("resources/").toString()).setCachePeriod(
properties.getCacheControlMaxAge());
// At least after the controller registry
registry.setOrder(10);
}
#Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(sessionDataArgumentResolver);
}
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new RequestLoggingInterceptor());
}
}
I ended up posting an issue on Github: https://github.com/spring-projects/spring-boot/issues/2817
The answer was embarrassingly simple: I needed to log the response status after invoking filterChain.doFilter:
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
filterChain.doFilter(request, response);
LOGGER.info("HTTP request for resource {} - status {}", request.getRequestURI(), response.getStatus());
}
It works perfectly after doing that.

Springmvc #Scheduled cron or fixedrate not firing

I am using all annotated version of springmvc and I have a class where I have scheduled a method to be run every 5 seconds. However, it doesnt seem to be firing.
I have created a package to be scanned when the app fires up and I have declared the class in the following way:
#Configuration
#ComponentScan("com.iautomation")
#EnableWebMvc
#EnableTransactionManagement
#PropertySource("classpath:application.properties")
public class WebAppConfig extends WebMvcConfigurerAdapter {
My class and cron:
#Component
public class DemoServiceBasicUsageCron {
//#Scheduled(cron="*/1 * * * * ?")
#Scheduled(fixedRate=5000)
public void demoServiceMethod()
{
System.out.println("\n\n\n\n");
System.out.println("Method executed at every 5 seconds. Current time is :: ");
System.out.println("\n\n\n\n");
}
}
The package is scanned when the app starts:
DEBUG DefaultListableBeanFactory:463 - Finished creating instance of bean 'demoServiceBasicUsageCron'
and another debug log:
DEBUG BeanNameUrlHandlerMapping:86 - Rejected bean name 'demoServiceBasicUsageCron': no URL paths identified
When I load the app in eclipse I dont see anything in the console.
You have to annotate your Configuration class with #EnableScheduling

Resources