HK2 does not see Spring Beans - spring

I have a Spring Boot application with Jersey 2 REST services.
Spring Boot seems to initialize correctly and I have Jersey Spring bridge ('org.glassfish.jersey.ext:jersey-spring3:2.22.2').
Despite this the following error is thrown then REST controller (JAX-RS 2.0) is initialized and a Spring Bean have to be injected into it.
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection
What can cause such error?
The bean is exist and annotated with #Named, so it is not the issue. Spring Boot by default scans for JSR-330 annotations too.
Edit:
initialization is done using:
#SpringBootApplication
public class Application extends SpringBootServletInitializer implements WebApplicationInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
Stacktrace:
DEBUG o.glassfish.jersey.server.ServerRuntime$Responder - An exception mapping did not successfully produce and processed a response. Logging the exception propagated to the container.
org.glassfish.hk2.api.MultiException: A MultiException has 3 exceptions. They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=RequestEndEventLogger,parent=RequestEndEventController,qualifiers={},position=-1,optional=false,self=false,unqualified=null,125747480)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of com.company.controller.RequestEndEventController errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on com.company.controller.RequestEndEventController
at org.jvnet.hk2.internal.Collector.throwIfErrors(Collector.java:89)
at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:249)
at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:357)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
at org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:83)
at org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:71)
at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture$1.call(Cache.java:97)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture.run(Cache.java:154)
at org.glassfish.hk2.utilities.cache.Cache.compute(Cache.java:199)
at org.jvnet.hk2.internal.SingletonContext.findOrCreate(SingletonContext.java:122)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2022)
at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:765)
at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:704)
at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:172)
at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:284)
at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:109)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:92)
at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:61)
at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:318)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154)
at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:473)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:341)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:228)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:120)
at org.springframework.boot.context.web.ErrorPageFilter.access$000(ErrorPageFilter.java:61)
at org.springframework.boot.context.web.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:95)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:113)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2500)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2489)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=RequestEndEventLogger,parent=RequestEndEventController,qualifiers={},position=-1,optional=false,self=false,unqualified=null,125747480)
at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:75)
at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:211)
at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:234)
... 80 common frames omitted
The controller is:
#Named
#Singleton
#Path("/RequestEndEvent")
public class RequestEndEventController {
private final Logger log = LoggerFactory.getLogger(getClass());
#Inject
private RequestEndEventLogger logger;
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response sendRequestEndEvent(RequestEndEvent requestEndEvent) {
logger.addRequestEndEvent(requestEndEvent);
return Response.status(Response.Status.OK).build();
}
}

The actual problem was something discovered in the comments (it was not shown in the original question).
With #SpringBootApplication (an alias for three annotations, including #ComponentScan), you get free component scan with Spring. But how component scan works (with out specifying packages to scan) is that it will scan the package of the #ComponentScan annotated class, and it's sub-packages. For this reason, it is recommended to put the "application" class in a root package, and have all the other packages as sub-packages of that package, e.g
com.app
Application
com.app.services
LoggingService
com.app.repos
UserRepo
With this set up, all the packages get scanned for annotated components classes. I guess the OP did not have it set up this way, so the Spring components weren't getting picked up in the scan.

Related

Autowired not working, dependency is null

