APPLICATION FAILED TO START (Spring MockMvc #WebMvcTest) - java

everyone. I am new to WebMvcTest, and am learning to write a PostControllerTest. While the project runs well, the test does not work.
2017-05-31 10:08:09.490 INFO 5768 --- [ main] nz.p2.controller.PostControllerTest : Starting PostControllerTest on My-PC with PID 5768 (started by Me in C:\...)
2017-05-31 10:08:09.491 INFO 5768 --- [ main] nz.p2.controller.PostControllerTest : No active profile set, falling back to default profiles: default
2017-05-31 10:08:10.989 INFO 5768 --- [ main] o.s.w.c.s.GenericWebApplicationContext : Refreshing org.springframework.web.context.support.GenericWebApplicationContext#2a8d39c4: startup date [Wed May 31 10:08:10 NZST 2017]; root of context hierarchy
2017-05-31 10:08:12.788 INFO 5768 --- [ main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2017-05-31 10:08:13.311 WARN 5768 --- [ main] o.s.w.c.s.GenericWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'reCaptchaAuthenticationFilter': Unsatisfied dependency expressed through field 'reCaptchaService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'nz.p2.captcha.ReCaptchaService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
2017-05-31 10:08:13.326 INFO 5768 --- [ main] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-05-31 10:08:13.534 ERROR 5768 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Field reCaptchaService in nz.p2.captcha.ReCaptchaAuthenticationFilter required a bean of type 'nz.p2.captcha.ReCaptchaService' that could not be found.
Action:
Consider defining a bean of type 'nz.p2.captcha.ReCaptchaService' in your configuration.
It tells me to do something with the ReCaptchaService; which isn't used with the PostController. Given the simplifed Controller class:
#Controller
public class PostController {
#Autowired
private PostService postService;
#RequestMapping(value = URI_POST_POST, method = RequestMethod.GET)
public ModelAndView get(#Valid Long mkid) throws IOException {
// do somthing here using postService;
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName(URI_POST_POST);
modelAndView.addObject("abc", abc);
return modelAndView;
}
}
The PostControllerTest class is here:
#RunWith(SpringRunner.class)
#WebMvcTest(controllers = PostController.class)
public class PostControllerTest {
private MockMvc mockMvc;
#Autowired
private WebApplicationContext webApplicationContext;
#MockBean
private PostController postControllereMock;
#Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(webApplicationContext).build();
}
#Test
public void testList() throws Exception {
assertThat(this.postControllereMock).isNotNull();
mockMvc.perform(MockMvcRequestBuilders.get(URI_POST_POST + "?mkid=8044022272730561994"))
.andExpect(status().isOk())
.andExpect(content().contentType("text/html;charset=UTF-8"))
.andExpect(view().name(URI_POST_POST))
.andExpect(MockMvcResultMatchers.view().name(URI_POST_POST))
.andExpect(content().string(Matchers.containsString("I have put together some image galleries")))
.andDo(print());
}
}
I have to mention that the reCaptchaService is #Autowired in the ReCaptchaAuthenticationFilter, and the latter one is #Autowired and used here:
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.
// tl; nw
.and().csrf().disable()
.addFilterBefore(reCaptchaAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
// tl; nw
}
}
So, in this case, how can I test the PostController?

Related

Bean injection not happening even after the presence of bean in Springboot

I am working on Spring project. In this project I have password encoder bean.
#Configuration
public class AppSecurityConfiguration extends WebSecurityConfigurerAdapter {
public AppSecurityConfiguration() {
System.out.println("\n\n " + getClass().getName() + "\n\n\n");
}
#Autowired
private UserService userService;
#Bean
public PasswordEncoder defaultPasswordEncoder() {
System.out.println("\n\n\n bean is created!!!!! \n\n\n");
return new BCryptPasswordEncoder();
}
// other configurations
}
And the class where injection is required is this,
#Component
public class Encoders {
private static PasswordEncoder bCryptPasswordEncoder;
#Autowired
private PasswordEncoder defaultPasswordEncoder;
public Encoders() throws UnsupportedEncodingException {
System.out.println("\n\n\n " + (defaultPasswordEncoder == null) + " \n\n\n"); // this has problem, as defaultPasswordEncoder is null.
Encoders.bCryptPasswordEncoder = defaultPasswordEncoder;
}
// other methods
}
The defaultPasswordEncoder in the above class is null even though I have autowired this field.
The logs are showing that although the appSecurityConfiguration bean was made before encoder bean still the defaultPasswordEncoder bean is being created after encoder bean.
Here is the log,
2021-10-31 10:28:51.644 DEBUG 58508 --- [ restartedMain] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'appSecurityConfiguration'
com.clone.postmanc.security.AppSecurityConfiguration$$EnhancerBySpringCGLIB$$9529a353
.
.
.
.
2021-10-31 10:28:51.695 DEBUG 58508 --- [ restartedMain] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'encoders'
true // coming from Encoder#Encoder showing that
// defaultPasswordEncoder bean is null
2021-10-31 10:28:51.697 DEBUG 58508 --- [ restartedMain] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'defaultPasswordEncoder'
bean is created!!!!! // coming from AppSecurityConfiguration#defaultPasswordEncoder
I have also tried depends on annotation,
#Component
#DependsOn("defaultPasswordEncoder")
public class Encoders {
// rest is same
}
Now in logs defaultPasswordEncoder bean is being created before encoders but still the injection is not happening and the PasswordEncoder defaultPasswordEncoder field is null.
Here is the log,
2021-10-31 10:28:51.644 DEBUG 58508 --- [ restartedMain] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'appSecurityConfiguration'
com.clone.postmanc.security.AppSecurityConfiguration$$EnhancerBySpringCGLIB$$9529a353
.
.
.
2021-10-31 10:51:27.323 DEBUG 59592 --- [ restartedMain] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'defaultPasswordEncoder'
bean is created!!!!!
2021-10-31 10:51:27.327 DEBUG 59592 --- [ restartedMain] o.s.b.f.s.DefaultListableBeanFactory : Creating shared instance of singleton bean 'encoders'
true // still the field is null.
Can someone tell what is happening? And to resolve this issue?
Use constructor injection instead of property injection
public Encoders(PasswordEncoder defaultPasswordEncoder)
Then the bean will be available in constructor.

