Hot questions for Using GlassFish in jersey

Question:

I'm trying to follow the Jersey docs to enable a non-200 response if an error occured (https://jersey.java.net/documentation/latest/representations.html#d0e3586)

My code looks like :

@POST
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public ResponseBuilder getData(@FormParam("one") String one,@FormParam("two") String two,@FormParam("three") String three) {
    if(one.isEmpty() || two.isEmpty() || three.isEmpty()) {
        logger.error("Missing params for getData");
        throw new WebApplicationException(501);
    }
    return Response.ok();
}
}

This unfortunately yields the following error :

[2015-02-01T16:13:02.157+0000] [glassfish 4.1] [SEVERE] [] [org.glassfish.jersey.message.internal.WriterInterceptorExecutor] [tid: _ThreadID=27 _ThreadName=http-listener-1(2)] [timeMillis: 1422807182157] [levelValue: 1000] [[ MessageBodyWriter not found for media type=text/plain, type=class org.glassfish.jersey.message.internal.OutboundJaxrsResponse$Builder, genericType=class javax.ws.rs.core.Response$ResponseBuilder.]]


Answer:

The problem is the return type of your method. It has to be Response instead of ResponseBuilder.

Change your code to the following and it should work:

@POST
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response getData(@FormParam("one") String one,@FormParam("two") String two,@FormParam("three") String three) {
    if(one.isEmpty() || two.isEmpty() || three.isEmpty()) {
        logger.error("Missing params for getData");
        throw new WebApplicationException(501);
    }
    return Response.ok();
}

Question:

I have created a jersey 2 client with the below code,

ClientConfig clientConfig = new ClientConfig();
clientConfig.property(ClientProperties.READ_TIMEOUT, 5000);
clientConfig.property(ClientProperties.CONNECT_TIMEOUT, 10000);
Client client =  ClientBuilder.newClient(clientConfig);       

I can able to make request and every thing works fine. But I want to control the number of client execution thread. In jersey 1, we can have the same implementation like below,

Client client =  Client.create();
client.setConnectTimeout(5000);
client.setReadTimeout(10000);
client.setExecutorService(Executors.newFixedThreadPool(10));

I want to replicate the same thing,

client.setExecutorService(Executors.newFixedThreadPool(10))

with jersey 2 client.

After some search I found this for jersey 2. But it is available in latest version of jersey 2 (2.26). I am using 2.25.1 jersey version. How to achieve the same for 2.25.1 version?


Answer:

I was just digging through the source and found ExecutorServiceProvider and @ClientAsyncExecutor. If you implement the former and annotate it with the latter, your executor should be used as long as the request is asynchronous (I noticed prior to your edit that you were looking for synchronous) and you register the provider with the client.

@ClientAsyncExecutor
static class MyExecutorServiceProvider implements ExecutorServiceProvider {

    @Override
    public ExecutorService getExecutorService() {
        System.out.println("Calling getExecutorService()");
        return Executors.newFixedThreadPool(10);
    }

    @Override
    public void dispose(ExecutorService executorService) {
        executorService.shutdown();
    }
}

Client client = ClientBuilder.newClient()
client.register(new MyExecutorServiceProvider());

Future<Response> res = client.target("test").async().get()

Question:

This is my web.xml

<servlet>
        <servlet-name>Simulator HTTP API</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Simulator HTTP API</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

and this is my simple web service:

@Path("partner")
public class PartnerAPI {

    @Path("/mt")
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String sendMT() {
        return "Sent";
    }

}

when i call it like this:

http://localhost:8080/myprojectname/partner/mt

i get 404 error mot found, what am i doing wrong?

Update

this is my maven

<dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>2.22.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-common</artifactId>
            <version>2.22.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>2.22.1</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>2.22.1</version>
        </dependency>

Answer:

You have different deployment options in Jersey 2:

If you want to do it via web.xml you have to add the an init-param where you specify which packages should be scanned:

<servlet>
        <servlet-name>Simulator HTTP API</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>insert.packagename.where.your.class.is.here</param-value>
        </init-param>
</servlet>

Another option is to create a basic class to configure your REST application.

This would look like this:

