here is my entity
#Entity
public class User {
#Id
private String id;
private String externalUserId;
private String email;
private String clientId;
private String clientSecret;
private boolean active;
public User(#Nonnull final String externalUserId, #Nonnull final String email,
#Nonnull final String clientId, #Nonnull final String clientSecret, final boolean active) {
id = UUID.randomUUID().toString();
this.externalUserId = externalUserId;
this.email = email;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.active = active;
}
}
and a UserService
import javax.annotation.Nonnull;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceUnit;
#Stateless
public class UserService {
#PersistenceUnit
private EntityManager entityManager;
#Nonnull
public User createUser(#Nonnull final User user) {
entityManager.persist(user);
return user;
}
}
I also have DBConfig as
import javax.annotation.sql.DataSourceDefinition;
import javax.ejb.Stateless;
#DataSourceDefinition(
name = "java:app/oauth/testDB",
className = "org.h2.jdbcx.JdbcDataSource",
url = "jdbc:h2:mem:test"
)
#Stateless
public class DBConfig {
}
test/src/main/resources/persistence.xml as
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="testDB" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.self.oauth.persistence.entities.User</class>
</persistence-unit>
</persistence>
My test looks like
public class UserTest {
#Inject
private UserService userService;
#Test
public void testUser() {
final User user = new User(UUID.randomUUID().toString(), "test#test.com", "clientId", "clientSecret", true);
userService.createUser(user);
assertTrue(true);
}
}
and I get NullPointeException on userService
What am I missing?
Injection is handled by a Java EE Container in execution time. In particular and checking your piece of code, an EJB container would handle the injection of UserService since it is declared to be a Stateless bean. When you deploy your entire application a container is set and injection works fine. When executing unit tests (I guess using junit) none of the services are launched, and any #Injection will end up with the variable set to null, because no container will be launched either.
The idea is that unit tests should be only used for testing pieces of code independently of external ones like the one contained in other classes. However, in your case it looks like you want an integration test, so, you really need all services to be up since you want to check that an object is persisted in the database. For that, you need you need to launch also a container. A good way of doing that, is using Arquillian.
For instance, in your case, the test should be something like this:
package org.arquillian.example;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
#RunWith(Arquillian.class)
public class UserTest{
#Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addClass(UserService.class)
.addClass(User.class)
.addClass(DBConfig.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
#Inject
private UserService userService;
#Test
public void testUser() {
final User user = new User(UUID.randomUUID().toString(), "test#test.com", "clientId", "clientSecret", true);
userService.createUser(user);
assertTrue(true);
}
}
Related
I have a CustomerUserDetailsService class, which is part of an implementation of Spring Boot authentication. I have tested my code manually, and it works correctly, allowing me to successfully log in to my app. However, I am unable to work out how to test the CustomerUserDetailsService.
As a unit test, I believe I would need to mock the userRepository member variable, but whatever I try in my test fails, the reason being userRepository is set to null. I've tried adding the #Repository annotation to userRepository but am told that is not allowed because it is an interface. There's also the fact that loadUserByUsername returns an instance of CustomUserDetails, which is just an implementation of an interface, so I have no idea how I'd mock that dependency?
I've also tried doing some kind of integration test but had similar issues, probably due to incorrect annotations on the test itself. In an ideal world, I'd prefer a unit test and would be extremely grateful for any guidance as to how to set it up.
These are the relevant classes...
CustomerUserDetailsService:
package com.phil.urlshortener.security;
import com.phil.urlshortener.model.User;
import com.phil.urlshortener.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class CustomUserDetailsService implements UserDetailsService {
#Autowired private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not found");
}
return new CustomUserDetails(user);
}
}
User:
package com.phil.urlshortener.model;
import lombok.Data;
import javax.persistence.*;
#Data
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false, unique = true, length = 50)
private String username;
#Column(nullable = false, length = 64)
private String password;
}
UserRepository:
package com.phil.urlshortener.repositories;
import com.phil.urlshortener.model.User;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, Long> {
#Query("SELECT u FROM User u WHERE u.username = ?1")
User findByUsername(String username);
}
CustomUserDetails:
package com.phil.urlshortener.security;
import com.phil.urlshortener.model.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
public class CustomUserDetails implements UserDetails {
private final User user;
public CustomUserDetails(User user) {
this.user = user;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
#Override
public String getPassword() {
return user.getPassword();
}
#Override
public String getUsername() {
return user.getUsername();
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
}
Maybe you forgot to use mockito annotation #RunWith(MockitoJUnitRunner.class).
Here it's the unit test for CustomUserDetailsService :
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.test.util.ReflectionTestUtils;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
#RunWith(MockitoJUnitRunner.class)
public class CustomUserDetailsService {
#Mock
private UserRepository userRepository;
private CustomUserDetailsService customUserDetailsService;
#Before
public void setUp() throws Exception {
customUserDetailsService = new CustomUserDetailsService(userRepository);
}
#Test
public void GIVEN_username_THEN_return_user_details() {
//Arrange
final String username = "existingUserName";
final User user = mock(User.class);
when(userRepository.findByUsername(username)).thenReturn(user);
//Act
final UserDetails userDetails = customUserDetailsService.loadUserByUsername(username);
//Assert
assertNotNull(userDetails);
assertEquals(user, ReflectionTestUtils.getField(userDetails, "user"));
}
}
Am making an API authentication feature with JWT in Spring boot rest, but am facing the following error :
Description:
Parameter 0 of constructor in
com.icfer.huxy.icfer.controller.UserController required a bean of type
'com.icfer.huxy.icfer.service.ApplicationUserRepository' that could
not be found.
Action:
Consider defining a bean of type
'com.icfer.huxy.icfer.service.ApplicationUserRepository' in your
configuration.
Below is what I have implemented regarding ApplicationUserRepository, and UserController classes.
ApplicationUserRepository.java
import com.icfer.huxy.icfer.model.ApplicationUser;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Component;
public interface ApplicationUserRepository extends JpaRepository<ApplicationUser, Long> {
ApplicationUser findByUsername(String username);
}
ApplicationUser.java
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity
public class ApplicationUser {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String username;
private String password;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
UserController.java
import com.icfer.huxy.icfer.model.ApplicationUser;
import com.icfer.huxy.icfer.service.ApplicationUserRepository;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/users")
public class UserController {
private ApplicationUserRepository applicationUserRepository;
private BCryptPasswordEncoder bCryptPasswordEncoder;
public UserController(ApplicationUserRepository applicationUserRepository,
BCryptPasswordEncoder bCryptPasswordEncoder) {
this.applicationUserRepository = applicationUserRepository;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
#PostMapping("/sign-up")
public void signUp(#RequestBody ApplicationUser user) {
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
applicationUserRepository.save(user);
}
}
My gradle file de is as below :
dependencies {
implementation('org.springframework.boot:spring-boot-starter-data-jpa')
implementation('org.springframework.boot:spring-boot-starter-security')
implementation('org.springframework.boot:spring-boot-starter-web')
compile("com.auth0:java-jwt:3.4.0")
runtimeOnly('mysql:mysql-connector-java')
testImplementation('org.springframework.boot:spring-boot-starter-test')
testImplementation('org.springframework.security:spring-security-test')
}
Below is the link to my project:
Github link
One more reason sharing an actual sample is helpful as none of the code you've shared provides the information that we need to help you.
On your #SpringBootApplication you have the following:
#SpringBootApplication
#EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, WebMvcAutoConfiguration.class})
public class IcferApplication { ... }
Because you are excluding DataSourceAutoConfiguration, no DataSource is created. There is no DataSource so JPA does not kick in. JPA is not started so your JPA repository is not created.
You could have ran your app in debug mode (i.e. by adding a -Ddebug system property):
JpaRepositoriesAutoConfiguration:
Did not match:
- #ConditionalOnBean (types: javax.sql.DataSource; SearchStrategy: all) did not find any beans of type javax.sql.DataSource (OnBeanCondition)
Matched:
- #ConditionalOnClass found required class 'org.springframework.data.jpa.repository.JpaRepository' (OnClassCondition)
- #ConditionalOnProperty (spring.data.jpa.repositories.enabled=true) matched (OnPropertyCondition)
Also, please don't use EnableAutoConfiguration together with SpringBootApplication, there is an exclude attribute on the latter as well.
Once I removed the exclude on DataSourceAutoConfiguration that error went away.
When I run the test, I get a dependency error of UserService is not able to be found to be injected. This is weird because no where in ConstantsController.java did I use UserService. Also, UserService is label properly with #Service annotation.
I have tried using the #MockBean annotation in the controller test class. It gave me unidentifiable errors. I even tried autowiring the bean in the configuration because the log said define bean of type of UserService in configuration. Still no luck.
UserService
package com.GMorgan.RateMyFriendv5.Service;
import com.GMorgan.RateMyFriendv5.Entitiy.Role;
import com.GMorgan.RateMyFriendv5.Entitiy.User;
import com.GMorgan.RateMyFriendv5.Repository.UserRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
#Slf4j
#Service
public class UserService {
private UserRepository repository;
public boolean login(String username, String password) {
List<User> userList = repository.findByUsername(username);
boolean isSuccessful = userList.get(0).isPassword(password);
log.info("Username: {} isSucessful: {}", username, isSuccessful);
return isSuccessful;
}
public boolean signUp(String email, String username, String password) {
if (userEmailExists(email) || userUsernameExists(username)) return false;
User user = new User();
user.setEmail(email);
user.setUsername(username);
user.setPassword(password);
user.setRole(Role.USER);
repository.save(user);
log.info("User email: {} username: {}", email, username);
return true;
}
public boolean userEmailExists(String email) {
return !repository.findByEmail(email).isEmpty();
}
public boolean userUsernameExists(String username) {
return !repository.findByUsername(username).isEmpty();
}
}
ConstantsController.java
package com.GMorgan.RateMyFriendv5.Controller;
import com.GMorgan.RateMyFriendv5.Utils.Mappings;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class ConstantsController {
#Value("${controller.constant.ping.message}")
public String pingMessage;
#RequestMapping(Mappings.PING)
public String ping() {
return pingMessage;
}
}
ConstantsControllerTest
#RunWith(SpringRunner.class)
#WebMvcTest
#AutoConfigureMockMvc
public class ConstantsControllerTest {
#Autowired
private MockMvc mockMvc;
#Value("${controller.constant.ping.message}")
public String pingMessage;
#Test
public void pingTest() throws Exception {
this.mockMvc.perform(get(Mappings.PING)).andDo(print()).andExpect(status().isOk())
.andExpect(content().string(containsString(pingMessage)));
}
}
I want the test to pass. In runtime, when I go to the link, I see the ping message. I want the test to do so as well.
you need to specify your controller that you want to test:
Add #WebMvcTest(ConstantsController.class) to your annotation
I'm trying to configure mongodb auditing in my spring boot app, and I having this error when trying to persist my domain class:
java.lang.IllegalArgumentException: Couldn't find PersistentEntity for type class com.example.hateoasapi.domain.Post!
Docs from here https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#auditing says that all this configs enough, but I don't know why it doesn't work in my project. Could someone help me?
My mongodb config class:
package com.example.hateoasapi.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.config.EnableMongoAuditing;
import org.springframework.data.mongodb.core.MongoTemplate;
import com.mongodb.MongoClient;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import java.util.Collection;
import java.util.Collections;
#Configuration
#EnableMongoAuditing
#EnableMongoRepositories(value = "com.example.hateoasapi.repository")
public class MongoConfig extends AbstractMongoConfiguration {
#Value("${spring.data.mongodb.database}")
private String databaseName;
#Value("${spring.data.mongodb.host}")
private String databaseHost;
#Value("${spring.data.mongodb.port}")
private Integer databasePort;
#Override
protected String getDatabaseName() {
return this.databaseName;
}
#Bean
#Override
public MongoClient mongoClient() {
return new MongoClient(databaseHost, databasePort);
}
#Bean
public MongoTemplate mongoTemplate() {
return new MongoTemplate(mongoClient(), databaseName);
}
#Override
protected Collection<String> getMappingBasePackages() {
return Collections.singleton("com.example.hateoasapi.domain");
}
}
AuditorAware implementation:
package com.example.hateoasapi.config;
import com.example.hateoasapi.domain.User;
import org.springframework.data.domain.AuditorAware;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import java.util.Optional;
#Component
public class SecurityAuditor implements AuditorAware<User> {
#Override
public Optional<User> getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
return null;
}
return Optional.of((User) authentication.getPrincipal());
}
}
And my domain class:
package com.example.hateoasapi.domain;
import javax.persistence.Id;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import org.joda.time.DateTime;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.mongodb.core.mapping.DBRef;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import org.springframework.hateoas.ResourceSupport;
import com.fasterxml.jackson.annotation.JsonCreator;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.*;
import java.io.Serializable;
import java.util.List;
import com.example.hateoasapi.controller.*;
#Getter
#Setter
#ToString
#Document
public class Post extends ResourceSupport implements Serializable {
#Id
#Field(value = "_id")
private String objectId;
#DBRef
private List<Comment> comments;
#DBRef
private User author;
#NotBlank
private String body;
#NotBlank
private String title;
private String categoryId;
#NotEmpty(message = "Tags cannot be empty")
private List<PostTag> tags;
#CreatedDate
private DateTime createdDate;
#LastModifiedDate
private DateTime lastModifiedDate;
#CreatedBy
private User createdBy;
private Long views;
private List<PostRating> likes;
private List<PostRating> dislikes;
#JsonCreator
public Post() {}
public Post(String title, String body) {
this.body = body;
this.title = title;
}
public Post(User author, String body, String title, String categoryId, List<PostTag> tags) {
this.author = author;
this.body = body;
this.title = title;
this.categoryId = categoryId;
this.tags = tags;
}
public void addLinks() {
this.add(linkTo(methodOn(PostController.class).getAllPosts(null)).withSelfRel());
}
}
I solved this issue with the next configuration:
#Configuration
#EnableMongoRepositories(basePackages = "YOUR.PACKAGE")
#EnableMongoAuditing
public class MongoConfig extends AbstractMongoConfiguration {
#Value("${spring.data.mongodb.host}")
private String host;
#Value("${spring.data.mongodb.port}")
private Integer port;
#Value("${spring.data.mongodb.database}")
private String database;
#Override
public MongoClient mongoClient() {
return new MongoClient(host, port);
}
#Override
protected String getDatabaseName() {
return database;
}
#Bean
public MongoTemplate mongoTemplate() throws Exception {
return new MongoTemplate(mongoDbFactory(), mappingMongoConverter());
}
#Bean
public MongoDbFactory mongoDbFactory() {
return new SimpleMongoDbFactory(mongoClient(), database);
}
}
just add the bean for MongoTemplate with the constructor of MongoTemplate(MongoDbFactory mongoDbFactory, #Nullable MongoConverter mongoConverter)
Quoting from JIRA ticket
You need to pipe the MappingMongoConverter that's available in the environment into MongoTemplate as well, i.e. use new MongoTemplate(dbFactory, converter). The constructor you use is for convenience, one-off usages. We usually recommend to use AbstractMongoConfiguration in case you'd like to customize anything MongoDB specific as this makes sure the components are wired together correctly.
More specifically, you need to inject pre-configured MappingMongoConverter or if you need to use your own converter, at least use pre-configured MongoMappingContext.
I had this problem also with spring boot 2.2
I had both #EnableMongoRepositories and #EnableMongoAuditing as configuration and i got the error Couldn't find PersistentEntity for type class
the problem in my case was the structure of the packages: Application class was a level lower than part of my model that used auditing.
I found on many forum posts that the 2 annotations are not compatible together in spring 2.2, but after restructuring the packages I was able to use both with success in spring boot 2.2
If you use the last version of Spring boot (2.0) and Spring Data, #EnableMongoAuditing
#EnableMongoRepositories are not compatible. It's the same with EnableReactiveMongoRepositories annotation.
If you want to enable mongo auditing, you need to remove your MongoConfig class, use config file to define your mongodb connection and everything will work.
If you use the last version of Spring boot (2.0) and Spring Data, #EnableMongoAuditing and #EnableMongoRepositories, try remove #EnableMongoRepositories. It should be working just this sample project - https://github.com/hantsy/spring-reactive-sample/tree/master/boot-data-mongo
Okay— I am assuming I am making a very obvious mistake here— but I can’t seem to find my answer through the several Google/SO searches I have done. My background with Java programming is heavily JSF based, and at work I only have experience using Faces to manage my beans (using the #Managed annotation). However, I am working on a personal project in which I am trying to use CDI for the first time. I am having trouble injecting a Service bean into a SessionScoped controller bean… It’s odd because I inject the same service bean into a different RequestScoped bean no problem… I don’t see what I am missing. I have the SessionScoped bean implementing Serializable, yet I am still getting the following error when I try to deploy, ONLY once I have added an #Inject variable to the bean (without which the bean will be pretty useless…): Caused by: org.apache.webbeans.exception.WebBeansConfigurationException: Passivation capable beans must satisfy passivation capable dependencies. Here’s a bit of my service and controller beans code:
UserService.java
import ds.nekotoba.model.User;
import java.util.Date;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.inject.Named;
import javax.persistence.EntityManager;
import org.apache.deltaspike.jpa.api.transaction.Transactional;
import org.apache.shiro.authc.credential.DefaultPasswordService;
import org.apache.shiro.authc.credential.HashingPasswordService;
import org.apache.shiro.crypto.hash.Hash;
#Named
#Transactional//Makes all methods in bean transactional
public class UserService {
#Inject
private EntityManager em;
public User findById(Long id) {
return em.find(User.class, id);
}
public User findByUsername(String username) {
return em.createNamedQuery("User.findByUsername", User.class)
.setParameter("username", username)
.getSingleResult();
}
public User find(String username, String password) {
List<User> found = em.createNamedQuery("User.find", User.class)
.setParameter("username", username)
.setParameter("password", password)
.getResultList();
return found.isEmpty() ? null : found.get(0);
}
#Produces
#Named("users")
#RequestScoped
public List<User> list() {
return em.createNamedQuery("User.list", User.class).getResultList();
}
public Long create(User user) {
….
}
public void update(User user){
em.merge(user);
}
public void delete(User user){
em.remove(em.contains(user) ? user : em.merge(user));
}
}
LoginController.java Note: The #Inject calls in this bean work no problem!
import ds.nekotoba.model.User;
import ds.nekotoba.service.UserService;
import ds.nekotoba.util.Globals;
import java.io.IOException;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.omnifaces.util.Faces;
import org.omnifaces.util.Messages;
#Named(value="login")
#RequestScoped
public class LoginController {
public LoginController() {
}
#Inject ProfileController profile;
#Inject UserService userService;
//Variables
private String username;
private String password;
private boolean remember;
//<editor-fold desc="Getters/Setters">
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isRemember() {
return remember;
}
public void setRemember(boolean remember) {
this.remember = remember;
}
//</editor-fold>
public void submit() throws IOException {
try {//Attempt login
SecurityUtils.getSubject().login(new UsernamePasswordToken(username, password, remember));
} catch (AuthenticationException ae) {
Messages.addGlobalError("不明なユーザ、また試してみてください。");
ae.printStackTrace();
}
//If successful, set User in ProfileController, get full user info
if(SecurityUtils.getSubject().isAuthenticated()){
User user = new User();
user.setUsername(username);
user.setPassword(password);
profile.setUserInfo(user);
//profile.refreshUserInfo(); //COMMENTED OUT DUE TO ERROR INJECTED IN ProfileController.java
}
//Redirect to intended page
SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(Faces.getRequest());
Faces.redirect(savedRequest != null ? savedRequest.getRequestUrl() : Globals.HOME_URL);
}
}
ProfileController.java (The error mentioned above manifests once I use any #Inject calls in this bean…)
import ds.nekotoba.model.User;
import ds.nekotoba.service.UserService;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import javax.inject.Named;
#Named(value="profile")
#SessionScoped
public class ProfileController implements Serializable {
#Inject UserService userService;//CAUSES ERROR MENTIONED ABOVE
//Variables
private User userInfo;
public ProfileController() {
}
public void refreshUserInfo() {
userInfo = userService.findByUsername(userInfo.getUsername());
}
//<editor-fold desc="Getters/Setters">
public User getUserInfo() {
return userInfo;
}
public void setUserInfo(User userInfo) {
this.userInfo = userInfo;
}
//</editor-fold>
}
Like I said, I am a new-comer to CDI injection, so I am sure I am missing something obvious… I just can’t figure it out. Any help would be greatly appreciated.
Other Project Info:
JSF 2.2
JPA 2.0
TomEE 1.7.1
OmniFaces 1.8.1
Apache Shiro 1.3.0-SNAPSHOT
Apache DeltaSpike (could this be a conflicting point?)
Foo implements Serializable is necessary but not sufficient for Foo to be serializable. All members of Foo also have to be serializable.
In your case, ProfileController is serializable, but its UserService member is not.