How to inject security context into CDI #Named bean?
I need to perform some custom validations, like dynamic role names validation, so I need to inject SessionContext. This is done with this:
#Resource
javax.ejb.SessionContext context;
But this injection only works in EJB beans, so I need to create an #Stateless bean just to wrap SessionContext, then I can inject this stateless bean into named bean and use it to access the security context.
I have tried with #Inject javax.security.enterprise.SecurityContext also, but this do not work at all.
Obs. If there is another approach, this will be welcome too!
Environment:
Wildfly 24
Java SE 11
References
No EjbContext available
https://www.baeldung.com/java-ee-8-security
Related
I am learning javaEE and I read somewhere about the main usage of cdi's was back then first in jsf-managed beans with annotations like #requestscope, #applicationscope, etc.. now in newer javaEE versions the cdi got available everywhere (even in ejb beans) so the question is, how do I have to annotate a class which shall be injected inside my local stateless ejb? I am asking this because the annotations like #RequestScope and all those are from jsf but I am not using jsf. Is #Default enough since its marked as default anyway? Is #Dependent better choice?
#Stateless
public class FooEjb{
#Inject Bar b;
}
// what annotation to put here?
public class Bar {
...
}
Yes you don't need JSF to use CDI in JavaEE.
If you are using CDI without using JSF, use the scope annotations from the javax.enterprise.context package.
#Default is a qualifier which as the name suggests the default qualifier. If you have multiple implementations/instances of the same class in your container, then you can use qualifiers to distinguish.
#Dependent is a scope which is the default scope. This means it will depend on the scope of the class it's injected in. A new instance of a #Dependent class will be injected every time a new instance of the class in which it is injected is created.
To enable CDI you need to put a beans.xml file in WEB-INF directory of your web project or META-INF directory of your EAR or EJB project.
According to the java ee documentation, no annotation is required in your case. A simple POJO is an injectable bean and receive the #Default annotation. No need to use JSF.
If I have a class which uses a spring bean, (will be wired via #Autowired).
I noticed that not only the class that will be injected needs the #Component but also the class the uses it (inject it). Why is it like that? Should not spring inject wherever #Autowired is? Without having to use #Component for the injector class?
Spring processes and manages only those classes which are marked by one of stereotype annotations #Component, #Controller, #Repository, #Service.
It does not scan all of your classes (that would make the startup very slow).
If the class is not managed by Spring it does not process any of the annotation inside that particular class.
In Spring, one works with beans. A bean is a java object that is managed by a spring context. When encountering a bean containing an #Inject, Spring will seach its context for a bean of the type of the variable to be injected. If no such bean is defined, Spring will have nothing to inject. Also, if the class with the #Inject doesn't have a bean, then Spring won't know about it, and thus cannot inject anything into it.
To get Spring to create a bean of a class, several methods are available. Through annotations, the class has to be annotated with #Component, or the more specialized annotations #Service, #Repository and #Controller. Only then will Spring create a bean for the class that can be #Injected into other beans.
so I have a RequestScoped bean that I am trying to inject UriInfo into using the Context annotation. The application is a JAX-RS based RESTful Web Service running on Wildfly 8 (and subsequently rest-easy). If I inject the UriInfo into the resource itself, it will inject correctly. If I try to inject it into any of the injected children, it will not inject and ends up null.
This was working for me on Web Sphere 8.5...but now it doesn't work on Wildfly 8. Any ideas? The source code is at https://github.com/rpg-maker-repo/rmmv-api. The resource is "com.trinary.rpgmaker.resource.PluginResource" and the place where I'm injecting the UriInfo is "com.trinary.rpgmaker.service.LinkGenerator". Currently I have the injection of UriInfo removed and the code that implemented it commented out. I have tried many ways of trying to inject it and none of them work.
Yes, the jaxrs-cdi integration is not fully specified and the implementations are free to enhance it to the extent that they want. Jersey (e.g. glassfish) has a very powerful integration and you can inject jaxrs' #Context into cdi beans (see http://hnusfialovej.cz/2015/02/25/jersey-further-improves-cdi-integration/). Resteasy's (e.g. Wildfly) integration isn't so straightforward but you can achieve injection of UriInfo into cdi beans via jaxrs providers (see http://blog.christianbauer.name/Accessing%20request%20details%20with%20JAX-RS%20and%20CDI/) (tested on wfly 10).
So you have a JAX-RS resource A which injects a CDI bean B and you want to use #Context to inject UriInfo into B?
Is there any reference in the Java EE spec to indicate that this is supposed to work?
I don't think so.
#Context is specific to JAX-RS and is not mentioned in the CDI 1.2 spec. It is not supported by CDI (unlike #PersistenceContext, #Resource and other legacy injections).
You could try to use a Provider which accesses the #Context:
#javax.ws.rs.ext.Provider
public class ContextInformationProducer {
#Produces
#RequestScoped
public ContextInformation create() {
ContextInformation contextInformation = new ContextInformation();
contextInformation.setBrowserUserAgent(httpHeaders.getHeaderString("User-Agent"));
}
Altough I am not sure if this is good practise, for which I have the following question:
Using #Context in JAX-RS Provider to provide context information to CDI beans
I am experimenting with Java Dependency Injection. Many questions here on SO talk about jndi resources being wired. But I think, a java class can be wired using #Resource annotation. I have a simple servlet in which I have two properties to be wired using CDI. I am using Tomcat6, Servlet 2.5, and Weld configuration.
The servlet code:
#Inject
private HikariConnectionProperties hikariConnectionProperties;
#Resource(name = "connectionProvider")
private IConnectionProvider connectionProvider;
However I get the code compiled, deployed. But, when there is a request for the corresponding servlet I get javax.naming.NameNotFoundException: Name connectionProvider is not bound in this Context.
But, I have #Named annotation for the ConnectionProvider class. The same configuration works with #Inject for both the fields.
So, my first question is how can I fix this issue? And is there any way that I can specify scope for a particular injection(using only annotations of JSR) without using Spring's #Scope? Any example is a great help as I am a newbie to CDI.
#Resource only works in Tomcat when you set up a resource in your container. Here's a reference for your own sake: http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html
It expects that you're binding a JNDI entry called "connectionProvider" in Tomcat. CDI does not bind elements to JNDI, it has its own internal mapping of objects to scopes. #Inject works here as you likely have not setup a resource for this class in your resource configuration.
I'm trying to write a servlet 3.0 web app, just to learn basic servlet handling. Normally i would use spring.
Now I have a servlet which access a DAO which queries the database. Now, what is the best way to instantiate that DAO and use it? My best guess would be to have a private property in the servlet and create an instance of the DAO when the servlet is created.
But, will the servlet be created multiple times?
Is there something similar to springs dependency injection available in servlet 3.0?
EJB 3 dependency injection is extremely simple to use. A single annotation, #EJB, causes the injection of a declared bean. The injection of the SomeDAO bean into a Servlet 3.0 looks like this:
#WebServlet(name="Messenger", urlPatterns={"/Messenger"})
public class Messenger extends HttpServlet {
#EJB
SomeDAO someDAO;
}
The injected SomeDAO bean could be an interface or a no-interface view bean. As long as there is only one implementation of the interface, it will be injected without any ceremony.
javax.servlet API is one of the technologies included in java-ee.
CDI, is the Context and Dependency Injection technology in java-ee
So to answer your question, your use case could be solved by using only CDI and Servlets.
But most of the application servers that supports above (e.g. TomEE, Glassfish webprofiles), will also support EJB (which uses cdi) and JPA. EJB+JPA can be used to implement DAOs.
Arjan Tijms has put together a nice link overview of what is included and happening in the java-ee-7 world