import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;

    @ApplicationPath("/test")
    public class YourApplication extends ResourceConfig {
        public YourApplication() {
            this.packages("insert.packagename.where.your.class.is.here");
        }
    }

Make sure to update the string with the package name where your PartnerAPI class is.

Then add the value inside @ApplicationPath to your URL. The link would look like this: http://localhost:8080/myprojectname/test/partner/mt

More information: Jersey docs: Chapter 4. Deploying a RESTful Web Service

Question:

I have a project depending on Netflix Feign and Glassfish Jersey implementation.

Feign uses the 1.1 spec of JAX-RS (JSR 311), and glassfish jersey implementation uses the 2.0 spec. The 2.0 is backward compatible, but the Gradle dependency name is changed.

Thus I have two dependencies in my project:

  • javax.ws.rs:jsr311-api:1.1.1
  • javax.ws.rs:javax-ws-rs-api:2.0.1

Both implements the same classes in the same packages, but one according to 1.x and one according to 2.x

In my Java code, I can only point out the class name and the package.

Can I tell Gradle that this actually is the same package although the name differs and in that way only get one set of the implementing classes in the class path?

Right now it is random what version of the classes that the JVM and Compiler picks. Sometime it does not compile, sometimes it compiles but does not run (MethodNotFoundException).


Answer:

In the end, I added this to my gradle file and it looks alright:

configurations.all {
    resolutionStrategy.dependencySubstitution {
        substitute module('javax.ws.rs:jsr311-api') with module('javax.ws.rs:javax.ws.rs-api:2.0.1')
    }
}

The dependency tree no longer includes the javax.ws.rs:jsr311-api dependency, and no more MethodNotFound-exception for javax.ws.rs.core.Application.getProperties(...) method.

Question:

http://www.mkyong.com/webservices/jax-rs/file-upload-example-in-jersey/ I'm following this guide and run to a problem. I have some questions.

  1. Do all the dependency have to be corresponded? My project has some org.glassfish.jersey dependency and this guide suggest to use org.sun.jersey. Do I have to change it with also the same version like this?

    <dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-multipart</artifactId>
    <version>2.16</version>
    </dependency>
    <dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-server</artifactId>
    <version>2.16</version>
    

  2. I have this error

    org.glassfish.jersey.server.model.ModelValidationException: Validation of the application resource model has failed during application initialization. [[FATAL] No injection source found for a parameter of type public ***.***.****.common.dto.response.AbstractResponse ***.***.****.m2m.instancetypeupload.webservice.InstanceTypeUploadWebService.upload(java.io.InputStream,org.glassfish.jersey.media.multipart.FormDataContentDisposition) at index 0.; source='ResourceMethod{httpMethod=POST, consumedTypes=[multipart/form-data], producedTypes=[application/json], suspended=false, suspendTimeout=0, suspendTimeoutUnit=MILLISECONDS, invocable=Invocable{handler=ClassBasedMethodHandler{handlerClass=class ***.***.****.m2m.instancetypeupload.webservice.InstanceTypeUploadWebService, handlerConstructors=[org.glassfish.jersey.server.model.HandlerConstructor@90516e]}, definitionMethod=public ***.***.***.common.dto.response.AbstractResponse ***.***.*****.m2m.instancetypeupload.webservice.InstanceTypeUploadWebService.upload(java.io.InputStream,org.glassfish.jersey.media.multipart.FormDataContentDisposition), parameters=[Parameter [type=class java.io.InputStream, source=file1, defaultValue=null], Parameter [type=class org.glassfish.jersey.media.multipart.FormDataContentDisposition, source=file1, defaultValue=null]], responseType=class ***.***.***.common.dto.response.AbstractResponse}, nameBindings=[]}']
    

    This is my web service

    @POST
    @Path("/upload")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.APPLICATION_JSON)
    public AbstractResponse upload(@FormDataParam("file1") InputStream file1,
                               @FormDataParam("file1") FormDataContentDisposition filename1
                              ) {
    

    This is my call:

    $.ajax({
          url: 'http://localhost:8080/******/webapi/m2m/upload',
          data: fd,
          processData: false,
          contentType: 'multipart/form-data',
          type: 'POST',
          success: function(data){
            alert(JSON.stringify(data));
            return;
          }
        });
    

The web service is reachable if it only has 1 parameter (FormData InputStream). How to fix it?

  1. I also want to add another String parameter for the web service. What should I do?

Thank you peeskillet for the answers. A bit extra.

SEVERE: The web application [/linterm2m] created a ThreadLocal with key of type [org.jvnet.hk2.internal.PerLocatorUtilities$1] (value [org.jvnet.hk2.internal.PerLocatorUtilities$1@df94b1]) and a value of type [java.util.WeakHashMap] (value [{}]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.

Answer:

If you project is using org.glassfish, you are using Jersey 2. com.sun is Jersey 1, and you should never mix the two. That being said, the error you are facing is most likely due to the fact that you didn't register the MultipartFeature. When the resource model (the resource methods) are being validated for "correctness" at startup, if the feature is not registered, the annotations specific to this feature is unknown, and it's like just having no annotation. And you cant have more than one method param with no annotation.

If you are using a ResourceConfig, you can simply use

public class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        register(MultiPartFeature.class);
    }
}

