NullPointer with #Autowire HttpServletRequest - java

I have the following code:
package com.example.helloworld;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.annotation.RequestScope;
#RestController
public class HelloWorldController {
#GetMapping("/")
public ResponseEntity<String> getGet(
#Autowired Foo foo) {
foo.sayHi();
return new ResponseEntity<>("OK", HttpStatus.OK);
}
}
#Component
#RequestScope
class Foo {
private #Autowired HttpServletRequest request;
public void sayHi() {
var name = this.request.getHeader("x-user-name");
System.out.println("Hi " + name);
}
}
When I try to curl with curl -H x-user-name:capybara http://localhost:8080, the following error is produced:
2022-09-09 17:07:28.623 ERROR 26350 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException: Cannot invoke "javax.servlet.http.HttpServletRequest.getHeader(String)" because "this.request" is null] with root cause
java.lang.NullPointerException: Cannot invoke "javax.servlet.http.HttpServletRequest.getHeader(String)" because "this.request" is null
at com.example.helloworld.Foo.sayHi(HelloWorldController.java:32) ~[classes!/:0.0.1-SNAPSHOT]
at com.example.helloworld.HelloWorldController.getGet(HelloWorldController.java:19) ~[classes!/:0.0.1-SNAPSHOT]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:577) ~[na:na]
at
...
Why is this.request null? Giving the popularity of https://stackoverflow.com/a/3324233/2287586, seems like this should work, what am I missing?

