How to access CDI managed bean from JAX-RS MessageBodyWriter? - java

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

Related

Using interceptors for dependent scoped beans in vaadin CDI

I'm currently trying to implement logging via an interceptor with Vaadin CDI (running in Wildfly 9.0.1). The interceptor works well for beans with a proxy (I need to annotate the class with vaadins #NormalXXX-Scopes), but if the class has no scope specified (implicit #Dependent), no proxy is created and the interceptor doesn't work.
How can I enable interceptors for Dependent-Scoped beans?

What is EJB alternative in Spring Framework

I am trying to learn Spring Framework, before that I used to create application with EJBs
[Web services]->[Business Layer]->[DAO Layer] | [Database]
in following way
WebServices: Restful API using Jersey with url mappings, that support both JSON and XML format( news/list.json, news/list.xml). Once a request is received by an endpoint(url-mapped-method) it is forwarded to a relevant EJB through lookup(remote, local). EJB process every thing, apply business rules and return result as DTO(Data transfer object),Service then transform the result into required format (JSON, XML)
Business Layer: Business Layer (Facade) implemented in EJB with remote and local interfaces, these EJBs can call other EJBs. WebService layer(and/or Timer service and MDBs) can also call any of the EJBs). For timer service related functionality I used EJB Timer Service and for Messages used Message Drive Bean and interceptor for logging and auditing.
DAO Layer: All the Database related functions(add,edit, delete, search) JPA/Hibernate using EntityManager are written here (Entity beans and HQL).
Seamless Transaction support, each EJB's method (lookup-based) call is treated as a separate transaction and calling methods of DAO layer are part of same transaction(provided that no extra configuration is provided). multiple operations are carried out in a single transaction If one db operation fails all others are roll backed automatically. Each Table is mapped as an entity class with relations etc.
I have worked on Spring MVC but could not map/understand correctly for above architecture
I know bit about AOP and that I think is a perfect replacement for Interceptors (or at least it work for me)
Now my question is how all these could be replaced in Spring framework?
Jersey (RestAPi) alternative in Spring>
EJB alternative in Spring (as EJB supports remoting, each lookup call to a method is treated as a transaction, calls to EJB's method could be intercepted and it comes with state-full and stateless flavors)?
Timer Service alternative in Spring?
Message Drive Bean alternative in Spring?
Interceptor alternative is AOP in Spring (As per my experience and that serve my purpose)
JPA(entity manager) alternative in spring?
Jersey (RestAPi) alternative in Spring?
Spring MVC does this perfectly fine, in my opinion. Just annotate your methods in your controller as the REST apis you want to use.
EJB alternative in Spring (as EJB supports remoting, each lookup call to a method is treated as a transaction, calls to EJB's method could be intercepted and it comes with state-full and stateless flavors)?
There is no full alternative. There are several techniques that implement this in parts: Spring remoting for remote calls, Spring transactions as transactions, Spring AOP interceptors for intercepting calls. However, for example XA transactions on remote calls are something you don't get as such in Spring. Spring however works fine with EJBs, so if you prefer them, you can still have them and use Spring in other parts of your software.
Timer Service alternative in Spring?
Spring task scheduling
Message Drive Bean alternative in Spring?
Message Listener Containers
Interceptor alternative is AOP in Spring (As per my experience and that serve my purpose)
There are several levels of interceptors in spring. There are handler interceptors in mvc, there are bean call interceptors like the SpringAutowiringInterceptor, and there are AOP-based interceptors that can be used in multiple layers.
JPA(entity manager) alternative in spring?
Spring has multiple of these as well. It's actually quite straightforward to just use JPA with Spring-Data, it's designed to integrate to JPA. There are Spring JDBC and other data layer alternatives though if Spring Data is not what you want.
Jersey (RestAPi) alternative in Spring ⇨ it's rest api (in spring with #Path annotation) or spring mvc if you want to use controllers (#Controller annotation)!
EJB alternative in Spring ⇨ Spring doesn't give statefull bean out of a box but you can use #Service annotation (or #Repository for DAO) but you have to handle transactions manually (with annotations for example)
Message Drive Bean alternative ⇨ There is no equivalent out of the box in Spring, you could use injection and librairies of Spring to get it working (package org.springframework.jms should contains what you need)!
JPA(entity manager) alternative is not ejb ⇨ so it can be used in Spring.
Spring is a lighweight library so you can do all you do with EJB but it's more configurable so you will have more work to do the same that EJB do. But this configuration brings you some advantages: you have the hand on it!
This explains Spring and Java EE (which is what you would have used EJBs in) side by side: http://www.slideshare.net/reza_rahman/java-ee-and-spring-sidebyside-34320697
Jersey offers Spring solutions too - see their website
Spring does support remote calls through, e.g., RMI; It also supports transactions; AFAIK, no explicit stateful/stateless Spring Components - it depends on how you use it
AFAIK nothing as awesome as TimerService, however, you could use Quartz
Spring offers MDPs (Message-Driven POJOs)
Spring does support JPA - see first link.
Another cool comparison slideshare: http://www.slideshare.net/kelapure/java-e-evsspringshootout

Wildfly 8/JAX-RS: UriInfo is null when injected into RequestScoped bean

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

dependency injection in a servlet 3.0 web app?

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

Constructor dependency injection with Servlet 3.0?

Since Servlet 3.0 it is possible to register Servlet instances programmatically with javax.servlet.ServletContext#addServlet. This class has also a createServlet method which analyses some annotations and performs dependency injection. I wonder if I need this method if I don't need the annotation processing. I'd like to have a servlet with a usual constructor to set required dependencies via dependency injection.
#Inject
public MyServlet(SomeDependency sd) { // Constructor
...
}
Questions:
Is it possible to construct a servlet instance "by hand" without createServlet? (new MyServlet())
Is it possible to use the dependency injection mechanism of a Java EE server to perform constructor injection? How to do it? Or is a separate DI framework like Guice required?
The recent Java EE 6 standard now supports dependency injection for servlets, the relevant part is called JSR-299 or CDI. The JSR-299 reference implementation, JBoss weld, can be deployed into servlet containers like Tomcat or Jetty as well if you don't want to use a full Java EE 6 application server like glassfish v3 e.g.
By the way, with an embedded Jetty server you can use its custom API to add preconfigured servlet instances.
Guice does this out of the box without the need for Java EE servers.
http://code.google.com/p/google-guice/wiki/ServletModule

Categories

Resources