If you are using web.xml, then can set an <init-param> for the Jersey servlet you registered

<init-param>
    <param-name>jersey.config.server.provider.classnames</param-name>
    <param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>

"I also want to add another String parameter for the web service. What should I do?"

You will need to make that as part of the multipart request and the client needs to make sure to send it as part of the multipart also. On the server side just add another @FormDataParam("anotherString") String anotherString as a method parameter. As for the client, I don't know jQuery that will to help with that. Haven't tested, but you can try this, which shows data being appended to FormParam. Here's something with Angular, where I built the request body myself. Might be a little much, as you may not need to explicitly set the content types.

Question:

I am trying to create a Maven based Jersey quick starter web App. I am selecting the glassfish archetype. But it is giving me the error given below. It is successfully creating com.sun.jersey archetype project. But with glassfish one its having issues. There are no proxy setup in my laptop which could interfere in downloading process. I need to sort this out asap.

Could not resolve archetype org.glassfish.jersey.archetypes:jersey quickstart-webapp:2.19 from any of the configured repositories.
Could not resolve artifact org.glassfish.jersey.archetypes:jersey-quickstart-webapp:jar:2.19
Failure to transfer org.glassfish.jersey.archetypes:jersey-quickstart-webapp:jar:2.19 from https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced. 
Original error: Could not transfer artifact org.glassfish.jersey.archetypes:jersey-quickstart-webapp:jar:2.19 from/to central (https://repo.maven.apache.org/maven2): connect timed out
Failure to transfer org.glassfish.jersey.archetypes:jersey-quickstart-webapp:jar:2.19 from https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced. Original error: Could not transfer artifact org.glassfish.jersey.archetypes:jersey-quickstart-webapp:jar:2.19 from/to central (https://repo.maven.apache.org/maven2): connect timed out

Answer:

It seems there is a typo error in the archetype's artifact: there is a missing hyphen. It's "jersey-quickstart-webapp" and not "jersey quickstart-webapp".

But there is also a timeout from Maven Central, so may be it was only that MC was not available at the time of transfert.

Whatever, before any new trial, delete the folders: - ~/.m2/repository/org/glassfish/jersey/archetypes/jersey quickstart-webapp - ~/.m2/repository/org/glassfish/jersey/archetypes/jersey-quickstart-webapp

Question:

I want to create a Java project with two modules. One is the module for data analysis and another one is the module for creating a restful server so that I can do data analysis remotely. The structure is as follows:

├── MyProject
|   ├── Module 1: classA
|   └── Module 2: 
|            └── HelloWorld (resource class)
|            └── MyApplication (configuration class)

In module 2 I use Jersey.(I am a green hand on it) And I use glassfish and Jersey to build it. (I refer to this link).

I imported the classes in module 1 to the resources class in module two

import module1.classA

public class HelloWorld {

    classA a;

    public HelloWorld(){

        classA a = new classA();

    }

    @GET
    @Consumes({MediaType.TEXT_PLAIN})
    @Produces(MediaType.TEXT_PLAIN)
    public String getClichedMessage(@QueryParam("test") String test){

        return a.data_analysis()

    }
}

However I get a exception as follows:

java.lang.NoClassDefFoundError: module1.classA;
at java.lang.Class.getDeclaredFields0(Native Method)
at java.lang.Class.privateGetDeclaredFields(Class.java:2583)
at java.lang.Class.getDeclaredFields(Class.java:1916)
at org.glassfish.jersey.internal.util.ReflectionHelper$4.run(ReflectionHelper.java:309)
at org.glassfish.jersey.internal.util.ReflectionHelper$4.run(ReflectionHelper.java:306)
at java.security.AccessController.doPrivileged(Native Method)
at org.glassfish.jersey.server.model.IntrospectionModeller.checkResourceClassFields(IntrospectionModeller.java:210)
at org.glassfish.jersey.server.model.IntrospectionModeller.doCreateResourceBuilder(IntrospectionModeller.java:137)
at org.glassfish.jersey.server.model.IntrospectionModeller.access$000(IntrospectionModeller.java:80)
at org.glassfish.jersey.server.model.IntrospectionModeller$1.call(IntrospectionModeller.java:111)
at org.glassfish.jersey.server.model.IntrospectionModeller$1.call(IntrospectionModeller.java:108)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:255)
at org.glassfish.jersey.server.model.IntrospectionModeller.createResourceBuilder(IntrospectionModeller.java:108)
at org.glassfish.jersey.server.model.Resource.from(Resource.java:744)
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:400)
at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:163)
at org.glassfish.jersey.server.ApplicationHandler$3.run(ApplicationHandler.java:323)
at org.glassfish.jersey.internal.Errors$2.call(Errors.java:289)
at org.glassfish.jersey.internal.Errors$2.call(Errors.java:286)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:286)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:320)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:285)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:310)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:170)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:358)
at javax.servlet.GenericServlet.init(GenericServlet.java:244)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1583)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1382)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5704)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5946)
at com.sun.enterprise.web.WebModule.start(WebModule.java:691)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1041)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:1024)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:747)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2286)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1932)
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:139)
at org.glassfish.internal.data.EngineRef.start(EngineRef.java:122)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:255)
at org.glassfish.jersey.server.model.IntrospectionModeller.createResourceBuilder(IntrospectionModeller.java:108)
at org.glassfish.jersey.server.model.Resource.from(Resource.java:744)
at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:400)
at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:163)
at org.glassfish.jersey.server.ApplicationHandler$3.run(ApplicationHandler.java:323)
at org.glassfish.jersey.internal.Errors$2.call(Errors.java:289)
at org.glassfish.jersey.internal.Errors$2.call(Errors.java:286)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:286)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:320)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:285)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:310)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:170)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:358)
at javax.servlet.GenericServlet.init(GenericServlet.java:244)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1583)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1382)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5704)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:5946)
at com.sun.enterprise.web.WebModule.start(WebModule.java:691)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1041)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:1024)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:747)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:2286)
at com.sun.enterprise.web.WebContainer.loadWebModule(WebContainer.java:1932)
at com.sun.enterprise.web.WebApplication.start(WebApplication.java:139)
at org.glassfish.internal.data.EngineRef.start(EngineRef.java:122)
Startup of context /test_gf_war_exploded failed due to previous errors]]