It doesn't work becuse it needs to be a Singleton bean and you have #RequestScope.
Maybe try this:
((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();

Related

Stack overflow calling Spring authenticationManager.authenticate

I started with a spring boot starter project version 2.3.5, but when I call authenticationManager.authenticate I get a stack overflow error.
java.lang.StackOverflowError: null
at ch.qos.logback.classic.Logger.callTurboFilters(Logger.java:751) ~[logback-classic-1.2.3.jar:na]
at ch.qos.logback.classic.Logger.isDebugEnabled(Logger.java:469) ~[logback-classic-1.2.3.jar:na]
at ch.qos.logback.classic.Logger.isDebugEnabled(Logger.java:465) ~[logback-classic-1.2.3.jar:na]
at org.apache.commons.logging.LogAdapter$Slf4jLog.isDebugEnabled(LogAdapter.java:310) ~[spring-jcl-5.2.10.RELEASE.jar:5.2.10.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:186) ~[spring-security-core-5.3.5.RELEASE.jar:5.3.5.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:524) ~[spring-security-config-5.3.5.RELEASE.jar:5.3.5.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:219) ~[spring-security-core-5.3.5.RELEASE.jar:5.3.5.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:524) ~[spring-security-config-5.3.5.RELEASE.jar:5.3.5.RELEASE]
Initially I did not use the user variable and instead created created the new UsernamePasswordAuthenticationToken inside the authenticationManager.authenticate either way I get the stack overflow error. I also have tried #PostMapping instead of #RequestMapping and Method. All of these cause the same failure.
I get the printline that says I am "in /Authenticate" with the following.
2020-11-09 16:20:32.141 DEBUG 10456 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to io.javabrains.springsecurityjwt.HelloResource#createAuthenticationToken(AuthenticationRequest)
2020-11-09 16:20:32.188 DEBUG 10456 --- [nio-8080-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Read "application/json;charset=UTF-8" to [io.javabrains.springsecurityjwt.models.AuthenticationRequest#758a32c5]
in /Authenticate
2020-11-09 16:20:32.197 DEBUG 10456 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Failed to complete request: org.springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.StackOverflowError
2020-11-09 16:20:32.201 ERROR 10456 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause
Here is the full code of the Class
Thank you for any info or things I should try!
package io.javabrains.springsecurityjwt;
import io.javabrains.springsecurityjwt.models.AuthenticationRequest;
import io.javabrains.springsecurityjwt.models.AuthenticationResponse;
import io.javabrains.springsecurityjwt.services.MyUserDetailsService;
import io.javabrains.springsecurityjwt.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class HelloResource {
#Autowired
private AuthenticationManager authenticationManager;
#Autowired
private MyUserDetailsService userDetailsService;
#Autowired
private JwtUtil jwtTokenUtil;
#RequestMapping( "/hello")
public String hello() {
return "Hello World";
}
#RequestMapping(value = "/authenticate", method = RequestMethod.POST)
public ResponseEntity<?> createAuthenticationToken(#RequestBody AuthenticationRequest authenticationRequest) throws Exception {
UsernamePasswordAuthenticationToken user = new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword());
System.out.println("in /Authenticate");
try {
authenticationManager.authenticate(
user
// new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword())
);
System.out.println("in Try in /Authenticate");
} catch (BadCredentialsException e) {
throw new Exception("Incorrect Username or Password", e);
}
System.out.println("outside the try catch");
final UserDetails userDetails = userDetailsService
.loadUserByUsername(authenticationRequest.getUsername());
final String jwt = jwtTokenUtil.generateToken(userDetails);
return ResponseEntity.ok(new AuthenticationResponse(jwt));
}
}

java.lang.NullPointerException while calling from controller

My Spring Boot program is compiling without any issues, but whenever I click the registration link it throws NullPointerException error. I am really at a loss as to what may be causing this. Given below is the error:-
java.lang.NullPointerException: null
at com.concretepage.controller.UserInfoController.registration(UserInfoController.java:32) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_171]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_171]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_171]
at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_171]
The UserinfoController class is given below:-
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.concretepage.entity.ProjectLevel;
import com.concretepage.service.LevelService;
import com.concretepage.service.UserInfoService;
#Controller
#RequestMapping("app")
public class UserInfoController {
#Autowired
private UserInfoService userInfoService;
private LevelService levelService;
#GetMapping("login")
public ModelAndView login() {
ModelAndView mav = new ModelAndView();
mav.setViewName("custom-login");
return mav;
}
#GetMapping("registration")
public ModelAndView registration() {
ModelAndView mav = new ModelAndView();
List<ProjectLevel> levels = levelService.getAllLevels();
mav.addObject("Levels", levels);
mav.setViewName("registration");
return mav;
}
#GetMapping("secure/project-details")
public ModelAndView getAllUserProjects() {
ModelAndView mav = new ModelAndView();
mav.addObject("userProjects", userInfoService.getAllUserProjects());
mav.setViewName("projects");
return mav;
}
Error is at the line -
List<ProjectLevel> levels = levelService.getAllLevels();
The LevelServiceImpl class is as below:-
package com.concretepage.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.concretepage.entity.ProjectLevel;
import com.concretepage.repositories.LevelRepository;
#Service
public class LevelServiceImpl implements LevelService {
#Autowired
private LevelRepository levelRepository;
#Override
public List<ProjectLevel> getAllLevels() {
List<ProjectLevel> levelList = levelRepository.findAll();
return levelList;
}
}
Just change this piece of code:
#Autowired
private UserInfoService userInfoService;
private LevelService levelService;
to
#Autowired
private UserInfoService userInfoService;
#Autowired
private LevelService levelService;
You must use separate #Autowired for private LevelService levelService;

After adding elasticsearch support, Spring Boot complain BeanCreationException with nested IllegalStateException No association found

I have run into a strange problem. I created a project with Spring Boot 2.0.1 with redis, mongodb and elasticsearch . Before adding elasticsearch, everything runs smoothly, but after I add elasticsearch, Spring Boot starts complaining,but the error looks like not related to elasticsearch, it complains that it could not create userRepo 。 Please get noticed I used lombok's #RequiredArgsConstructor to generate constructor to make injection work, so it should not be #autowired issue, Anyone can help me out? thank in adavance
2018-05-02 16:12:58.687 INFO 74244 --- [ restartedMain] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/]
2018-05-02 16:12:59.037 WARN 74244 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig' defined in file [/Users/wangpeng/workspace/books/gtm/backend/api/out/production/classes/dev/local/gtm/api/config/SecurityConfig.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userDetailsServiceImpl' defined in file [/Users/wangpeng/workspace/books/gtm/backend/api/out/production/classes/dev/local/gtm/api/security/UserDetailsServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepo': Invocation of init method failed; nested exception is java.lang.IllegalStateException: No association found!
2018-05-02 16:12:59.037 DEBUG 74244 --- [ restartedMain] h.i.c.PoolingHttpClientConnectionManager : Connection manager is shutting down
2018-05-02 16:12:59.037 DEBUG 74244 --- [ restartedMain] h.i.c.PoolingHttpClientConnectionManager : Connection manager shut down
Process finished with exit code 1
my subproject's build.gradle is as follows:
apply plugin: 'org.springframework.boot'
configurations {
compile.exclude module: 'spring-boot-starter-tomcat'
}
bootRun {
systemProperties = System.properties as Map<String, ?>
}
test {
systemProperties['spring.profiles.active'] = 'test'
}
dependencies {
implementation("io.springfox:springfox-swagger2:${springFoxVersion}")
implementation("io.springfox:springfox-bean-validators:${springFoxVersion}")
implementation("io.springfox:springfox-swagger-ui:${springFoxVersion}")
implementation("org.springframework.boot:spring-boot-starter-undertow")
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("io.jsonwebtoken:jjwt:0.9.0")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-aop")
implementation("org.zalando:problem-spring-web:0.20.1")
implementation("org.redisson:redisson:${redissonVersion}")
implementation("com.fasterxml.jackson.module:jackson-module-afterburner")
implementation("org.springframework.boot:spring-boot-starter-data-mongodb")
implementation("org.springframework.boot:spring-boot-starter-data-redis")
implementation("com.github.vanroy:spring-boot-starter-data-jest:3.1.2.RELEASE")
testImplementation("org.springframework.security:spring-security-test")
}
The UserRepo is as follows
package dev.local.gtm.api.repository;
import dev.local.gtm.api.domain.User;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
#Repository
public interface UserRepo extends MongoRepository<User, String> {
String USERS_BY_LOGIN_CACHE = "usersByLogin";
String USERS_BY_MOBILE_CACHE = "usersByMobile";
String USERS_BY_EMAIL_CACHE = "usersByEmail";
#Cacheable(cacheNames = USERS_BY_MOBILE_CACHE)
Optional<User> findOneByMobile(#Param("mobile") String mobile);
#Cacheable(cacheNames = USERS_BY_EMAIL_CACHE)
Optional<User> findOneByEmailIgnoreCase(#Param("email") String email);
#Cacheable(cacheNames = USERS_BY_LOGIN_CACHE)
Optional<User> findOneByLogin(#Param("login") String login);
Page<User> findAllByLoginNot(Pageable pageable, #Param("login") String login);
List<User> findAllByActivatedIsFalseAndCreatedDateBefore(Instant dateTime);
}
The Spring Security Configuration is as follows:
package dev.local.gtm.api.config;
import dev.local.gtm.api.security.AuthoritiesConstants;
import dev.local.gtm.api.security.jwt.JWTConfigurer;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.filter.CorsFilter;
import org.zalando.problem.spring.web.advice.security.SecurityProblemSupport;
import javax.annotation.PostConstruct;
#RequiredArgsConstructor
#Configuration
#ComponentScan(basePackages = "dev.local.gtm.api")
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
#Import(SecurityProblemSupport.class)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private final AuthenticationManagerBuilder authenticationManagerBuilder;
private final UserDetailsService userDetailsService;
private final CorsFilter corsFilter;
private final SecurityProblemSupport problemSupport;
private final JWTConfigurer jwtConfigurer;
#PostConstruct
public void init() {
try {
authenticationManagerBuilder
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
} catch (Exception e) {
throw new BeanInitializationException("安全配置失败", e);
}
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
#Override
public void configure(WebSecurity web) {
web.ignoring()
.antMatchers(HttpMethod.OPTIONS, "/**")
.antMatchers("/app/**/*.{js,html}")
.antMatchers("/i18n/**")
.antMatchers("/content/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/test/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
.exceptionHandling()
.authenticationEntryPoint(problemSupport)
.accessDeniedHandler(problemSupport)
.and()
.csrf()
.disable()
.headers()
.frameOptions()
.disable()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/websocket/tracker").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/websocket/**").permitAll()
.antMatchers("/management/health").permitAll()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
.antMatchers("/v2/api-docs/**").permitAll()
.antMatchers("/swagger-resources/configuration/ui").permitAll()
.antMatchers("/swagger-ui/index.html").permitAll()
.and()
.apply(jwtConfigurer);
}
}
The UserDetailServiceImpl is as follows:
package dev.local.gtm.api.security;
import dev.local.gtm.api.config.Constants;
import dev.local.gtm.api.domain.User;
import dev.local.gtm.api.repository.UserRepo;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import lombok.val;
import org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import java.util.Locale;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
#Log4j2
#RequiredArgsConstructor
#Component("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
private final UserRepo userRepo;
#Override
public UserDetails loadUserByUsername(final String login) {
log.debug("正在对用户名为 {} 的用户进行鉴权", login);
if (new EmailValidator().isValid(login, null)) {
val userByEmailFromDatabase = userRepo.findOneByEmailIgnoreCase(login);
return userByEmailFromDatabase.map(user -> createSpringSecurityUser(login, user))
.orElseThrow(() -> new UsernameNotFoundException("系统中不存在 email 为 " + login + " 的用户"));
}
if (Pattern.matches(Constants.MOBILE_REGEX, login)) {
val userByMobileFromDatabase = userRepo.findOneByMobile(login);
return userByMobileFromDatabase.map(user -> createSpringSecurityUser(login, user))
.orElseThrow(() -> new UsernameNotFoundException("系统中不存在手机号为 " + login + " 的用户"));
}
String lowercaseLogin = login.toLowerCase(Locale.ENGLISH);
val userByLoginFromDatabase = userRepo.findOneByLogin(lowercaseLogin);
return userByLoginFromDatabase.map(user -> createSpringSecurityUser(lowercaseLogin, user))
.orElseThrow(() -> new UsernameNotFoundException("User " + lowercaseLogin + " was not found in the database"));
}
private org.springframework.security.core.userdetails.User createSpringSecurityUser(String lowercaseLogin, User user) {
if (!user.isActivated()) {
throw new UserNotActivatedException("用户 " + lowercaseLogin + " 没有激活");
}
val grantedAuthorities = user.getAuthorities().stream()
.map(authority -> new SimpleGrantedAuthority(authority.getName()))
.collect(Collectors.toList());
return new org.springframework.security.core.userdetails.User(user.getLogin(),
user.getPassword(),
grantedAuthorities);
}
}
[update] After I change spring-boot-jest to spring-boot-elasticsearch the error is more specific. it now says the elasticsearchTemplate bean is not defined, but in fact it is.
2018-05-02 17:04:59.776 WARN 76262 --- [ restartedMain] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig' defined in file [/Users/wangpeng/workspace/books/gtm/backend/api/out/production/classes/dev/local/gtm/api/config/SecurityConfig.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userDetailsService' defined in file [/Users/wangpeng/workspace/books/gtm/backend/api/out/production/classes/dev/local/gtm/api/security/UserDetailsServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepo': Cannot resolve reference to bean 'elasticsearchTemplate' while setting bean property 'elasticsearchOperations'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'elasticsearchTemplate' available
2018-05-02 17:04:59.805 INFO 76262 --- [ restartedMain] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2018-05-02 17:04:59.822 INFO 76262 --- [ restartedMain] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-05-02 17:04:59.925 ERROR 76262 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in dev.local.gtm.api.security.UserDetailsServiceImpl required a bean named 'elasticsearchTemplate' that could not be found.
Action:
Consider defining a bean named 'elasticsearchTemplate' in your configuration.
Process finished with exit code 1
The bean is defined in ElasticConfig as follows
package dev.local.gtm.api.config;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.elasticsearch.client.Client;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.EntityMapper;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.io.IOException;
#Configuration
#EnableConfigurationProperties(ElasticsearchProperties.class)
#ConditionalOnProperty("spring.data.elasticsearch.cluster-nodes")
public class ElasticConfig {
#Bean
public ElasticsearchTemplate elasticsearchTemplate(Client client, Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder) {
return new ElasticsearchTemplate(client, new CustomEntityMapper(jackson2ObjectMapperBuilder.createXmlMapper(false).build()));
}
public class CustomEntityMapper implements EntityMapper {
private ObjectMapper objectMapper;
public CustomEntityMapper(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
}
#Override
public String mapToString(Object object) throws IOException {
return objectMapper.writeValueAsString(object);
}
#Override
public <T> T mapToObject(String source, Class<T> clazz) throws IOException {
return objectMapper.readValue(source, clazz);
}
}
}
It turns out I reuse same entities for both Elasticsearch and MongoDB, which raise the exception. So I managed to get it resolved by separating the entities

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in "package name"

I am new to spring and hibernate as well as to stackoverflow
A developing ecommerce project using spring hibernate maven
creating two file one for frontend and 2nd for backend after creating two file i am adding dependency of backend into frontend pom.ml file
I am using java to create sessionfactory ,datasource and transaction manager
here is the code I dont understand what mistake i am doing
package com.ecom.Config;
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBuilder;
import
org.springframework.transaction.annotation.EnableTransactionManagement;
import com.ecom.Model.CustomerRegistration;
#Configuration
#ComponentScan("com.ecom")
#EnableTransactionManagement
public class AnnotationConfigApplicationContext {
#Bean(name = "dataSource")
public DataSource getH2DataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl("jdbc:h2:tcp://localhost/~/Ecommerce");
dataSource.setDriverClassName("org.h2.Driver");
dataSource.setUsername("sa");
dataSource.setPassword("");
return dataSource;
}
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.hbm2ddl.auto", "create");
return properties;
}
#Autowired
#Bean(name = "sessionFactory")
public SessionFactory getSessionFactory(DataSource dataSource) {
LocalSessionFactoryBuilder sessionBuilder = new
LocalSessionFactoryBuilder(dataSource);
sessionBuilder.addProperties(getHibernateProperties());
sessionBuilder.addAnnotatedClass(CustomerRegistration.class);
return sessionBuilder.buildSessionFactory();
}
#Autowired
#Bean(name = "transactionManager")
public HibernateTransactionManager getTransactionManager(SessionFactory
sessionFactory) {
HibernateTransactionManager transactionManager = new
HibernateTransactionManager(sessionFactory);
return transactionManager;
}
}
Contoller
package com.ecom.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import com.ecom.DAO.CustomerRegDAO;
import com.ecom.Model.CustomerRegistration;
#Controller
public class CustomerRegController
{
#Autowired
private CustomerRegDAO customerRegDAO ;
#RequestMapping("/registrationForm")
public String Registration(Model theModel)
{
CustomerRegistration theCustomerRegistration = new
CustomerRegistration();
theModel.addAttribute("customer", theCustomerRegistration);
return "registration-form";
}
#RequestMapping("/saveCustomer")
public String saveCustomer(#ModelAttribute("customer")
CustomerRegistration theCustomerRegistration)
{
customerRegDAO.saveCustomer(theCustomerRegistration);
return "index";
}
}
DAO
package com.ecom.DAOImplementation;
import javax.transaction.Transactional;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;
import com.ecom.DAO.CustomerRegDAO;
import com.ecom.Model.CustomerRegistration;
#Repository("CustomerRegDAO")
#Transactional
public class CustomerRegDAOImpl implements CustomerRegDAO {
private SessionFactory sessionFactory;
#Transactional
public void saveCustomer(CustomerRegistration theCustomerRegistration) {
Session currentsession = sessionFactory.getCurrentSession();
currentsession.saveOrUpdate(theCustomerRegistration);
}
}
Error:
Type Exception Report
Message Servlet.init() for servlet [spring] threw exception
Description The server encountered an unexpected condition that prevented
it from fulfilling the request.
Exception
javax.servlet.ServletException: Servlet.init() for servlet [spring] threw
exception
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase
.java:475)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogVa
lve.java:651)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:498)
Root cause
org.springframework.beans.factory.BeanCreationException: Error creating
bean
with name 'sessionFactory' defined in
com.ecom.Config.AnnotationConfigApplicationContext: Bean instantiation via
factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to instantiate
[org.hibernate.SessionFactory]: Factory method 'getSessionFactory' threw
exception; nested exception is java.lang.NoClassDefFoundError: Could not
initialize class
org.hibernate.annotations.common.reflection.java.JavaReflectionManager
java.lang.NoClassDefFoundError: Could not initialize class
org.hibernate.annotations.common.reflection.java.JavaReflectionManager
The exception is indicating that the class JavaReflectionManager is not found. This class is present in hibernate-commons-annotations jar file. Can you add this in your pom.xml and try running it again?
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>4.0.2.Final</version>
</dependency>

