I have an Apache Wicket 1.5 application that uses Shiro for security, and Guice for dependency injection.
Most of its pages are stateless, but some of my model objects (user data, current menu state, ...) need to be consistent across all requests in the same session. All of these objects have both logic (mostly simple finder methods using remote EJB3 interfaces to access a database) and state, and all of them implement Serializable.
Here's a short excerpt that should convey the idea:
#SessionScoped
public class UsersImpl implements Users, Serializable {
private static final long serialVersionUID = 8841809043461673585L;
private final Logger log = LoggerFactory.getLogger( UsersImpl.class );
#Inject
public UserService users;
#Inject
public RoleService roles;
private UserDTO currentUser;
public UserVO findUserByUser( UserVO user ) {
UserDTO userDto = null;
try {
userDto = users.findUserByUser( user.toUserDTO() );
} catch( Exception e ) {
log.error( "Error finding user:"+user.id, e );
}
return userDto != null ? new UserVO( userDto ) : null;
}
(...)
}
I developed and unit tested the classes using #Singleton (for simplicity), and everything works fine this way, but I get frequent errors like this, now that I have switched to #SessionScoped for production:
Guice provision errors:
1) Error in custom provider, org.apache.shiro.session.InvalidSessionException:
java.lang.IllegalArgumentException:
HttpSession based implementations of the Shiro Session interface requires attribute keys to be String objects. The HttpSession class does not support anything other than String keys.
Obviously, Guice seems to use some custom Key object to store the objects in the session, and the Shiro HttpSession implementation can't handle that. Strangely enough, though, this exception does not occur for all of the #SessionScoped classes, but certainly for more than one.
I have been searching the web like crazy, looking for an idea what I could do - some way to force Guice to use Strings for keys, some other way to make the HttpSession more compatible, anything - but I can't seem to find any helpful information. Also, judging from my search results for the error message, I seem to be the only person on the planet who even has this problem at all...
Is there any way to make this work? Or am I doing something wrong here?
Well, this question is hard to answer, but i try to give you some options...
You error is from upfront checking... so, i assume your application did not even start, right? Then you are very likely using Production stage or there is some binding eagerly created and that object refers to another in Session scope, which is problem. So, now you should change all your SessionScope direct injection to Providers injection as in this example:
Could you change
#Inject
public UserService users;
to
#Inject
public Provider<UserService> userProvider; //and call userProvider.get() when you will need it?
Why so?
SessionScoped objects are accessible only whitin GuiceFilter.doFilter() so if you mixing scopes it could end up in some runtime exceptions. Especially, when you change Stage to Production or set some Singletons to eagerly loaded. You can learn more here. It is good practice to use Providers when mixing Scopes
The problem could be that the Subject is bind only inside ShiroFilter.doFilter() check my post. Then, if you are outside let say GuiceFilter the could be no Subject bound at that time. Again, try to use Providers.
Hope, will help a little.
Related
I'm trying to get used to how JSF works with regards to accessing data (coming from a spring background)
I'm creating a simple example that maintains a list of users, I have something like
<h:dataTable value="#{userListController.userList}" var="u">
<h:column>#{u.userId}</h:column>
<h:column>#{u.userName}</h:column>
</h:dataTable>
Then the "controller" has something like
#Named(value = "userListController")
#SessionScoped
public class UserListController {
#EJB
private UserListService userListService;
private List<User> userList;
public List<User> getUserList() {
userList = userListService.getUsers();
return userList;
}
}
And the "service" (although it seems more like a DAO) has
public class UserListService {
#PersistenceContext
private EntityManager em;
public List<User> getUsers() {
Query query = em.createQuery("SELECT u from User as u");
return query.getResultList();
}
}
Is this the correct way of doing things? Is my terminology right? The "service" feels more like a DAO? And the controller feels like it's doing some of the job of the service.
Is this the correct way of doing things?
Apart from performing business logic the inefficient way in a managed bean getter method, and using a too broad managed bean scope, it looks okay. If you move the service call from the getter method to a #PostConstruct method and use either #RequestScoped or #ViewScoped instead of #SessionScoped, it will look better.
See also:
Why JSF calls getters multiple times
How to choose the right bean scope?
Is my terminology right?
It's okay. As long as you're consistent with it and the code is readable in a sensible way. Only your way of naming classes and variables is somewhat awkward (illogical and/or duplication). For instance, I personally would use users instead of userList, and use var="user" instead of var="u", and use id and name instead of userId and userName. Also, a "UserListService" sounds like it can only deal with lists of users instead of users in general. I'd rather use "UserService" so you can also use it for creating, updating and deleting users.
See also:
JSF managed bean naming conventions
The "service" feels more like a DAO?
It isn't exactly a DAO. Basically, JPA is the real DAO here. Previously, when JPA didn't exist, everyone homegrew DAO interfaces so that the service methods can keep using them even when the underlying implementation ("plain old" JDBC, or "good old" Hibernate, etc) changes. The real task of a service method is transparently managing transactions. This isn't the responsibility of the DAO.
See also:
I found JPA, or alike, don't encourage DAO pattern
DAO and JDBC relation?
When is it necessary or convenient to use Spring or EJB3 or all of them together?
And the controller feels like it's doing some of the job of the service.
I can imagine that it does that in this relatively simple setup. However, the controller is in fact part of the frontend not the backend. The service is part of the backend which should be designed in such way that it's reusable across all different frontends, such as JSF, JAX-RS, "plain" JSP+Servlet, even Swing, etc. Moreover, the frontend-specific controller (also called "backing bean" or "presenter") allows you to deal in a frontend-specific way with success and/or exceptional outcomes, such as in JSF's case displaying a faces message in case of an exception thrown from a service.
See also:
JSF Service Layer
What components are MVC in JSF MVC framework?
All in all, the correct approach would be like below:
<h:dataTable value="#{userBacking.users}" var="user">
<h:column>#{user.id}</h:column>
<h:column>#{user.name}</h:column>
</h:dataTable>
#Named
#RequestScoped // Use #ViewScoped once you bring in ajax (e.g. CRUD)
public class UserBacking {
private List<User> users;
#EJB
private UserService userService;
#PostConstruct
public void init() {
users = userService.listAll();
}
public List<User> getUsers() {
return users;
}
}
#Stateless
public class UserService {
#PersistenceContext
private EntityManager em;
public List<User> listAll() {
return em.createQuery("SELECT u FROM User u", User.class).getResultList();
}
}
You can find here a real world kickoff project here utilizing the canonical Java EE / JSF / CDI / EJB / JPA practices: Java EE kickoff app.
See also:
Creating master-detail pages for entities, how to link them and which bean scope to choose
Passing a JSF2 managed pojo bean into EJB or putting what is required into a transfer object
Filter do not initialize EntityManager
javax.persistence.TransactionRequiredException in small facelet application
It is a DAO, well actually a repository but don't worry about that difference too much, as it is accessing the database using the persistence context.
You should create a Service class, that wraps that method and is where the transactions are invoked.
Sometimes the service classes feel unnecessary, but when you have a service method that calls many DAO methods, their use is more warranted.
I normally end up just creating the service, even if it does feel unnecessary, to ensure the patterns stay the same and the DAO is never injected directly.
This adds an extra layer of abstraction making future refactoring more flexible.
I love dependency injection frameworks and how they allow me to request the one object everything starts with. All the wiring is made on the first request for that "master" object.
However, there are objects that should be created during runtime, e.g. based on user input. And sometimes those newly created objects should be shared among other objects created by the framework.
My current approach is to have "uninitialized" objects injected by the framework. During runtime I set up the object with setter methods as soon as possible.
What I don't like with this approach is that the setter methods are really invoked only once and should then never be touched again. This prevents me from declaring the fields as final. I don't now how to create the object not before all necessary information is available without losing all the benefits from the DI framework.
I'm new to DI. Are there any good patterns for this?
Example:
// The service is used through out the application
interface Service {
makeRequest()
}
What I want to do after user typed in credentials:
new ConcreteService(username, password)
// but now I need to inject the concrete servive manually everywhere I need it!
What I'm currently doing:
interface Service {
makeRequest()
setCredentials(username, password)
}
// service can be injected by framework, but I don't like setter methods
// that much (and they can pollute the interface)
Most of my experience with dependency injection is with C# but I believe the concept remains the same no matter what language.
What I understand from the original poster is that he's trying to "persist" information within the dependency injection container in order to retrieve the information at a later time.
The problem with this approach is that, in a multi-threaded scenario, there's the possibility that the dependency that you are using to persist information has its values overwritten by another thread. This can happen because the dependency injection container usually holds a single instance of the object which is returned to you whenever you need it. Therefore, you need to make sure that your design is thread safe.
In my experience, using the dependency injection container to maintain state is bad.
What you register in your dependency injection container are the objects that provide a "service" and that don't maintain any state.
Objects that you use to hold information are usually business objects. These business objects should just be instantiated with "new" (without the dependency injection container), populate them in the usual manner (with setters or initialization method or constructor) and just be passed on as part of the signature of the operations that your services expose.
Note: You can register your dependency as "transient" which would tell the dependency injection container to return a new instance every time you ask for the dependency. This would avoid the need to use the "new" keyword explicitly and give you more control when writing unit tests with a mocking framework.
Hope this helps!
One way you could do it would be to use a factory.
For example, say you had this class...
public class UserBean {
private int userId;
private UserService userService;
// other resources / dependency fields etc
public UserBean(int userId, UserService userService, ...other dependencies...) {
this.userService = userService;
this.userId = userId;
this.... = ...
}
// ...getter for userId maybe etc...
// Some method that uses the user's data AND the component/service you want to inject from Spring...
public void incrementHitCount() {
userService.incrementHitCount(userId);
}
}
...where "userService" is something you want that is managed by the IoC container. If you then have a component that needs to create one of these, e.g....
#Component
public class UserHitCountIncrementerThing {
public ResponseBean doThatThing(HttpServletRequest request) {
int userId = request.<get the user Id from it...>
UserBean userbean = new UserBean(userId, /* need dependencies here! */);
...do stuff...
}
}
You could just #Autowire in all of the services to this bean, or you could create a factory and just #Autowire one, for example...
#Component
public class UserBeanFactory {
#Autowired
private UserService userService
//...other #Autowired dependencies...
public UserBean createUser(int userId) {
return new UserBean(userService, ...etc..., userId);
}
}
Now just use this where you need it, e.g...
#Component
public class UserHitCountIncrementerThing {
#Autowired
private UserBeanFactory userFactory;
public ResponseBean doThatThing(HttpServletRequest request) {
int userId = request.<get the user Id from it...>
UserBean userbean = userFactory.createUser(userId);
...do stuff...
}
}
Is this what you were getting at?
Hope this helps.
I was trying to get simple webapp working with Guice and JPA on Jetty, using the persistence and servlet guice extensions.
I have written this Service implementation class:
public class PersonServiceImpl implements PersonService {
private EntityManager em;
#Inject
public PersonServiceImpl(EntityManager em) {
this.em = em;
}
#Override
#Transactional
public void savePerson(Person p) {
em.persist(p);
}
#Override
public Person findPerson(long id) {
return em.find(Person.class, id);
}
#Override
#Transactional
public void deletePerson(Person p) {
em.remove(p);
}
}
And this is my servlet (annotated with #Singleton):
#Inject
PersonService personService;
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String name = req.getParameter("name");
String password = req.getParameter("password");
String email = req.getParameter("email");
int age = Integer.valueOf(req.getParameter("age"));
Person p = new Person();
p.setAge(age);
p.setName(name);
p.setEmail(email);
p.setPassword(password.toCharArray());
logger.info("saving person");
personService.savePerson(p);
logger.info("saved person");
logger.info("extracting person");
Person person = personService.findPerson(p.getId());
resp.getWriter().print("Hello " + person.getName());
}
When I run this it works, and I get the name sent to the client, but when I look at the log I see that there is no DML generated for the insertion and selection from postgresql does not return any results, which means it wasn't really persisted.
I debugged through the code and I saw that JpaLocalTxnInterceptor called txn.commit().
Then I made a change to PersonServiceImpl and used Provider<EntityManager> instead of just EntityManager and it worked as expected. Now I don't really understand why and it's probably because I don't really understand the idea behind Provider.
On the Guice wiki page it says:
Note that if you make MyService a #Singleton, then you should inject Provider instead.
However, my PersonServiceImpl is not a #Singleton so I am not sure why it applies, perhaps it's because of the Servlet?
I would really appreciate if you could clear this out for me.
You need Provider<EntityManager> because Guice's built-in persistence and servlet extensions expect EntityManager to be request-scoped. By injecting a request-scoped EntityManager from a service held in a singleton servlet, you're making a scope-widening injection, and Guice won't store data from a stale, mismatched EntityManager.
Providers
Provider is a one-method interface that exposes a get() method. If you inject a Provider<Foo> and then call get(), it will return an instance created the same way as if you had injected Foo directly. However, injecting the Provider allows you to control how many objects are created, and when they are created. This can be useful in a few cases:
only creating an instance if it's actually needed, especially if the creation takes lots of time or memory
creating two or more separate instances from within the same component
deferring creation to an initialization method or separate thread
mixing scopes, as described below
For binding of X, Provider<X>, or #Provides X, Guice will automatically allow you to inject either X or Provider<X> directly. You can use Providers without adjusting any of your bindings, and Providers work fine with binding annotations.
Scopes and scope-widening injections
Broadly speaking, scopes define the lifetime of the object. By default, Guice creates a new object for every injection; by marking an object #Singleton, you instruct Guice to inject the same instance for every injection. Guice's servlet extensions also support #RequestScoped and #SessionScoped injections, which cause the same object to be injected within one request (or session) consistently but for a new object to be injected for a different request (or session). Guice lets you define custom scopes as well, such as thread scope (one instance per thread, but the same instance across injections in the same thread).
#Singleton public class YourClass {
#Inject HttpServletRequest request; // BAD IDEA
}
What happens if you inject a request-scoped object directly from within a #Singleton component? When the singleton is created, it tries to inject the instance relevant to the current request. Note that there might not be a current request, but if there is one, the instance will be saved to a field in the singleton. As requests come and go, the singleton is never recreated, and the field is never reassigned--so after the very first request your component stops working properly.
Injecting a narrow-scope object (#RequestScoped) into a wide scope (#Singleton) is known as a scope-widening injection. Not all scope-widening injections show symptoms immediately, but all may introduce lingering bugs later.
How Providers help
PersonService isn't annotated with #Singleton, but because you're injecting and storing an instance in a #Singleton servlet, it might as well be a singleton itself. This means EntityManager also has singleton behavior, for the same reasons.
According to the page you quoted, EntityManager is meant to be short-lived, existing only for the session or request. This allows Guice to auto-commit the transaction when the session or request ends, but reusing the same EntityManager is likely preventing storage of data any time after the first. Switching to a Provider allows you to keep the scope narrow by creating a fresh EntityManager on every request.
(You could also make PersonService a Provider, which would also likely solve the problem, but I think it's better to observe Guice's best practices and keep EntityManager's scope explicitly narrow with a Provider.)
I have 2 Stateless EJBs StatelessA and StatelessB, both of them have interceptors InterceptorA and InterceptorB respectively. Also, StatelessB has Asynchronous methods. Something like this:
#Stateless
#Interceptors(InterceptorA.class)
public class StatelessA{...
#Stateless
#Asynchronous
#Interceptors(InterceptorB.class)
public class StatelessB{...
When calling a method on StatelessA, it calls several StatelessB methods and returns a value.
I am trying to develop 2 interceptors to store the total time and the subtotal times of StatelessB calls, this is the objective of the interceptors.
I need to do it so InterceptorA can see the detail of InterceptorB data, so I store only a value in the DB, containing the total time (of SLSB A) and the subtotal times (of SLSB B).
I tried using a ThreadLocal variable (containing a list of times, something like long[]), which works fine if StatelessB is not asyncrhonous.
The problem is that when it is asynchronous, the variable is not available, since it is running in a different thread (AFAIK).
I also tried injecting EJBContext or using the InvocationContext, but none of them works.
Can someone point me out what other alternatives do I have?
Thanks in advance.
I was thinking this over and over, and arrived to a solution, which is using the security context to pass data.
The solution involves using the only data propagated in an asynchronous invocation, as specified in EJB 3.1:
4.5.4 Security Caller security principal propagates with an asynchronous method invocation. Caller security principal propagation
behaves exactly the same for asynchronous method invocations as it
does for synchronous session bean invocations.
In JBoss, one can access the security context and use a data map in it to pass the values from InterceptorA to InterceptorB, as follows:
In InterceptorA:
SecurityContext securityContext = SecurityContextAssociation.getSecurityContext();
securityContext.getData().put("interceptorAData",data);
In InterceptorB:
SecurityContext securityContext = SecurityContextAssociation.getSecurityContext();
securityContext.getData().get("interceptorAData");
I tested it and it works great in JBoss EAP 6.1.
This solution implies couplig the interceptor to the server implementation (JBoss AS), but the principle works for other servers.
The advantage is that it decouples the application logic from the interceptors, which was the first objective.
I appreciate any comments.
Would it work to store the information you need in an #Entity object and then use the #PersistenceContext annotation to inject an EntityManager into the beans to persist and find the data? Something like:
#PersistenceContext
EntityManager entityManager;
...
method() {
MyEntityTimer met = new MyEntityTimer(getCurrentTime(), id);
entityManager.persist(met);
}
...
elsewhere:
MyEntityTimer met = entityManager.find(MyEntityTimer.class, id);
and:
#Entity
#Table(name = "TABLE")
public class MyEntityTimer {
#Id
#Column(name = "ID")
private int id;
...
}
I'll answer my question with what I ended up doing.
The only way I found to pass a variable from interceptor A to interceptor B was adding a parameter to the EJBs A and B, something like this:
#Stateless
#Interceptors(InterceptorA.class)
public class StatelessA{
public void methodA(Object reserved, ...other params )
#Stateless
#Asynchronous
#Interceptors(InterceptorB.class)
public class StatelessB{
public void methodB(Object reserved, ...other params)
This way, when InterceptorA is called, I'll set the reserved parameter with the data I need to share with InterceptorB.
InterceptorB will access this variable with no issue getting it from the parameters.
The down side to this solution is that the dummy parameters are needed, coupling in some way the EJBs with the interceptors..
I've been going through the Play! 2.1 example to setup a basic login system following the ZenTasks example. Where I get stuck is the JavaForms part. I want to validate the login request using an instance of an auth service that is provided via Guice DI.
I'm following Play20 Sample. This example uses a static authenticate() method to run the authentication when form validation is requested after form submission. Any thoughts on how to perform this validation step in a non-static scope?
Note: I have looked at the Play! Authenticate plugin as well as the SecureSocial plugin, however those projects are overkill for what I want to do right now. Also, I am interested in a general solution for allowing non-static validation in JavaForms.
Edit:
It seems there is some confusion about what I am asking for here. What I am hoping to find is an alternate way to perform the validation step of the form submission that is sent by a Play! framework Form.form() generated form. Currently it requires that a validate() method be called on an instance of a POJO which is not created through the DI framework. This results in static references being required to access authorization services etc...
Edit 2:
The current solution I am working with is this:
public static class AuthServiceFormReference {
#Inject
public static Provider<AuthService> authService;
}
// In my auth module configure()
//...
requestStaticInjection(AuthController.AuthServiceFormReference.class);
//...
public static class Login {
#Required
public String email;
#Required
public String password;
public String validate(){
if(AuthServiceFormReference.authService.get().authenticateAdmin(email, password) == null) {
return "Invalid user or password";
}
return null;
}
}
It's an okay workaround, but it still relies on static injection :(
Play Framework does not offer Dependency Injection out of the box. However you can integrate it with Guice or Spring. As a lazy developer you could also create a Singleton for the service, or make it a plugin (as it probably needs to prepare work on application startup anyways). Then you can get a reference to your plugin -- Play.application().plugin(AuthPlugin.class).
In this particular case you can do a database lookup in the validate methods, e.g. User u = User.find.where().eq("username", username).eq("password`,password).findUnique();
if (u == null)
return "Error.";
else
return null;
So this isn't so much about Play Framework, but Java programming in general.
Assuming you use Spring, you can do it like in any other Java program:
#Configurable
public class MyModel {
#Autowired
transient MyService myService;
public String validate() { ... }
}
The #Configurable annotation makes the class capable of dependency injection. The transient qualifier makes sure the field doesn't get picked up as a field to save into a database.
Spring works fine with Play 2.0/2.1 in one of my projects. I don't consider dependency injection in model objects aesthetically pleasing, but if you need it you can use it.