Which shows that the class in module1 is not found.

I am wondering how to deal with it. And if my framework for realizing it is wrong, what is the right method to import others modules to Jersey?


Answer:

In order to access Module 1 resources in Module 2 you need to add Module 1 to the Module Dependencies of Module 2. Select Open Module Settings in the context menu and add the module in the Dependencies tab.

Question:

I'm with this test project named CLAWS-Dicionario, and I'm trying to run it on Glassfish server (which is working flawlessly). All I have is that class:

package com.k19.restful.resources;

import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces;

@Path("/helloworld")
public class HelloWorldResource {

    @GET 
    @Produces("text/plain") 
    public String showHelloWorld() { 
        return "Olá mundo!"; 
    }
}

And this add at web.xml in order to incorporate Jersey to it

<servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <param-value>com.k19.restful.resources</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

I've also added the following jersey libraries to my build-path:

asm-debug-all-5.0.3.jar
javax.ws.rs-api-2.0.1.jar
jersey-server.jar
org.osgi.core-4.2.0

So I run the project, and everything feels fine. But when I try to access this URL:

http://localhost:8080/CLAWS-Dicionario/helloworld

It returns a 404 error. I'm sure the host is congured at 8080 port (the URL localhost:8080 works just fine). So what is the problem?

EDIT: The server began to present another problems, which took me to that line of the domain.xml file:

 <application context-root="/CLAWS_-_Dicionário" object-type="user" name="CLAWS-Dicionario" directory-deployed="true" location="${com.sun.aas.instanceRootURI}/eclipseApps/CLAWS-Dicionario/">