I cannot inject the PasswordEncoder class because of the JWTTokenProvider

I am writing a REST MVC application. I'm using Spring Boot and Hibernate. For protection, I decided to add Spring Security and JWT to the project.
I use BCryptEncoder to encode the password. Accordingly, I have it in the JWTTokenProvider class as a bean. I need to inject PasswordEncoder into the UserService class, but I can't. I understand the reason, but I don’t know how to fix it.
UserSevice:
#RequiredArgsConstructor
#Service
public class UserService {
private final UserRepository userRepository;
private final UserMapper userMapper;
private final PasswordEncoder passwordEncoder;
public UserDTO registration (RegistrationUserDTO registrationUserDTO){
User user = new User();
user.setName(registrationUserDTO.getName());
user.setLastName(registrationUserDTO.getLastName());
user.setLogin(registrationUserDTO.getLogin());
user.setMail(registrationUserDTO.getMail());
user.setPassword(passwordEncoder.encode(registrationUserDTO.getPassword()));
user.setRole(Role.CUSTOMER);
userRepository.save(user);
return userMapper.userToUserDTO(user);
}
}
JwtTokenProvider:
#RequiredArgsConstructor
#Component
public class JwtTokenProvider {
// Fields
//
private final UserDetailsService userDetailsService;
#Value("${jwt.token.secret}")
private String secret;
#Value("${jwt.token.expired}")
private Long validityInMilliSeconds;
// METHODS
//
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(8);
}
#PostConstruct
protected void init() {
secret = Base64.getEncoder().encodeToString(secret.getBytes());
}
/**
*
* #param login
* #param role
* #return ТОКЕН
*/
public String createToken(String login, Role role) {
Claims claims = Jwts.claims().setSubject(login);
claims.put("roles", role.name());
Date now = new Date();
Date validity = new Date(now.getTime() + validityInMilliSeconds);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
}
public Authentication getAuthentication(String token) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(getLogin(token));
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
}
public String getLogin(String token) {
return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateToken(String token) {
try {
Jws<Claims> claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token);
return !claims.getBody().getExpiration().before(new Date());
} catch (JwtException | IllegalArgumentException e) {
throw new JwtAuthenticationException("JWT token is expired or invalid");
}
}
/**
*
* #param req
* #return bearerToken
*/
public String resolveToken(HttpServletRequest req) {
String bearerToken = req.getHeader("Authorization");
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7);
}
return null;
}
}
JwtUserDetailsService:
#Slf4j
#Service
#RequiredArgsConstructor
public class JwtUserDetailsService implements UserDetailsService {
private final UserService userService;
#Override
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
User user = userService.findByLogin(login);
JwtUser jwtUser = JwtUserFactory.create(user);
log.info("IN loadUserByUsername - user with login: {} successfully loaded", login);
return jwtUser;
}
}
Logs:
2020-08-20 11:59:44.964 WARN 15396 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig' defined in file [D:\JetBrainsProjects\Coffeetearea\build\classes\java\main\ru\coffeetearea\config\SecurityConfig.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jwtTokenProvider' defined in file [D:\JetBrainsProjects\Coffeetearea\build\classes\java\main\ru\coffeetearea\security\jwt\JwtTokenProvider.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jwtUserDetailsService' defined in file [D:\JetBrainsProjects\Coffeetearea\build\classes\java\main\ru\coffeetearea\security\JwtUserDetailsService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userService' defined in file [D:\JetBrainsProjects\Coffeetearea\build\classes\java\main\ru\coffeetearea\service\UserService.class]: Unsatisfied dependency expressed through constructor parameter 2; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'jwtTokenProvider': Requested bean is currently in creation: Is there an unresolvable circular reference?
2020-08-20 11:59:44.964 INFO 15396 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2020-08-20 11:59:49.500 INFO 15396 --- [ task-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
Exception in thread "task-2" org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'delegatingApplicationListener': Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:212)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207)
at org.springframework.context.event.AbstractApplicationEventMulticaster.retrieveApplicationListeners(AbstractApplicationEventMulticaster.java:245)
at org.springframework.context.event.AbstractApplicationEventMulticaster.getApplicationListeners(AbstractApplicationEventMulticaster.java:197)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:134)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361)
at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.publishEventIfRequired(DataSourceInitializedPublisher.java:99)
at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher.access$100(DataSourceInitializedPublisher.java:50)
at org.springframework.boot.autoconfigure.orm.jpa.DataSourceInitializedPublisher$DataSourceSchemaCreatedPublisher.lambda$postProcessEntityManagerFactory$0(DataSourceInitializedPublisher.java:200)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
2020-08-20 11:59:49.525 INFO 15396 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
2020-08-20 11:59:49.532 INFO 15396 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2020-08-20 11:59:49.589 INFO 15396 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
2020-08-20 11:59:49.598 INFO 15396 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2020-08-20 11:59:49.628 INFO 15396 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-08-20 11:59:49.659 ERROR 15396 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
securityConfig defined in file [D:\JetBrainsProjects\Coffeetearea\build\classes\java\main\ru\coffeetearea\config\SecurityConfig.class]
┌─────┐
| jwtTokenProvider defined in file [D:\JetBrainsProjects\Coffeetearea\build\classes\java\main\ru\coffeetearea\security\jwt\JwtTokenProvider.class]
↑ ↓
| jwtUserDetailsService defined in file [D:\JetBrainsProjects\Coffeetearea\build\classes\java\main\ru\coffeetearea\security\JwtUserDetailsService.class]
↑ ↓
| userService defined in file [D:\JetBrainsProjects\Coffeetearea\build\classes\java\main\ru\coffeetearea\service\UserService.class]
└─────┘
Process finished with exit code 1
The problem is you are injecting something, the JwtTokenProvider in an #Configuration class that produces a bean that is needed by the JwtTokenProvider. So the JwtTokenProvider needs something provided by the security configuration while the SecurityConfig can only be created when it has a JwtTokenProvider hence a circular dependency.
Remove #Component from the JwtTokenProvider and create an #Bean method in the SecurityConfig (or whatever it is called) which creates the JwtTokenProvider.
It is also not recommended to use #Bean methods in #Components so move that to the SecurityConfig as well.
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{
#Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(8);
}
#Bean
public JwtTokenProvider jwtTokenProvider(UserDetailsService userDetailsService) {
return new JwtTokenProvider(userDetailsService);
}
// other config
}
Now there probably still is an issue as your JwtUserDetailsService needs the UserService which needs the PasswordEncoder and this again creates a circular reference. You might be better of injecting the UserRepository into your JwtUserDetailsService and use that to get the user by the login. I'm assuming that the UserService simply delegates to the UserRepository.findByLogin method.
#Slf4j
#Service
#RequiredArgsConstructor
public class JwtUserDetailsService implements UserDetailsService {
private final UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
User user = userRepository.findByLogin(login);
if (user != null) {
JwtUser jwtUser = JwtUserFactory.create(user);
log.info("IN loadUserByUsername - user with login: {} successfully loaded", login);
return jwtUser;
} else {
throw new UsernameNotFoundException("Unknown user '"+login+"'");
}
}
}
NOTE: Your UserDetailsService didn't honour the contract (no user found should throw an UsernameNotFoundException. The modified one does honour that contract.