The project that I have is currently set up like so:
Controller:
package com.frclocks.district.controller;
:imports:
#Path("/districts")
#Controller
public class DistrictController {
#Autowired
private DistrictService districtService;
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<District> getDistricts() {
return districtService.getAllDistricts();
}
}
Service (Impl):
package com.frclocks.district.service;
:imports:
#Service("districtService")
#Transactional
public class DistrictServiceImpl implements DistrictService {
#Autowired
private DistrictDao districtDao;
#Override
public List<District> getAllDistricts() {
return districtDao.getAllDistricts();
}
}
Config:
package com.frclocks.config;
:imports:
#Configuration
#ComponentScan(basePackages="com.frclocks", includeFilters=#ComponentScan.Filter(Controller.class))
public class AppConfig { }
The web.xml is empty as I'll be using JavaConfig instead of xml, nor do I have any spring config xml. I have read through several tutorials online, several threads on here, and even browsed through a project at work that I'm developing with which also uses #Autowired and have reached a brick wall. Some of the tutorials say to do something in a main class (such as here: Spring Docs) but the project at work doesn't do anything like that. It has a similar AppConfig (with a few additional, not necessary annotations for me) and no xml config files. What would I be doing wrong? What am I missing here? Thanks!
EDIT: Stack trace for the null:
SEVERE: Servlet.service() for servlet
[com.frclocks.config.FRCLocksApplication] in context with path
[/frclocks] threw exception
org.jboss.resteasy.spi.UnhandledException: java.lang.NullPointerException
at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:78)
at org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:222)
at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:195)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:457)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:231)
at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:137)
at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:361)
at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:140)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:217)
at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:227)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:650)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at com.frclocks.district.controller.DistrictController.getDistricts(DistrictController.java:27)
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:498)
at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:140)
at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:511)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:402)
at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$0(ResourceMethodInvoker.java:366)
at org.jboss.resteasy.core.interception.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:361)
at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:368)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:340)
at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:313)
at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:441)
... 31 more
You have mixed RestEasy and Spring MVC. You should decide for either of those frameworks for your REST endpoints. #Controller is a Spring annotation, while #Path is a JAX-RS annotation. Both together don't work. Currently your Controller is called through RestEasy, which doesn't know anything about your Spring configuration.

Thymeleaf exception resolving template for REST Endpoint using Spring Data Rest + Spring Security