Repare the CLAWS_-_Dicionário part. Would this be the real name of my project? I had to remove the accent in order the server to work, and I'm finding no more console response when running the project...and even if I try the URL http://localhost:8080/CLAWS_-_Dicionario/helloworld, the error is still there,so...just found it something important to point.


Answer:

Depending on which Servlet version you use, you need:

For Servlet 2.x implementation:

  • jersey-container-servlet-core.jar

For Servlet 3.x implementation:

  • jersey-container-servlet.jar

org.glassfish.jersey.servlet.ServletContainer is not packaged in jersey-server.jar

According to the api doc for Class ServletContainer

If the initialization parameter is not present and a initialization parameter "jersey.config.server.provider.packages" is present (see ServerProperties.PROVIDER_PACKAGES) a new instance of ResourceConfig with this configuration is created. The initialization parameter "jersey.config.server.provider.packages" MUST be set to provide one or more package names. Each package name MUST be separated by ';'.

The parameter com.sun.jersey.config.property.packages have been replaced by jersey.config.server.provider.packages in version 2.x.

<init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>com.k19.restful.resources</param-value>
</init-param>

In domain.xml, you should have the context-root representing the url path from where the application is accessible:

<application context-root="/CLAWS-Dicionario" object-type="user" name="CLAWS-Dicionario" directory-deployed="true" location="${com.sun.aas.instanceRootURI}/eclipseApps/CLAWS-Dicionario/">

letting you access your application from:

 http://localhost:8080/CLAWS-Dicionario/helloworld

Question:

package model;

import java.net.URI;
import java.util.Collection;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

@Path("/item")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Stateless
public class InfoRestService {
    // the PersistenceContext annotation is a shortcut that hides the fact
    // that, an entity manager is always obtained from an EntityManagerFactory.
    // The peristitence.xml file defines persistence units which is supplied by
    // name
    // to the EntityManagerFactory, thus dictating settings and classes used by
    // the
    // entity manager
    @PersistenceContext(unitName = "Task")
    private EntityManager em;

    // Inject UriInfo to build the uri used in the POST response
    @Context
    private UriInfo uriInfo;

    @POST
    public Response createItem(PersonInfo item) {
        if (item == null) {
            throw new BadRequestException();
        }
        em.persist(item);

        // Build a uri with the Item id appended to the absolute path
        // This is so the client gets the Item id and also has the path to the
        // resource created
        URI itemUri = uriInfo.getAbsolutePathBuilder().path(item.getId()).build();

        // The created response will not have a body. The itemUri will be in the
        // Header
        return Response.created(itemUri).build();
    }

    @GET
    @Path("{id}")
    public Response getItem(@PathParam("id") String id) {
        PersonInfo item = em.find(PersonInfo.class, id);

        if (item == null) {
            throw new NotFoundException();
        }

        return Response.ok(item).build();
    }

    // Response.ok() does not accept collections
    // But we return a collection and JAX-RS will generate header 200 OK and
    // will handle converting the collection to xml or json as the body
    @GET
    public Collection<PersonInfo> getItems() {
        TypedQuery<PersonInfo> query = em.createNamedQuery("PersonInfo.findAll",
                PersonInfo.class);
        return query.getResultList();
    }

    @PUT
    @Path("{id}")
    public Response updateItem(PersonInfo item, @PathParam("id") String id) {
        if (id == null) {
            throw new BadRequestException();
        }

        // Ideally we should check the id is a valid UUID. Not implementing for
        // now
        item.setId(id);
        em.merge(item);

        return Response.ok().build();
    }

    @DELETE
    @Path("{id}")
    public Response deleteItem(@PathParam("id") String id) {
        PersonInfo item = em.find(PersonInfo.class, id);
        if (item == null) {
            throw new NotFoundException();
        }
        em.remove(item);
        return Response.noContent().build();
    }

}


