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
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.
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
I'm struggling with accessing CDI managed beans from a JAX-RS message body handler in TomEE.
My handler class (implements MessageBodyWriter<Object>, MessageBodyReader<Object>) is registered via the cxf.jaxrs.providers property in openejb-jar.xml. When I use the #Inject annotation on the constructor, the handler is silently ignored (because it then lacks a no-arg constructor). When using field injection instead, the field stays empty. Obviously, message body handlers are entirely unmanaged in TomEE (CXF).
I tried getting the BeanManager via JNDI, but that fails without logging an exception.
Is there any other way to do this, or am I doing something wrong? Alternatively, I would of course appreciate a way to make the handler itself managed, and register it programmatically somehow.
Injection should work just fine in versions of CXF >= 2.7. Prior versions utilize JAX-RS 1.x, which is not tightly integrated with CDI. In particular, JAX-RS 1.x providers, even in the presence of a CDI container, are managed by the JAX-RS runtime (not the CDI one), and only support the following injection annotations:
#Resource
#Resources
#EJB
#EJBs
#WebServiceRef
#WebServiceRefs
#PersistenceContext
#PersistenceContexts
#PersistenceUnit
#PersistenceUnits
References:
JAX-RS 1.0 specification, Section 6.2
JAX-RS 2.0 specification, Section 10.2.3
Apache CXF - Migrating from JAX-RS 1.1 to 2.0
The following is the situation :
I have a business layer, that is an EJB project. In fact, there is only one EJB that is created. This EJB is responsible to expose the service classes to other layers, that calls the EJB. I want to introduce spring (to use DI feature) in this layer.
My concern is, what is the best way to load the spring context in this business layer, so that the spring context does not get loaded again and again, whenever the EJB gets called ?
(In a Web project, there is an advantage rather to configure the spring context in contextLoaderListener, and it gets loaded once only when the application gets started)
I have thought of including spring in the same layer because :
Configure the dependencies of all DAO and service classes and inject them wherever necessary.
To use spring support for hibernate in the business layer.
Ease of Unit testing, by injecting the properties into classes and simulating the same. Don't need to run the other layers again and again, to test my business classes/methods.
To be able to use AOP (Aspect Oriented Programming) for Logging and method level auditing.
Kindly help me suggesting the best way, to load the spring context in an EJB project. I also want to know , if there are any alternatives if I can load the same in the app server (I am using Web sphere app server).
Thanks and Regards,
Jitendriya Dash
Spring should be configured as part of your application in the normal way that you always set it up. Then you need to access the Spring beans from the EJB layer. To access (adapted from this post), create a Spring bean as follows:
#Component
public class SpringApplicationContext implements ApplicationContextAware {
private static ApplicationContext CONTEXT;
public void setApplicationContext(ApplicationContext context) throws BeansException {
CONTEXT = context;
}
public static Object getBean(String beanName) {
return CONTEXT.getBean(beanName);
}
}
Then, to call the bean in question from the legacy app:
SomeService someService = (SomeService)SpringApplicationContext.getBean("someServiceImpl");
The Spring context is initialized once, and your EJB layer can access at will.
For EJB3, Spring recommends using an EJB3 Injection Interceptor. Basically you specify your Spring context using a ContextSingletonBeanFactoryLocator which entails creating your Spring context in a beanContextRef.xml in your classpath. Probably as part of your EAR. The SpringBeanAutowiringInterceptor injects your bean into your EJB.
Marking the EJB been as a Singleton (#Singleton). And storing the spring context in a variable in this bean, after it is created once, so that you can return the same context again and again.