Хорошо. Я предполагаю, что я делаю очень очевидную ошибку здесь, но я не могу найти ответ на него через несколько поисков Google/SO, которые я выполнил. Мой опыт программирования на Java в значительной степени основан на JSF, и на работе у меня есть опыт использования Faces для управления моими бобами (с использованием аннотации @Managed
). Тем не менее, я работаю над личным проектом, в котором я пытаюсь использовать CDI в первый раз. У меня возникли проблемы с вводом компонента Service в компонентный компонент SessionScoped
... Это странно, потому что я вставляю тот же сервисный компонент в другой bean-компонент RequestScoped
без проблем ... Я не вижу, чего мне не хватает. У меня есть компонент SessionScoped
, реализующий Serializable
, но я все еще получаю следующую ошибку при попытке развернуть: ТОЛЬКО после того, как я добавил переменную @Inject
в bean-компонент (без которого компонент будет бесполезен ...): Caused by: org.apache.webbeans.exception.WebBeansConfigurationException: Passivation capable beans must satisfy passivation capable dependencies.
немного моя служба и контроллер фасоли кода:Проблема с простой вставкой CDI ... Связанная с ошибкой «Пассивация» при использовании @Inject в компоненте SessionScoped Controller
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 Примечания: @Inject
вызовов в этой бобовой работе не проблема!
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 (Ошибка упоминалось выше манифестов раз я использую любые @Inject
вызовы в этом компоненте ...)
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>
}
Как я уже сказал, я новый пришелец в КДИ инъекции, поэтому я уверен, что мне не хватает чего-то очевидного ... Я просто не могу понять. Любая помощь будет принята с благодарностью.
Другая информация Проект:
JSF 2,2
JPA 2,0
TomEE 1.7.1
OmniFaces 1.8.1
Apache Shiro 1.3.0-SNAPSHOT
Apache DeltaSpike (это могло быть и противоположная точка ?)
Хорошо ... Итак, какие у меня варианты? Я просто реализую Serializable в UserService? Я не хочу менять его. Я должен попробовать это, когда вернусь домой. Спасибо за совет. – mousouchop
Спасибо за этот улов, это была моя проблема. Теперь я понимаю, что класс шаблонов, который мы используем в проектах на работе, все реализует 'Serializable', как правило, поэтому я никогда раньше не сталкивался с этим конкретным исключением. Еще раз спасибо! – mousouchop
Как указано в моем предыдущем комментарии - общая тенденция в моей работе - просто реализовать «Serializable» на всех компонентах Controller/Service/Model ... это обычная практика, чтобы избежать неожиданных и, казалось бы, случайных ошибок, таких как то, что я выше, когда вводится/разрешается экземпляр компонента? Есть ли лишние накладные расходы, связанные с этим подходом? Или это отраслевой стандарт? – mousouchop