package model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;


/**
 * The persistent class for the person_info database table.
 * 
 */
@Entity
@XmlRootElement
@Table(name="person_info")
@NamedQuery(name="PersonInfo.findAll", query="SELECT p FROM PersonInfo p")
public class PersonInfo implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    private String id;

    private String email;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;

    public PersonInfo() {
    }

    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getEmail() {
        return this.email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

}

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="Task">
        <jta-data-source>jdbc/DBtest</jta-data-source>
        <class>model.PersonInfo</class>
    </persistence-unit>
</persistence>

and the other class is Application package model;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("rest")
public class ApplicationConfig extends Application{

}

I really have no idea, the connections are made ok .. I'm using Glassfish 4 server and MySQL database... code is deploying but when I want to access the localhost:8080/Task/.. (my app) the only thing it says is this:

"HTTP Status 404 - Not Found / Type Status report

messageNot Found descriptionThe requested resource is not available."


Answer:

The code you supplied is working (when commenting out the persistence related stuff), I guess you are just confusing something.

The @ApplicationPath annotation sets the root context which comes after your project name.

If you project name really is Task you have to use this URL: http://localhost:8080/Task/rest/item

Otherwise: http://localhost:8080/YOUR_PROJECT_NAME/rest/item

See also:

  • How to set up JAX-RS Application using annotations only (no web.xml)?

Question:

I am trying to download a file from my server. My problem is that if I use chunkedStreamingMode the server is return me a 405 - Method not Allowed Error. If I don't set the chunkedStreamingMode the download works perfectly.

I don't understand why the file download with chunkedStreamingMode enabled gets rejected by my server. Is there anything I am doing wrong here? Or do I need to set something on the server to get chunkedStreamingMode working ?

On my server I have:

@GET
@Path("/{fileId}")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response downloadFile(@PathParam("fileId") long fileId, @Context HttpServletRequest req,
                @Context HttpServletResponse response) throws IOException {
..
}

On the client I use:

WebTarget target = rootTarget.path(uri);                            
Invocation.Builder builder = target.request(MediaType.APPLICATION_OCTET_STREAM_TYPE);
response = builder.get();

I use the following HttpUrlConnectorProvider on my client:

private static HttpUrlConnectorProvider buildHttpUrlConnectorProvider(){
     HttpUrlConnectorProvider.ConnectionFactory factory = new HttpUrlConnectorProvider.ConnectionFactory() {
            @Override
            public HttpURLConnection getConnection(URL url) throws IOException {                      
                HttpURLConnection result = (HttpURLConnection) url.openConnection();
                result.setChunkedStreamingMode(4096);                          
                result.setDoOutput(true);  
                return result;
            }
        };
     return new HttpUrlConnectorProvider().connectionFactory(factory);
}

Answer:

I finally solved this by setting the following property for the client config insted of setChunkedStreamingMode(4096); in the HTTPUrlConnection:

.property(ClientProperties.REQUEST_ENTITY_PROCESSING, "CHUNKED");

Question:

I have a maven web application with the following project facets enabled.

  • Dynamic Web Project 3.0
  • JAX-RS REst Web Services 2.0
  • Java 1.7

What I am basically trying to do is expose one of our functionalities as a RESTful web service, for which, I am using Jersey packages.