org.springframework.beans.factory.BeanCreationException & org.springframework.beans.BeanInstantiationException,No default constructor found

I am trying to use facebook api to create a facebook application using spring + thymeleaf + hibernate if I am trying to inject an Facebook parameter to the constructor
its showing the following error
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'facebookController' defined in file [D:\ff-sdefault constructor found; nested exception is java.lang.NoSuchMethodException: com.ff.FacebookController$$EnhancerByCGLIB$$80bb261.<init>()
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1030)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:975)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:665)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext.refresh(AnnotationConfigEmbeddedWebApplicationContext.java:193)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:514)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:281)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:697)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:686)
at com.fff.Application.main(Application.java:192)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.ff.FacebookController$$EnhancerByCGLIB$$80bb261]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.fff.FacebookController$$EnhancerByCGLIB$$80bb261.<init>()
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1023)
... 21 more
Caused by: java.lang.NoSuchMethodException: com.fff.FacebookController$$EnhancerByCGLIB$$80bb261.<init>()
at java.lang.Class.getConstructor0(Class.java:2800)
at java.lang.Class.getDeclaredConstructor(Class.java:2043)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
... 22 more
2013-11-04 16:30:27.157 INFO 5132 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
and this is the code
package com.fff;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.social.facebook.api.Facebook;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.inject.Inject;
#Controller
#RequestMapping("/facebook")
#Configuration
#ComponentScan("com.fff.service")
public class FacebookController {
private Facebook facebook;
#Autowired
private RegisterUserService registerUserService;
#Inject
public FacebookController(Facebook facebook) {
this.facebook = facebook;
}
#RequestMapping(value = "/register", method = RequestMethod.GET)
public String register(Model model) {
if (!facebook.isAuthorized()) {
return "redirect:/connect/facebook";
}
String email = facebook.userOperations().getUserProfile().getEmail();
String name = facebook.userOperations().getUserProfile().getName();
String firstName = facebook.userOperations().getUserProfile().getFirstName();
String lastName = facebook.userOperations().getUserProfile().getLastName();
String middleName = facebook.userOperations().getUserProfile().getMiddleName();
String dateOfBirth = facebook.userOperations().getUserProfile().getBirthday();
String userName = facebook.userOperations().getUserProfile().getUsername();
String gender = facebook.userOperations().getUserProfile().getGender();
String religion = facebook.userOperations().getUserProfile().getReligion();
model.addAttribute("user", new User(name, firstName, lastName));
return "registration";
}
#RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(Model model, User user) {
registerUserService.registerUser(user);
return "redirect:/";
}
}
Your "FacebookController" doesn't have a Default Constructor public FacebookController() and Spring needs it to create a new bean. When you declare you constructor public FacebookController(Facebook facebook), you're telling to Spring that the only existing constructor receives a parameter.
You can let you default Constructor like
#Autowire
private Facebook facebook;
public FacebookController() { }

Categories