Setting up H2 database in Spring + Hibernate without XML File yields NullPointerException

I have a problem regarding the proper setup of a H2 database in springboot + hibernate and would very much appreciate your help. I guess my problem is in the #Transaction Annotation, since the respective class throws a NullPointerException. Here is some background information:
The idea of the program (which is not yet finished) is that agents (class "AgentLogic") can calulate prices for specific tasks within a Multi-Agent System. In order to calculate the price, an agent draws parameters from a database. These parameters are needed for some Machine Learning algorithms (in class "MachineLearningSource"), which will calculate the price of the agent.
I would like to setup the configuration of the database WITHOUT using an XML File, similar to the example in http://www.baeldung.com/hibernate-4-spring
The project has the following structure:
Project Structure
UPDATED CODE AFTER INCORPORATING CHANGES FROM #StanislavL
The project is implemented in SpringBoot. Accordingly, I use the following Application class:
package org.schlago.mldb;
import...
#SpringBootApplication
public class Application {
public static void main(String[] args) {
// ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
SpringApplicationBuilder builder = new SpringApplicationBuilder(Application.class);
builder.headless(false);
ConfigurableApplicationContext context = builder.run(args);
}
}
The following class contains the configuration of the database in Spring Hibernate, called DataBaseConfig:
package org.schlago.mldb.database;
import...
#Configuration
#Profile("param_db")
#EnableTransactionManagement
#ComponentScan({"org.schlago.mldb.mapping","org.schlago.mldb.machineLearning"})
public class DatabaseConfig {
#Autowired
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("datasource.driver"));
dataSource.setUrl(env.getProperty("datasource.url"));
dataSource.setUsername(env.getProperty("datasource.username"));
dataSource.setPassword(env.getProperty("datasource.password"));
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory(){
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(env.getProperty("entitymanager.packagesToScan"));
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", env.getProperty("jpa.hibernate.dialect"));
hibernateProperties.put("hibernate.show_sql", env.getProperty("jpa.hibernate.show-sql"));
hibernateProperties.put("hibernate.hbm2ddl.auto", env.getProperty("jpa.hibernate.hbm2ddl.auto"));
hibernateProperties.put("spring.jpa.hibernate.ddl-auto", env.getProperty("jpa.hibernate.ddl-auto"));
sessionFactoryBean.setHibernateProperties(hibernateProperties);
return sessionFactoryBean;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory sessionFactory){
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory);
return transactionManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
}
This configuration uses the following environment (#Profile) in order to setup the sessionFactoryBean, called appliation.yaml:
spring.profiles: param_db
datasource:
driver: org.h2.Driver
url: jdbc:h2:tcp://localhost/~/test
username: sa
password:
jpa:
hibernate.show-sql: true
hibernate.hbm2ddl.auto: none
hibernate.dialect: org.hibernate.dialect.H2Dialect
hibernate.ddl-auto: validate
hibernate.globally_quoted_identifiers: true
entitymanager:
packagesToScan: org.schlago.mldb.mapping
Parameters shall be inserted to the database via a DAO, using a #Transactional Annotation. This DAO is called ParametersDao:
package org.schlago.mldb.mapping;
import ...
#Transactional
public class ParametersDao {
#Autowired
private SessionFactory _sessionFactory;
private Session getSession() {
return _sessionFactory.getCurrentSession();
}
public void save(Parameters parameters) { getSession().save(parameters); }
public void update(Parameters parameters) {
getSession().update(parameters);
}
public List<Parameters> getAllParameters() {
return getSession().createQuery("from Parameters").list();
}
public Parameters getParameterById(int id) {
List<Parameters> parametersList = getSession()
.createQuery("from Parameters where paramId = :theId")
.setParameter("theId", id).list();
if (parametersList.size() == 0) {
return null;
}
return parametersList.get(0);
}
}
Parameters are specified via the Paramters class:
package org.schlago.mldb.mapping;
#Entity
#Table(name = "mlparam")
public class Parameters {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long paramId;
#Column(name = "name")
private String name;
#Column(name = "value")
private double value;
#Column(name = "timestamp")
private Date timestamp;
public Parameters(){
}
public long getParamId() {
return paramId;
}
public void setParamId(int paramId) {
this.paramId = paramId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) { this.timestamp = timestamp; }
}
I think there is an error in the way ParametersDao is setup. However, for your better understanding, here are the other classes used within this project. The following class is AgentLogic, which will calculate a price upon request in a later strange of the code. Since the code is still in an early stage, I used #PostConstruct rather than a request, in order to test if the price calulation works:
package org.schlago.mldb.logic;
import...
#Component
public class AgentLogic {
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
#Autowired
private MachineLearningSource machineLearningSource;
#PostConstruct
public void init(){
int priceInCent = 50;
priceInCent = machineLearningSource.getPrice(getAgent());
LOGGER.info("Answered with offer about " + priceInCent + " Cents.");
}
// DUMMY class: Return a new agent
public static Agent getAgent(){
// Currently, an Agent is just an (empty) dummy class
Agent agent = new Agent();
return agent;
}
}
Finally, the following class is responsible for price calcuation. Since the code is still in an early stage, price calculation is set randomly, rather than implementing machinelearning algorithms. In the method getParameters(), some Parameters are inserted to the dataBase for testing purposes:
package org.schlago.mldb.machineLearning;
import org.schlago.mldb.Nodes.Agent;
import org.schlago.mldb.mapping.Parameters;
import org.schlago.mldb.mapping.ParametersDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date;
import java.util.HashMap;
import java.util.Random;
#Component
public class MachineLearningSource {
#Autowired
ParametersDao parametersDao;
private static final Logger LOGGER = LoggerFactory.getLogger(MachineLearningSource.class);
public int getPrice(Agent agent) {
Random r = new Random();
int thePrice = r.nextInt(99) + 1;
LOGGER.info("The price is dynamically calculated right now!");
HashMap<String, Double> parameters = getParameters();
return thePrice;
}
public HashMap<String, Double> getParameters() {
HashMap<String, Double> equationParameters = new HashMap<>();
// TEST: Since database is currently empty, parameters are inserted manually here (this will change later)
LOGGER.info("About to insert into table");
Parameters myCalcParams = new Parameters();
myCalcParams.setName("kappa");
myCalcParams.setValue(2.39583992);
myCalcParams.setTimestamp(new Date());
parametersDao.save(myCalcParams);
LOGGER.info("Successfully inserted parameters");
/*
// Get the parameters via parametersDao, work in progress!
List<Parameters> parameters = parametersDao.getAllParameters();
Parameters myParam = parametersDao.getParameterById(3748);
if (myParam == null) {
LOGGER.info("Dataset does not exist!");
}
for (Parameters param : parameters) {
equationParameters.put(param.getName(), param.getValue());
LOGGER.info("Actual parameter for price calculation: " + param.getName());
LOGGER.info("Value: " + param.getValue());
}
*/
// TEST: Return dummy equationParameters
equationParameters.put("a", 2.48238948239);
equationParameters.put("b", 8.23482489729);
return equationParameters;
}
}
UPDATED ERROR STATEMENT
Unfortuntely, I still get an error:
2017-02-03 14:41:39.005 INFO 7416 --- [ main] org.schlago.mldb.Application : Starting Application on mobile-97 with PID 7416 (C:\Users\Jan\Documents\Masterarbeit\12_MLDBtest\target\classes started by Jan in C:\Users\Jan\Documents\Masterarbeit\12_MLDBtest)
2017-02-03 14:41:39.005 INFO 7416 --- [ main] org.schlago.mldb.Application : The following profiles are active: param_db
2017-02-03 14:41:39.083 INFO 7416 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext#79ca92b9: startup date [Fri Feb 03 14:41:39 CET 2017]; root of context hierarchy
2017-02-03 14:41:40.581 INFO 7416 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'databaseConfig' of type [class org.schlago.mldb.database.DatabaseConfig$$EnhancerBySpringCGLIB$$829d3967] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-02-03 14:41:40.721 INFO 7416 --- [ main] o.s.j.d.DriverManagerDataSource : Loaded JDBC driver: org.h2.Driver
2017-02-03 14:41:41.004 INFO 7416 --- [ main] j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
2017-02-03 14:41:41.020 INFO 7416 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [
name: default
...]
2017-02-03 14:41:41.129 INFO 7416 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core {4.3.11.Final}
2017-02-03 14:41:41.129 INFO 7416 --- [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
2017-02-03 14:41:41.129 INFO 7416 --- [ main] org.hibernate.cfg.Environment : HHH000021: Bytecode provider name : javassist
2017-02-03 14:41:41.394 INFO 7416 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
2017-02-03 14:41:41.521 INFO 7416 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
2017-02-03 14:41:41.693 INFO 7416 --- [ main] o.h.h.i.ast.ASTQueryTranslatorFactory : HHH000397: Using ASTQueryTranslatorFactory
2017-02-03 14:41:42.363 INFO 7416 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000227: Running hbm2ddl schema export
2017-02-03 14:41:42.432 INFO 7416 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000230: Schema export complete
2017-02-03 14:41:42.510 WARN 7416 --- [ main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'agentLogic': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.schlago.mldb.machineLearning.MachineLearningSource org.schlago.mldb.logic.AgentLogic.machineLearningSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'machineLearningSource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.schlago.mldb.mapping.ParametersDao org.schlago.mldb.machineLearning.MachineLearningSource.parametersDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.schlago.mldb.mapping.ParametersDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
2017-02-03 14:41:42.510 INFO 7416 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2017-02-03 14:41:42.510 INFO 7416 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000227: Running hbm2ddl schema export
2017-02-03 14:41:42.559 INFO 7416 --- [ main] org.hibernate.tool.hbm2ddl.SchemaExport : HHH000230: Schema export complete
2017-02-03 14:41:42.559 ERROR 7416 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'agentLogic': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.schlago.mldb.machineLearning.MachineLearningSource org.schlago.mldb.logic.AgentLogic.machineLearningSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'machineLearningSource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.schlago.mldb.mapping.ParametersDao org.schlago.mldb.machineLearning.MachineLearningSource.parametersDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.schlago.mldb.mapping.ParametersDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.schlago.mldb.machineLearning.MachineLearningSource org.schlago.mldb.logic.AgentLogic.machineLearningSource; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'machineLearningSource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.schlago.mldb.mapping.ParametersDao org.schlago.mldb.machineLearning.MachineLearningSource.parametersDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.schlago.mldb.mapping.ParametersDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'machineLearningSource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.schlago.mldb.mapping.ParametersDao org.schlago.mldb.machineLearning.MachineLearningSource.parametersDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.schlago.mldb.mapping.ParametersDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.schlago.mldb.mapping.ParametersDao org.schlago.mldb.machineLearning.MachineLearningSource.parametersDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.schlago.mldb.mapping.ParametersDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations:
2017-02-03 14:41:42.575 INFO 7416 --- [ main] .b.l.ClasspathLoggingApplicationListener : Application failed to start with classpath: [file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/charsets.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/deploy.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/access-bridge-64.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/cldrdata.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/dnsns.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/jaccess.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/jfxrt.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/localedata.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/nashorn.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/sunec.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/sunjce_provider.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/sunmscapi.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/sunpkcs11.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/ext/zipfs.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/javaws.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/jce.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/jfr.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/jfxswt.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/jsse.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/management-agent.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/plugin.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/resources.jar, file:/C:/Program%20Files/Java/jdk1.8.0_60/jre/lib/rt.jar, file:/C:/Users/Jan/Documents/Masterarbeit/12_MLDBtest/target/classes/, file:/C:/Users/Jan/.m2/repository/org/springframework/boot/spring-boot-starter-data-jpa/1.3.5.RELEASE/spring-boot-starter-data-jpa-1.3.5.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/boot/spring-boot-starter/1.3.5.RELEASE/spring-boot-starter-1.3.5.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/boot/spring-boot/1.3.5.RELEASE/spring-boot-1.3.5.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/1.3.5.RELEASE/spring-boot-autoconfigure-1.3.5.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/boot/spring-boot-starter-logging/1.3.5.RELEASE/spring-boot-starter-logging-1.3.5.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/ch/qos/logback/logback-classic/1.1.7/logback-classic-1.1.7.jar, file:/C:/Users/Jan/.m2/repository/ch/qos/logback/logback-core/1.1.7/logback-core-1.1.7.jar, file:/C:/Users/Jan/.m2/repository/org/slf4j/jul-to-slf4j/1.7.21/jul-to-slf4j-1.7.21.jar, file:/C:/Users/Jan/.m2/repository/org/slf4j/log4j-over-slf4j/1.7.21/log4j-over-slf4j-1.7.21.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-core/4.2.6.RELEASE/spring-core-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/yaml/snakeyaml/1.16/snakeyaml-1.16.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/boot/spring-boot-starter-aop/1.3.5.RELEASE/spring-boot-starter-aop-1.3.5.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-aop/4.2.6.RELEASE/spring-aop-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/aopalliance/aopalliance/1.0/aopalliance-1.0.jar, file:/C:/Users/Jan/.m2/repository/org/aspectj/aspectjweaver/1.8.9/aspectjweaver-1.8.9.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/boot/spring-boot-starter-jdbc/1.3.5.RELEASE/spring-boot-starter-jdbc-1.3.5.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/apache/tomcat/tomcat-jdbc/8.0.33/tomcat-jdbc-8.0.33.jar, file:/C:/Users/Jan/.m2/repository/org/apache/tomcat/tomcat-juli/8.0.33/tomcat-juli-8.0.33.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-jdbc/4.2.6.RELEASE/spring-jdbc-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/hibernate/hibernate-entitymanager/4.3.11.Final/hibernate-entitymanager-4.3.11.Final.jar, file:/C:/Users/Jan/.m2/repository/org/jboss/logging/jboss-logging/3.3.0.Final/jboss-logging-3.3.0.Final.jar, file:/C:/Users/Jan/.m2/repository/org/jboss/logging/jboss-logging-annotations/1.2.0.Beta1/jboss-logging-annotations-1.2.0.Beta1.jar, file:/C:/Users/Jan/.m2/repository/org/hibernate/hibernate-core/4.3.11.Final/hibernate-core-4.3.11.Final.jar, file:/C:/Users/Jan/.m2/repository/antlr/antlr/2.7.7/antlr-2.7.7.jar, file:/C:/Users/Jan/.m2/repository/org/jboss/jandex/1.1.0.Final/jandex-1.1.0.Final.jar, file:/C:/Users/Jan/.m2/repository/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar, file:/C:/Users/Jan/.m2/repository/xml-apis/xml-apis/1.0.b2/xml-apis-1.0.b2.jar, file:/C:/Users/Jan/.m2/repository/org/hibernate/common/hibernate-commons-annotations/4.0.5.Final/hibernate-commons-annotations-4.0.5.Final.jar, file:/C:/Users/Jan/.m2/repository/org/hibernate/javax/persistence/hibernate-jpa-2.1-api/1.0.0.Final/hibernate-jpa-2.1-api-1.0.0.Final.jar, file:/C:/Users/Jan/.m2/repository/org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA.jar, file:/C:/Users/Jan/.m2/repository/javax/transaction/javax.transaction-api/1.2/javax.transaction-api-1.2.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/data/spring-data-jpa/1.9.4.RELEASE/spring-data-jpa-1.9.4.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/data/spring-data-commons/1.11.4.RELEASE/spring-data-commons-1.11.4.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-orm/4.2.6.RELEASE/spring-orm-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-context/4.2.6.RELEASE/spring-context-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-expression/4.2.6.RELEASE/spring-expression-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-tx/4.2.6.RELEASE/spring-tx-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-beans/4.2.6.RELEASE/spring-beans-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/org/slf4j/jcl-over-slf4j/1.7.21/jcl-over-slf4j-1.7.21.jar, file:/C:/Users/Jan/.m2/repository/org/springframework/spring-aspects/4.2.6.RELEASE/spring-aspects-4.2.6.RELEASE.jar, file:/C:/Users/Jan/.m2/repository/com/sparkjava/spark-core/1.1.1/spark-core-1.1.1.jar, file:/C:/Users/Jan/.m2/repository/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-server/9.2.16.v20160414/jetty-server-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-http/9.2.16.v20160414/jetty-http-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-util/9.2.16.v20160414/jetty-util-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-io/9.2.16.v20160414/jetty-io-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-webapp/9.2.16.v20160414/jetty-webapp-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-xml/9.2.16.v20160414/jetty-xml-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-servlet/9.2.16.v20160414/jetty-servlet-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/org/eclipse/jetty/jetty-security/9.2.16.v20160414/jetty-security-9.2.16.v20160414.jar, file:/C:/Users/Jan/.m2/repository/net/sf/xenqtt/xenqtt/0.9.7/xenqtt-0.9.7.jar, file:/C:/Users/Jan/.m2/repository/org/json/json/20151123/json-20151123.jar, file:/C:/Users/Jan/.m2/repository/com/pi4j/pi4j-core/1.0/pi4j-core-1.0.jar, file:/C:/Users/Jan/.m2/repository/org/bouncycastle/bcprov-jdk15on/1.54/bcprov-jdk15on-1.54.jar, file:/C:/Users/Jan/.m2/repository/org/bouncycastle/bcpkix-jdk15on/1.54/bcpkix-jdk15on-1.54.jar, file:/C:/Users/Jan/.m2/repository/com/h2database/h2/1.4.192/h2-1.4.192.jar, file:/C:/Users/Jan/.m2/repository/org/opcfoundation/ua/1.02.337.10/ua-1.02.337.10.jar, file:/C:/Users/Jan/.m2/repository/com/prosys/ua/server-client-sdk/2.2/server-client-sdk-2.2.jar, file:/C:/Program%20Files%20(x86)/JetBrains/IntelliJ%20IDEA%202016.2.5/lib/idea_rt.jar]
Try to add #Component annotation to the MachineLearningSource service class and check both dao and the service are included in the #ComponentScan
UPDATE
In the AgentLogic you manually create the machineLearningSource
MachineLearningSource machineLearningSource = new MachineLearningSource();
priceInCent = machineLearningSource.getPrice(getAgent());
Instead add
#Autowired
private MachineLearningSource machineLearningSource;
To the class to let Spring initialize this properly. Or you can autowire dao in the class and manually call
machineLearningSource.setDao(theAutowiredDao);
UPDATE2:
Now the dao is not marked to be detected as a spring bean. Add #Repository annotation to the DAO.
UPDATE3:
sessionFactoryBean.setPackagesToScan(env.getProperty("entitymanager.packagesToScan"));
check which exactly packages are scanned there. Need to have all packages where your entity classes are stored.

Did not find handler method

I am trying to invoke a rest endpoint, but getting this info when i call it, resulting in a 404 error in UI
2016-08-07 13:43:42.611 DEBUG 27834 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /api/v1/operations
2016-08-07 13:43:42.614 DEBUG 27834 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/api/v1/operations]
2016-08-07 13:43:42.615 DEBUG 27834 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/api/v1/operations] are [/**]
2016-08-07 13:43:42.616 DEBUG 27834 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/api/v1/operations] are {}
2016-08-07 13:43:42.617 DEBUG 27834 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/api/v1/operations] to HandlerExecutionChain with handler [ResourceHttpRequestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#39ead1b7]]] and 1 interceptor
There are 2 controller class in the same package with different endpoint
#RestController
public class OperationRetrievalController {
#Autowired
OperationRetrievalManager operationRetrievalManager;
private static Logger logger = Logger.getLogger(OperationRetrievalController.class);
#RequestMapping("/api/v1/operations")
public ResponseEntity<List<OperationView>> requestUserOperations() {
String ssoId = "xxxxxx";
logger.info("Inside request operationRetrivel Manager +++++++++>>>>>>>>");
return new ResponseEntity<List<OperationView>>(operationRetrievalManager.retrieveOperations(ssoId), HttpStatus.OK);
}
}
I have another class in the same package :
#RestController
public class ComponentRetrievalController {
#Autowired
ComponentRetrievalManager componentRetrievalManager;
#RequestMapping(value = "api/v1/component/{sso_id}" , method=RequestMethod.GET)
public ResponseEntity<List<Component>> requestUserComponent(#PathVariable("sso_id") String ssoId) {
return new ResponseEntity<List<Component>>(componentRetrievalManager.retrieveComponents(ssoId), HttpStatus.OK);
}
}
Here is the Spring boot app class :
#SpringBootApplication
#EnableAutoConfiguration
#EnableJpaRepositories(basePackages="com.ge.power.bis.repositories")
#ComponentScan(basePackages="com.ge.power.bis.managers")
public class Application {
private static Logger logger = Logger.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(Application.class);
ApplicationContext ctx = springApplication.run(args);
logger.info("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames)
{
logger.info(beanName);
}
}
}
Here is the structure of my package
When I remove all the annotations in Application.java and just keeping the #SpringBootApplication, It gives the following error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'componentRetrievalController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.ge.power.bis.managers.ComponentRetrievalManager com.ge.power.bis.controllers.ComponentRetrievalController.componentRetrievalManager; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.ge.power.bis.managers.ComponentRetrievalManager] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapable
#Service was missing on one of the Impl class
You need to mark the service class as "Available to make beans" so the Spring's component-scan will be able to make bean and inject values.
This can be done by #Component annotation. As mentioned in the answer by #sromit, adding #Service annotation will also work, as it already inherits the #Component. #Repository and #Controller also inherit the #Component annotation.

Init method in Spring Controller (annotation version)

I'm converting a controller to the newer annotation version. In the old version I used to specify the init method in springmvc-servlet.xml using:
<beans>
<bean id="myBean" class="..." init-method="init"/>
</beans>
How can I specify the init method using the annotation version?
You can use
#PostConstruct
public void init() {
// ...
}
Alternatively you can have your class implement the InitializingBean interface to provide a callback function (afterPropertiesSet()) which the ApplicationContext will invoke when the bean is constructed.
There are several ways to intercept the initialization process in Spring. If you have to initialize all beans and autowire/inject them there are at least two ways that I know of that will ensure this. I have only testet the second one but I belive both work the same.
If you are using #Bean you can reference by initMethod, like this.
#Configuration
public class BeanConfiguration {
#Bean(initMethod="init")
public BeanA beanA() {
return new BeanA();
}
}
public class BeanA {
// method to be initialized after context is ready
public void init() {
}
}
If you are using #Component you can annotate with #EventListener like this.
#Component
public class BeanB {
#EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
}
}
In my case I have a legacy system where I am now taking use of IoC/DI where Spring Boot is the choosen framework. The old system brings many circular dependencies to the table and I therefore must use setter-dependency a lot. That gave me some headaches since I could not trust #PostConstruct since autowiring/injection by setter was not yet done. The order is constructor, #PostConstruct then autowired setters. I solved it with #EventListener annotation which wil run last and at the "same" time for all beans. The example shows implementation of InitializingBean aswell.
I have two classes (#Component) with dependency to each other. The classes looks the same for the purpose of this example displaying only one of them.
#Component
public class BeanA implements InitializingBean {
private BeanB beanB;
public BeanA() {
log.debug("Created...");
}
#PostConstruct
private void postConstruct() {
log.debug("#PostConstruct");
}
#Autowired
public void setBeanB(BeanB beanB) {
log.debug("#Autowired beanB");
this.beanB = beanB;
}
#Override
public void afterPropertiesSet() throws Exception {
log.debug("afterPropertiesSet()");
}
#EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
log.debug("#EventListener");
}
}
This is the log output showing the order of the calls when the container starts.
2018-11-30 18:29:30.504 DEBUG 3624 --- [ main] com.example.demo.BeanA : Created...
2018-11-30 18:29:30.509 DEBUG 3624 --- [ main] com.example.demo.BeanB : Created...
2018-11-30 18:29:30.517 DEBUG 3624 --- [ main] com.example.demo.BeanB : #Autowired beanA
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanB : #PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanB : afterPropertiesSet()
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanA : #Autowired beanB
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanA : #PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [ main] com.example.demo.BeanA : afterPropertiesSet()
2018-11-30 18:29:30.607 DEBUG 3624 --- [ main] com.example.demo.BeanA : #EventListener
2018-11-30 18:29:30.607 DEBUG 3624 --- [ main] com.example.demo.BeanB : #EventListener
As you can see #EventListener is run last after everything is ready and configured.
#PostConstruct、implement InitializingBean、specify init-method they have call orders. So you can't use them to replace init-method. You can try this:
#Bean(initMethod = "init")
public MyBean mybean() {
return new MyBean();
}
class MyBean {
public void init() {
System.out.println("MyBean init");
}
}
in your class, you can declare a method named init().
Refer to:
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#:~:text=Multiple%20lifecycle%20mechanisms%20configured%20for%20the%20same%20bean%2C%20with%20different%20initialization%20methods%2C%20are%20called%20as%20follows%3A
public class InitHelloWorld implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean,
String beanName) throws BeansException {
System.out.println("BeforeInitialization : " + beanName);
return bean; // you can return any other object as well
}
public Object postProcessAfterInitialization(Object bean,
String beanName) throws BeansException {
System.out.println("AfterInitialization : " + beanName);
return bean; // you can return any other object as well
}
}

Categories