I have setup REST endpoints previously without issue but I am now creating a new endpoint in my spring application and I have recently introduced spring security. This is the first custom endpoint in the application with security.
Rest Endpoint - RequestMapping
#RequestMapping(value = "setUserPassword", method = RequestMethod.POST)
public void setUserPassword(#RequestBody String jsonObject) throws Exception {
System.out.println("In endpoint");
}
I can send a HTTP POST to the endpoint and have the output print but then I get an exception. I can only assume this has to do with adding spring security as I have not had issues in the other spring data rest project which does not have spring security.
Question
What am I missing when configuring new REST endpoints when Spring Security is enabled?
SecurityConfiguration
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired
private SpringDataJpaUserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(this.userDetailsService)
.passwordEncoder(MCBPasswordEncoder.PASSWORD_ENCODER);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/built/**", "/main.css").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/", true)
.permitAll()
.and()
.httpBasic()
.and()
.csrf().and() // TODO enable for production
.logout()
.logoutSuccessUrl("/");
}
Exception
2016-06-01 16:34:16 - [THYMELEAF][http-nio-8081-exec-1] Exception processing template "setUserPassword": Error resolving template "setUserPassword", template might not exist or might not be accessible by any of the configured Template Resolvers
2016-06-01 16:34:16 - Servlet.service() for servlet [dispatcherServlet] in context with path [/api] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template "setUserPassword", template might not exist or might not be accessible by any of the configured Template Resolvers] with root cause
org.thymeleaf.exceptions.TemplateInputException: Error resolving template "setUserPassword", template might not exist or might not be accessible by any of the configured Template Resolvers
at org.thymeleaf.TemplateRepository.getTemplate(TemplateRepository.java:246)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1104)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1060)
at org.thymeleaf.TemplateEngine.process(TemplateEngine.java:1011)
at org.thymeleaf.spring4.view.ThymeleafView.renderFragment(ThymeleafView.java:335)
at org.thymeleaf.spring4.view.ThymeleafView.render(ThymeleafView.java:190)
at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1243)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1027)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:971)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:968)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:870)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:844)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:213)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:162)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Solution
Adding the correct #RequestBody to the #Controller
#RequestBody Map<String, Object> payload
I think your problem is not related to the Spring Security configuration but to your controller method instead.
In the exception you are getting when calling the method it says it is trying to find the Thymeleaf response view related to your method. Your method doesn't return any view name, so Spring MVC is trying to find a Thymeleaf view with the same name as the method name.
Add a #ResponseBody annotation to the method and a produces = MediaType.APPLICATION_JSON_VALUE to the RequestMapping annotation to narrow the supported media types.
Also you'll have to handle the response, returning and object or by yourself. Take a look at the Supported Method Return Types

Spring Social Facebook UncategorizedApiException: (#3) Application does not have the capability to make this API call

I have developed a simple web application that accesses Facebook data through Spring Boot (v1.2.6.RELEASE) and Spring Social Facebook (v2.0.2.RELEASE) similar to the example given here
I have created a new App in Facebook which use Graph API version 2.5.
According to this example i have modified facebookConnect.html putting this different scope to the method POST request:
<html>
<head>
<title>Facebook Extractor</title>
</head>
<body>
<h3>Connect to Facebook</h3>
<form action="/recommender/connect/facebook" method="POST">
<input type="hidden" name="scope" value="public_profile, user_friends, email, user_likes" />
<div class="formInfo">
<p>You aren't connected to Facebook yet. Click the button to connect this application with your Facebook account.</p>
</div>
<p><button type="submit">Connect to Facebook</button></p>
</form>
</body>
handled by ConnectController which kick off the OAuth authorization code flow...
After OAuth success (with permission granted) and connection is done, i get the following error:
(#3) application does not have the capability to make this api call.
Here the main part of the controller which handle the redirect from Facebook App:
#Controller
#Scope(value="session")
public class FacebookExtractor {
private Logger logger = Logger.getLogger(FacebookExtractor.class);
private Facebook facebook;
#Autowired
GraphDatabase graphDatabase;
#Autowired
PersonRepository personRepository;
#Autowired
UserProfileRepository userProfileRepository;
#Autowired
AttributeDefinitionRepository attributeDefinitionRepository;
#Autowired
AttributeRepository attributeRepository;
#Autowired
ConceptRepository conceptRepository;
#Autowired
RecommenderGovConsumerRepository recGovRepository;
#Autowired
GovConsumerInfluencedByGovConsumerRelationshipRepository influenceRepository;
#Autowired
ExtractorListener listener;
private String userBind;
#Inject
public FacebookExtractor(Facebook facebook) {
this.facebook = facebook;
}
#RequestMapping(method = RequestMethod.GET, value = "/facebookExtractor")
public ModelAndView FacebookDataUserExtraction() {
if (!facebook.isAuthorized()) {
return new ModelAndView("redirect:/recommender/connect/facebook");
}
String account=userBind;
Long netId = null;
Transaction tx = graphDatabase.beginTx();
try {
User user = facebook.userOperations().getUserProfile();
Person p = savePerson(user);
UserProfile up = saveUserProfile(user);
up.setUser(p);
userProfileRepository.save(up);
p.setProfile(up);
saveSocialInteractions(up);
saveSocialPreferences(up);
personRepository.save(p);
netId=p.getId();
tx.success();
} finally {
tx.close();
}
if (account != null) {
/*
* Binding di Facebook riuscito.
*/
listener.onProfileDataCompleted(netId, SNAccountType.Facebook);
listener.onInteractionsCompleted(netId, InteractionType.Friendship, SNAccountType.Facebook);
return new ModelAndView("redirect:http://localhost:8080/portal",
"accountF", account);
} else {
//vista opportuna per estrazione avvenuta senza bind
return new ModelAndView("facebookNoBindExtraction");
}
}
Watching the stack trace error, seems i'm getting error at this line in controller:
User user = facebook.userOperations().getUserProfile();
but it is strange because I should have permission to get basic user profile data by default.
Note: the same code with an older App in Facebook which use Graph API version 2.3 works perfectly, but i need a new one for different purpose and can't force a new App in Facebook to use that version...
Here the stack error i get....
12:01:16.953 [http-nio-9080-exec-5] ERROR
o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet
[dispatcherServlet] in context with path [] threw exception [Request
processing failed; nested exception is
org.springframework.social.UncategorizedApiException: (#3) Application
does not have the capability to make this API call.] with root cause
org.springframework.social.UncategorizedApiException: (#3) Application
does not have the capability to make this API call. at
org.springframework.social.facebook.api.impl.FacebookErrorHandler.handleFacebookError(FacebookErrorHandler.java:91)
~[spring-social-facebook-2.0.2.RELEASE.jar:2.0.2.RELEASE] at
org.springframework.social.facebook.api.impl.FacebookErrorHandler.handleError(FacebookErrorHandler.java:59)
~[spring-social-facebook-2.0.2.RELEASE.jar:2.0.2.RELEASE] at
org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:614)
~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:570)
~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.web.client.RestTemplate.execute(RestTemplate.java:545)
~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:253)
~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.social.facebook.api.impl.FacebookTemplate.fetchObject(FacebookTemplate.java:214)
~[spring-social-facebook-2.0.2.RELEASE.jar:2.0.2.RELEASE] at
org.springframework.social.facebook.api.impl.FacebookTemplate.fetchObject(FacebookTemplate.java:209)
~[spring-social-facebook-2.0.2.RELEASE.jar:2.0.2.RELEASE] at
org.springframework.social.facebook.api.impl.UserTemplate.getUserProfile(UserTemplate.java:53)
~[spring-social-facebook-2.0.2.RELEASE.jar:2.0.2.RELEASE] at
org.springframework.social.facebook.api.impl.UserTemplate.getUserProfile(UserTemplate.java:49)
~[spring-social-facebook-2.0.2.RELEASE.jar:2.0.2.RELEASE] at
it.cerict.recommender.extractor.controllers.FacebookExtractor.FacebookDataUserExtraction(FacebookExtractor.java:89)
~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
Method) ~[na:1.8.0_60] at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
~[na:1.8.0_60] at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
~[na:1.8.0_60] at java.lang.reflect.Method.invoke(Method.java:497)
~[na:1.8.0_60] at
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858)
~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
~[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
~[spring-webmvc-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
~[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
~[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
~[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
~[tomcat-embed-websocket-8.0.26.jar:8.0.26] at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
~[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
~[tomcat-embed-core-8.0.26.jar:8.0.26] at
it.cerict.recommender.config.CORSFilter.doFilter(CORSFilter.java:22)
~[classes/:na] at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
~[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
~[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
~[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
~[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE] at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
~[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
~[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
~[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1526)
[tomcat-embed-core-8.0.26.jar:8.0.26] at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1482)
[tomcat-embed-core-8.0.26.jar:8.0.26] at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[na:1.8.0_60] at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[na:1.8.0_60] at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
[tomcat-embed-core-8.0.26.jar:8.0.26] at
java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]
The problem is with PROFILE_FILEDS in
public User getUserProfile(String facebookId) {
return graphApi.fetchObject(facebookId, User.class, PROFILE_FIELDS);
}
Array PROFILE_FIELDS contains many many fields and as I understang correctly spring-social docs, Facebook returned only this fields you have rights to view.
But now something changed:
$curl "https://graph.facebook.com/v2.5/me?access_token=[access_tokens]&fields=[all_the_fields_from_PROFILE_FIELDS]
{"error":{"message":"(#3) Application does not have the capability to make this API call.","type":"OAuthException","code":3,"fbtrace_id":"Antivssjj1d"}}
$ curl "https://graph.facebook.com/v2.3/me?access_token=[access_token]&fields=id,about"
{"id":"1135898619755433"}
In the meantime I've found sollution. Instead
User profile = facebook.userOperations().getUserProfile()
we can use
User profile = facebook.fetchObject("me", User.class, "id", "name", "link", "email");
//Note: facebook = org.springframework.social.facebook.api.Facebook
//Note: User.class = org.springframework.social.facebook.api.User.class
Or wait the update of spring-social-facebook, there is a pull request pending on the repository: https://github.com/spring-projects/spring-social-facebook/pull/171
UPDATE: Fix for me with the 2.0.3.RELEASE version.
I continued to get this error, even after adding the publish_actions scope that my app needed. The issue in my case was that I needed Facebook to review my app. This is the case if your app was created after April 30th, 2014 and one or more of the following is true:
You want your App to be listed in the Facebook App Center
You want to create new, or edit existing, Open Graph actions and stories
Your app asks people for any extended permissions including publish_actions
Have a look at the Facebook Login Review FAQs for more info on the review process.

Spring boot and #SessionAttributes

I'm working on an app with Spring Boot 1.2.5 RELEASE and having a problem that's difficult to replicate, and seems to be related to my session. Doing lots of research indicates that when using the #SessionAttribute annotation my session will end when my web page accesses another controller. Although I also found some information that indicates this is no longer true with the most recent Spring Boot. Also, the other controller does not use the same template or session identifier as this controller.
Alternatively I think my session may be expiring, but I can't seem to find any information talking about a default time out.
The app is straightforward, just a web page to edit form data. Sometimes when the save button is clicked an exception is thrown saying something to the effect that "adminForm" is not valid model data. I'm sorry I have been unable to replicate the exception and had not saved it.
The code is below, thanks in advance for your comments.
#SessionAttributes("adminForm")
#Controller
public class Admin_FormController
{
final static protected long INDEX_RA = 1L;
#Autowired
private AdminDataRepository rep;
#RequestMapping(value="/admin", method=RequestMethod.GET)
public String adminForm(Model model)
{
AdminData ad = rep.findById(INDEX_RA);
// If there is no configuration record, create one and assign the primary key
if(ad == null)
{
ad = new AdminData();
ad.setId(INDEX_RA);
}
model.addAttribute("adminForm", ad);
return "adminForm";
}
#RequestMapping(value="/admin", method=RequestMethod.POST)
public #ResponseBody AdminData adminSubmit(#ModelAttribute("adminForm") AdminData ad, Model model)
{
rep.save(ad);
model.addAttribute("adminForm", ad);
return ad;
}
}
UPDATE:
Here is the exception that is thrown:
2015-07-28 11:12:16.564 ERROR 52963 --- [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Expected session attribute 'adminForm'] with root cause
org.springframework.web.HttpSessionRequiredException: Expected session attribute 'adminForm'
at org.springframework.web.method.annotation.ModelFactory.initModel(ModelFactory.java:115)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:753)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
I was able to solve this problem by specifying that the session should never time out. This is fine in our case since this app is secured behind a single sign on appl. Here is what I added to the application.properties file:
server.session-timeout=-1

Spring 4 - Autowire Generic

I create an generic interface CRUDService to generate multiple entity service classes with all implement the same CRUD Methods.
interface CRUDService<T> {
public abstract T saveEntity(T entity)
public abstract T getEntity(T entity)
public abstract long getCount()
}
Then I implemented from my entity Hypervisor an service class HypervisorService which implements my CRUDService
#Service
class HypervisorService implements CRUDService<Hypervisor> {
#Autowired
private HypervisorRepository hypervisorRepository
#Override
#Transactional
public Hypervisor saveEntity(Hypervisor entity) {
return hypervisorRepository.saveAndFlush(entity)
}
#Override
public Hypervisor getEntity(Hypervisor entity) {
return hypervisorRepository.findOne(entity.getId())
}
#Override
public long getCount() {
return hypervisorRepository.count()
}
}
But when i try to autowire it with
#Autowired
private CRUDService<Hypervisor> hypervisorService
I got an "java.lang.ClassCastException: com.sun.proxy.$Proxy68 cannot be cast to net.ifis.ites.hermes.services.HypervisorService" exception.
I don't understand why Spring sayes it has an classcastexception but when i changed my Service code to
#Service
class HypervisorService<Hypervisor> implements CRUDService<Hypervisor> {
...
}
My code works and i can use my generic interface but i don't think this is a good practice to use it.
Stack Trace :
java.lang.ClassCastException: com.sun.proxy.$Proxy68 cannot be cast to net.ifis.ites.hermes.services.HypervisorService
at net.ifis.ites.hermes.services.HypervisorService$saveEntity.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:110)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:122)
at net.ifis.ites.hermes.ui.MyVaadinUI.init(MyVaadinUI.groovy:38)
at com.vaadin.ui.UI.doInit(UI.java:646)
at net.ifis.ites.hermes.ui.MyVaadinUI.doInit(MyVaadinUI.groovy)
at com.vaadin.server.communication.UIInitHandler.getBrowserDetailsUI(UIInitHandler.java:214)
at com.vaadin.server.communication.UIInitHandler.synchronizedHandleRequest(UIInitHandler.java:74)
at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1408)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:350)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:721)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:466)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:358)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:318)
at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:128)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:146)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:50)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
In my VaadinUI i autowire only my service class and generate an hypervisor and try to save it to my database and visualize the current database counts from all hypervisors as an label.
#Component
#SpringUI
class MyVaadinUI extends UI {
#Autowired
private CRUDService<Hypervisor> hypervisorService
#Override
protected void init(VaadinRequest vaadinRequest) {
VerticalLayout layout = new VerticalLayout()
Hypervisor hypervisor = hypervisorService.saveEntity(new Hypervisor("KVM"))
layout.addComponent(new Label("Hypervisors : " + hypervisorService.getCount()))
setContent(layout)
}
}
I will try to use CGLIB for my application now.
I use in my configuration
#EnableAspectJAutoProxy(proxyTargetClass=true) and now my code works with
class HypervisorService implements CRUDService<Hypervisor> {
...
}

Resources