#EJB annotation not working for REST API class file - rest

#EJB not working, returning null pointer exception when used. I am using jersey. It is working in the similar project of jersey earlier.
Rest API class
#Path("")
public class Services
{
#EJB
UserSessionBeanLocal userBean;
#POST
#Produces(MediaType.APPLICATION_JSON)
#Path("register")
public Response register(#FormParam("userName") final String name, #FormParam("userPassword") final String pass, #FormParam("userEmail") String email)
{
if (userBean.isEmailRegistered(email)) // userBean is null here
{
// code
}
}
}
Stateless EJB
#Stateless
public class UserSessionBean implements UserSessionBeanLocal
{
static ArrayList<User> usersList = new ArrayList<User>();
static int userCount = 0;
User u = null;
#Override
public boolean isEmailRegistered(final String email)
{
return usersList.stream().anyMatch(d -> d.getEmail().equals(email));
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.enovate.assignment.ejb1</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/user/*</url-pattern>
</servlet-mapping>
</web-app>
Any help is appreciated. Thanks in advance.
I was expecting it should work fine. Now I have to use the JNDI lookup way to instantiate the bean.
As I mentioned it is working in almost similar project. I found something that #EJB does not work in non-managed bean if is related, but I don't understand it.

Related

MessageBodyWriter not found for media type={application/xml, q=1000} - Jersey + Jaxb

I am writing a RESTful web service with Jersey. I want to return a custom object in XML form to consumer. The error I am getting is:
MessageBodyWriter not found for media type={application/xml, q=1000}, type=class com.test.ws.Employee, genericType=class com.test.ws.Employee.
Below is the code:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>com.vogella.jersey.first</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<!-- Register resources and providers under com.vogella.jersey.first package. -->
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.test.ws</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Service Class
package com.test.ws;
#Path("/hello")
public class Hello {
#GET
#Path("/sayHello")
#Produces(MediaType.APPLICATION_XML)
public Employee sayHello() {
Employee employee = new Employee();
employee.setEmpId(1);
employee.setFirstName("Aniket");
employee.setLastName("Khadke");
return employee;
}
}
Employee.java
package com.test.ws;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "employee")
public class Employee {
public String firstName;
public String lastName;
public int empId;
public Employee(String firstName, String lastName, int empId) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.empId = empId;
}
public Employee() {
super();
}
#XmlElement
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
#XmlElement
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
#XmlElement
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
}
And here is the list of libraries added:
Can anyone help me?
I believe your error is in the web.xml. Try changing your part to this in your web.xml.
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<!-- Register resources and providers under com.vogella.jersey.first package. -->
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.test.ws</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
One way to solve your issue is to create a custom javax.ws.rs.core.Application or org.glassfish.jersey.server.ResourceConfig. It seems that your server does not detect your providers for the serialization. By implementing your own Application, you will be able to specify which provider you want to use. for your example, what you could have done is :
MyApplication.java
package com.test.ws;
public class MyApplication extends ResourceConfig {
public MyApplication() {
//register your resources
packages("com.test.ws");
//if you're using Jackson as your XMLProvider for example
register(JacksonJaxbXMLProvider.class);
}
}
And add the application in your deployment file :
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>com.vogella.jersey.first</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.test.ws.MyApplication</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Employee class should implements Serializable interface
I was able to resolve the issue myself. This was because of having conflicting jars included in build path. Here is the snap for jar files.
I manage a legacy project wich I needed to add a REST web service. This not have Maven.
For jersey 2.25, the last compiled with Java SDK 1.7, I solved adding jar
jersey-media-jaxb-2.25.jar

Restfull webservices + ejb

I'm working on simple web application using both ejb and resteasy following this example. Unfortunately something does not work.
My ear includes one jar with ejb beans and war containing only my web.xml file.
Application deploys with no errors but I cannot access my services.
My beans:
#Local
#Path("/")
public interface IMyBean {
#GET
#Path("date")
#Produces("text/plain")
String getDate();
#GET
#Path("param/{param}")
#Produces("text/plain")
String getParam(#PathParam("param") String param);
}
#Stateless
public class MyBean implements IMyBean {
#Override
public String getDate() {
return new Date();
}
#Override
public String getParam(String param) {
return param;
}
}
And here is my web.xml:
<web-app>
<display-name>Archetyp Created Web Application</display-name>
<context-param>
<param-name>resteasy.jndi.resources</param-name>
<param-value>rest/AuthorizationBean/local</param-value>
</context-param>
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
Modules in my app got names: rest(jar with ejb beans), war (war archive) and ear(ear archive). I'm deploying on Jboss 7.1.1.
Your URL pattern is correct. but path is not mentioned on the getDate() method. try below and use localhost:8080/war/date, localhost:8080/ear/date it will work
#GET
#Path("/date")
#Produces("text/plain")
String getDate();

404 error in JAXRS service using jersey and tomcat

Coding a JAXRS service using jersey and deployed on tomcat. Application subclass
#ApplicationPath("/rest")
public class RestApplication extends Application {
public RestApplication() {
// TODO Auto-generated constructor stub
System.out.println("Inside RestApplication Constructor");
}
#Override
public Set<Class<?>> getClasses() {
// TODO Auto-generated method stub
System.out.println("Get Class");
Set<Class<?>> s=new HashSet<Class<?>>();
s.add(SupportDataService.class);
return s;
}
}
Resource class
#Path("/supportdata")
public class SupportDataService {
public SupportDataService() {
// TODO Auto-generated constructor stub
System.out.println("Inside SupportDataService Constructor");
}
#Path("/support")
#GET
#Produces(MediaType.TEXT_XML)
public String getSupportData(){
String xmlSupport=null;
xmlSupport="<SupportData><Support><key>path1</key><value>value1</value></Support><Support><key>path2</key><value>value2</value></Support></SupportData>";
return xmlSupport;
}
}
Added all jersey jar in WEB-INF/lib except javax.servlet-api-3.0.1.jar and hitting url
http://localhost:8080/RestConfigurator/rest/supportdata/support
but getting 404 error. Not specified any web.xml as subclassed Application.
So with Tomcat 6, which is a Servlet 2.5 implementation, we are required to have a web.xml declaring the ServletContainer. You can see more about it here. Basically, if you want to keep your RestApplication class, the web.xml would look something like
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>MyApplication</servlet-name>
<servlet-class>
org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>thepackge.of.RestApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>MyApplication</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
Given you have added all the jars from Jersey JAX-RS 2.0 RI bundle (besides the servlet-api), this should work. I've tested with Maven on Tomcat 6 and it works fine. Maven just pulls in all most of the jars from that bundle. But the app deployment doesn't differ.

ContainerRequestFilter ContainerResponseFilter doesn't get called

I am trying to learn jersey by creating a small RESTful service. I want to use the Filters for specific reasons(Like I want to use the ContainerResponseFilter for CORS headers to allow cross domain requests). However, I am just not able to get these filters intercept my call. I have seen all the posts for this problem and most of them say to register with annotation provider or in web.xml.
I have tried registering the files in web.xml as well as giving a #Provider annotation for the container
Here is my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html#d4e194 -->
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/spring/config/BeanLocations.xml</param-value>
</context-param>
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.rest.example</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.rest.example.cors</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.rest.example.CORSFilter</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.rest.example.RequestFilter</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webresources/*</url-pattern>
</servlet-mapping>
</web-app>
Here are my Filters:
package com.rest.example.cors;
import javax.ws.rs.ext.Provider;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;
#Provider
public class CORSFilter implements ContainerResponseFilter {
public ContainerResponse filter(ContainerRequest creq,
ContainerResponse cresp) {
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Origin", "*");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Credentials", "true");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS, HEAD");
cresp.getHttpHeaders().putSingle("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With");
return cresp;
}
}
package com.rest.example.cors;
import javax.ws.rs.ext.Provider;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;
#Provider
public class RequestFilter implements ContainerRequestFilter {
public ContainerRequest filter(ContainerRequest request) {
System.out.println("request filter");
return request;
}
}
Link to my github project.
I added a Jersey Application class and registered the filter in the class, which solved my problem. Also upgraded my jersey version to 2.x from 1.x
public class MyApplication extends ResourceConfig {
/**
* Register JAX-RS application components.
*/
public MyApplication () {
register(RequestContextFilter.class);
register(JacksonFeature.class);
register(CustomerResource.class);
register(Initializer.class);
register(JerseyResource.class);
register(SpringSingletonResource.class);
register(SpringRequestResource.class);
register(CustomExceptionMapper.class);
}
}
I solved the problem on Wildfly 10 / rest easy like this (CORSFilter is my ContainerResponseFilter):
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
#ApplicationPath("/rest")
public class JaxRsActivator extends Application {
#Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> resources = new HashSet<Class<?>>();
resources.add(CORSFilter.class);
return resources;
}
}
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>org.anchepedheplatform.infrastructure.core.filters.ResponseCorsFilter</param-value>
</init-param>
First, I wrote a class which implements com.sun.jersey.spi.container.ContainerResponseFilter
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;
/**
* Filter that returns a response with headers that allows for Cross-Origin
* Requests (CORs) to be performed against the platform API.
*/
public class ResponseCorsFilter implements ContainerResponseFilter {
#Override
public ContainerResponse filter(final ContainerRequest request, final ContainerResponse response) {
final ResponseBuilder resp = Response.fromResponse(response.getResponse());
resp.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
final String reqHead = request.getHeaderValue("Access-Control-Request-Headers");
if (null != reqHead && !reqHead.equals(null)) {
resp.header("Access-Control-Allow-Headers", reqHead);}
response.setResponse(resp.build());
return response;
}
and later I had put this reference of this class in intit-param web.xml.
If you are extending the ResourceConfig class the process of registering all the providers can be tedious one and chances are there that one can even miss few providers.
What here can be done with a type of ResourceConfig is you can use packages method in the default constructor to specify the packages("") which will contain your rest resources and the providers. For Instance lets say we have a package com.test.poc.rest which contains all the rest services and another package namely com.test.poc.providers then our resourceConig will look like:
public class CustomResourceConfig extends ResourceConfig{
public CustomResourceConfig(){
super();
packages("com.test.poc.rest;com.test.poc.providers");
//register any custom features
register(JacksonFeature.class); // enabling JSON feature.
}
}
and boom jersey will now scan for your webservices annotated with #Path and for the providers annotated with #Provider.

Guice and GWT problem - can't find GWT.rpc

I build a simple contact manager app with simple service and it did work.
Then I decided I want to use Guice for managing my services and implementations.
I also use mvp4g plugin for MVP design pattern.
I followed the exmaple of Eric Burke on his blog, and my code looks like that:
ContactService.java
#RemoteServiceRelativePath("GWT.rpc")
public interface ContactService extends RemoteService {
public void saveContact(Contact c);
public List<Contact> listContacts();
}
ContactServletModule.java:
#Singleton
public class ContactServletModule extends ServletModule{
private static String SQL_MAP_CONFIG = "org/yuri/SqlMapConfig.xml";
private SqlSessionFactory factory = null;
#Provides
public SqlSessionFactory getSqlSessionFactory(){
if(this.factory == null){
try {
/*
* Create new factory
*/
Reader r = Resources.getResourceAsReader(SQL_MAP_CONFIG);
this.factory = new SqlSessionFactoryBuilder().build(r);
} catch (IOException ex) {
/*
* do nothing, factory is null still
*/
} finally{
return this.factory;
}
}
else{
return this.factory;
}
}
#Override
protected void configureServlets() {
serve("/YuriContactManager/GWT.rpc").with(GuiceRemoteServiceServlet.class);
bind(ContactService.class).to(ContactServiceImpl.class);
}
}
MyGuiceContextListener.java
public class MyGuiceContextListener extends GuiceServletContextListener {
#Override
protected Injector getInjector() {
return Guice.createInjector(new ContactServletModule());
}
}
But when when I start my app and try to list contacts by calling listContacts(), tomcat tells me that GWT RPC can't be found (exactly: The requested resource (/YuriContactManager/org.yuri.ContactManager/GWT.rpc) is not available.) My web.xml looks like that:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.yuri.server.MyGuiceContextListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>welcomeGWT.html</welcome-file>
</welcome-file-list>
</web-app>
Any one had similar problem or has any idea what might be wrong?
found the error :) In ContactServletModule serve path needs to be modified to "/org.yuri.YuriContactManager/GWT.rpc" - I think the reason why is that I'm also using mvp4g framework, but I'm not sure.