When I hit the rest URL, I am getting the following exception.

    SEVERE: Servlet.service() for servlet [com.bnym.dwf.BulkRemoveCSVEntitlements] in context with path [/bnym-dwf-rest-app] threw exception [Servlet execution threw an exception] with root cause
    java.lang.NoSuchMethodError: org.glassfish.jersey.client.ClientProperties.getValue(Ljava/util/Map;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
    at org.glassfish.jersey.client.authentication.HttpAuthenticationFilter.getMaximumCacheLimit(HttpAuthenticationFilter.java:166)
    at org.glassfish.jersey.client.authentication.HttpAuthenticationFilter.<init>(HttpAuthenticationFilter.java:130)
    at org.glassfish.jersey.client.authentication.HttpAuthenticationFeature.configure(HttpAuthenticationFeature.java:602)
    at org.glassfish.jersey.model.internal.CommonConfig.configureFeatures(CommonConfig.java:609)
    at org.glassfish.jersey.model.internal.CommonConfig.configureMetaProviders(CommonConfig.java:550)
    at org.glassfish.jersey.client.ClientConfig$State.initRuntime(ClientConfig.java:361)
    at org.glassfish.jersey.client.ClientConfig$State.access$000(ClientConfig.java:84)
    at org.glassfish.jersey.client.ClientConfig$State$3.get(ClientConfig.java:116)
    at org.glassfish.jersey.client.ClientConfig$State$3.get(ClientConfig.java:113)
    at org.glassfish.jersey.internal.util.collection.Values$LazyValue.get(Values.java:275)
    at org.glassfish.jersey.client.ClientConfig.getRuntime(ClientConfig.java:667)
    at org.glassfish.jersey.client.ClientRequest.getClientRuntime(ClientRequest.java:162)
    at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:644)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:375)
    at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:275)
    at com.activiti.extension.bean.ActivitiEntitlementsMain.getUsers(ActivitiEntitlementsMain.java:114)
    at com.activiti.extension.bean.RemoveCEEPEntitlements.bulkRemoval(RemoveCEEPEntitlements.java:47)
    at com.activiti.extension.bean.DWFCommon.bulkRemoveUsingCSV(DWFCommon.java:640)
    at com.bnym.dwf.BulkRemoveCSVEntitlements.service(BulkRemoveCSVEntitlements.java:54)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

I guess this is an issue with the version of Jersey that I am using. The list of dependencies snippet from my pom.xml is as follows.

<dependencies>
    <dependency>
        <groupId>javax.ws.rs</groupId>
        <artifactId>javax.ws.rs-api</artifactId>
        <version>2.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.hk2.external</groupId>
        <artifactId>aopalliance-repackaged</artifactId>
        <version>2.4.0-b31</version>
    </dependency>

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2.2</version>
    </dependency>

    <dependency>
        <groupId>asm</groupId>
        <artifactId>asm-util</artifactId>
        <version>3.3.1</version>
    </dependency>

    <dependency>
        <groupId>org.apache.ws.commons.axiom</groupId>
        <artifactId>axiom-api</artifactId>
        <version>1.2.13</version>
    </dependency>
    <dependency>
        <groupId>org.apache.ws.commons.axiom</groupId>
        <artifactId>axiom-impl</artifactId>
        <version>1.2.13</version>
    </dependency>
    <dependency>
        <groupId>org.apache.axis</groupId>
        <artifactId>axis</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>org.apache.axis2</groupId>
        <artifactId>axis2-adb</artifactId>
        <version>1.6.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.axis2</groupId>
        <artifactId>axis2-kernel</artifactId>
        <version>1.6.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.axis2</groupId>
        <artifactId>axis2-transport-http</artifactId>
        <version>1.6.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.axis2</groupId>
        <artifactId>axis2-transport-local</artifactId>
        <version>1.6.2</version>
    </dependency>
    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.3</version>
    </dependency>
    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.9</version>
    </dependency>
    <dependency>
        <groupId>commons-discovery</groupId>
        <artifactId>commons-discovery</artifactId>
        <version>0.2</version>
    </dependency>
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>commons-httpclient</groupId>
        <artifactId>commons-httpclient</artifactId>
        <version>3.1</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1.1</version>
    </dependency>
    <dependency>
        <groupId>ewh.E3</groupId>
        <artifactId>E3Client</artifactId>
        <version>0.0.1.2-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>com.owlike</groupId>
        <artifactId>genson</artifactId>
        <version>1.3</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.hk2</groupId>
        <artifactId>hk2-api</artifactId>
        <version>2.4.0-b25</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.hk2</groupId>
        <artifactId>hk2-locator</artifactId>
        <version>2.4.0-b25</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.hk2</groupId>
        <artifactId>hk2-utils</artifactId>
        <version>2.4.0-b25</version>
    </dependency>
    <dependency>
        <groupId>httpcomponents-httpcore</groupId>
        <artifactId>httpcore</artifactId>
        <version>4.0-alpha6</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.2.3</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.2.3</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.2.3</version>
    </dependency>
    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.18.1-GA</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.hk2.external</groupId>
        <artifactId>javax.inject</artifactId>
        <version>2.4.0-b25</version>
    </dependency>
    <dependency>
        <groupId>javax.xml.bind</groupId>
        <artifactId>jaxb-api</artifactId>
        <version>2.2.7</version>
    </dependency>
    <dependency>
        <groupId>com.sun.xml.bind</groupId>
        <artifactId>jaxb-impl</artifactId>
        <version>2.2.6</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-client</artifactId>
        <version>2.13</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-common</artifactId>
        <version>2.13</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet-core</artifactId>
        <version>2.13</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.13</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.bundles.repackaged</groupId>
        <artifactId>jersey-guava</artifactId>
        <version>2.13</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-jaxb</artifactId>
        <version>2.19</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson1</artifactId>
        <version>2.13</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-server</artifactId>
        <version>2.13</version>
    </dependency>
    <dependency>
        <groupId>com.googlecode.json-simple</groupId>
        <artifactId>json-simple</artifactId>
        <version>1.1.1</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
    </dependency>
    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>org.apache.neethi</groupId>
        <artifactId>neethi</artifactId>
        <version>3.0.2</version>
    </dependency>
    <dependency>
        <groupId>com.opencsv</groupId>
        <artifactId>opencsv</artifactId>
        <version>3.3</version>
    </dependency>
    <dependency>
        <groupId>org.osgi</groupId>
        <artifactId>org.osgi.core</artifactId>
        <version>4.2.0</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.hk2</groupId>
        <artifactId>osgi-resource-locator</artifactId>
        <version>1.0.1</version>
    </dependency>
    <dependency>
        <groupId>javax.persistence</groupId>
        <artifactId>persistence-api</artifactId>
        <version>1.0</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.7</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.2.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.1.0.Final</version>
    </dependency>
    <dependency>
        <groupId>wsdl4j</groupId>
        <artifactId>wsdl4j</artifactId>
        <version>1.6.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.ws.commons.schema</groupId>
        <artifactId>XmlSchema</artifactId>
        <version>1.4.7</version>
    </dependency>
    <dependency>
        <groupId>org.json</groupId>
        <artifactId>json</artifactId>
        <version>20090211</version>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
    </dependency>
</dependencies>

I was using Jersey 2.19 packages earlier but then changed to 2.13. I have tried doing maven clean and maven build as well as Eclipse IDE's clean and build project multiple times.

In jersey-client 2.13 documentation, I find the getValue method available under ClientProperties class. Can someone help me identify why the issue still occurs?


Answer:

To resolve these kind of errors, I usually, always update the sources of all the dependencies available in the POM.

Use the below command to fetch all sources of the jar files:

mvn dependency:sources

Now go back to eclipse, use the Ctrl + Shift + T, to find the 'org.glassfish.jersey.client.ClientProperties' file, and verify the getValue() method(s).

If you find the right method (with correct order of parameters), then it is a run time issue. Check your server lib to find any older(new) versions of that jar.

Question:

I have a class like this:

class Customer {
    private int id;
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

and I have a glass fish web service:

i want to know it is possible to send a customer object using get

(i know i can do this in post, but in get ... i don't know)

this is what i tried:

@GET
    @Path("/test")
    @Produces(MediaType.TEXT_PLAIN)
    @Consumes(MediaType.APPLICATION_OCTET_STREAM)
    public String test(@QueryParam("customer") Customer customer) {
        return "Done " + customer.getId();
    }

then i call it like this:

..../test?id=4&name=william

I know that is wrong, but i don't know the correct way, and i don't know if that is even possible using get


Answer:

@QueryParam should be used for each individual parameter. For instance

/cusomters?name=hello&id=1

@GET
@Produces(...)
public Response get(@QueryParam("name") String name,
                    @QueryParam("id") int id)

If you want put it into a bean, you can use @BeanParam, which allows you to put arbitrary @XxxParams into a bean. For example

class Customer {
    @QueryParam("name")
    private String name;
    @QueryParam("id")
    private int id;
    // getters/setters
}

@GET
public Response get(@BeanParam Customer customer)

But do keep in mind REST principles. To create a customer resource, it should be done with POST. Also be considerate of security concerns. You do not want private user information in URLs.