[JERSEY-307] Support HttpURLConnection proxy configuration Created: 11/Jun/09  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Critical
Reporter: gz4p9c Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: Windows XP
Platform: PC


Issuezilla Id: 307

 Description   

I have developed a swing application under NB (matisse) that uses the Jersey
client API to populate a JTable. All of my development was using the URL -
http://localhost/testdata/rest and the recipient server was running on the same
system as the client. All was fine until I tried to deploy the server code on
another host in the network. When using any URL that points to a real host
(anything other than localhost), I get the included exception. It appears that
something is routing all non "localhost" requests (even if I use the hostname
of the local system) to a proxy?

com.sun.jersey.api.client.UniformInterfaceException: GET
http://w2gz4p9c04.amer.corp.eds.com:8080/rest/elitfiles?
batchsize=25&startpage=0&tonode&qname=D&fromnode&applid returned a response
status of 407
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:572)
at com.sun.jersey.api.client.WebResource.access$400(WebResource.java:68)
at com.sun.jersey.api.client.WebResource$Builder.get
(WebResource.java:454)
at connectconsole.ConnectConsoleView.populateBPTable
(ConnectConsoleView.java:624)
at connectconsole.ConnectConsoleView.getDoneQueue
(ConnectConsoleView.java:572)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke
(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke
(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jdesktop.application.ApplicationAction.noProxyActionPerformed
(ApplicationAction.java:662)
at org.jdesktop.application.ApplicationAction.actionPerformed
(ApplicationAction.java:698)
at javax.swing.AbstractButton.fireActionPerformed
(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed
(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed
(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed
(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased
(BasicButtonListener.java:236)
at java.awt.AWTEventMulticaster.mouseReleased
(AWTEventMulticaster.java:272)
at java.awt.Component.processMouseEvent(Component.java:6038)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3260)
at java.awt.Component.processEvent(Component.java:5803)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4410)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.LightweightDispatcher.retargetMouseEvent
(Container.java:4322)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
at java.awt.Container.dispatchEventImpl(Container.java:2102)
at java.awt.Window.dispatchEventImpl(Window.java:2429)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters
(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter
(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy
(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)



 Comments   
Comment by sandoz [ 11/Jun/09 ]

I replied to your email, and moved it over to the Jersey users list:

http://markmail.org/search/?q=list%3Anet.java.dev.jersey.users#query:list%3Anet.java.dev.jersey.users+page:2+mid:ryk4gsdbsds2oefp+state:results

Can you try accessing the same URL using command line utility curl and also
accessing using your browser.

Comment by gz4p9c [ 11/Jun/09 ]

Both curl and my browser connect and return results correctly (neither request
any proxy credentials).

Comment by sandoz [ 11/Jun/09 ]

SO it has to be something with the configuration of HttpURLConnection.

Do you have any system properties set up in your application:

http://java.sun.com/j2se/1.5.0/docs/guide/net/properties.html

?

Note that there is nothing in the Jersey Client implementation to support proxies.

If you write a simple test using HttpURLConnection in the sample application
does it work? for example

URL u = ...
HttpURLConnection c = (HttpURLConnection)u.openConnection();
InputStream in = c.getInputStream();

Comment by gz4p9c [ 11/Jun/09 ]

It appears to be some type of issue with NB, Matisse, or the Swing environment
itself. The HttpURLConnection c = (HttpURLConnection)u.openConnection(); fails
the same way. I did try all of the included properties and they do not resolve
the issue. I am assuming the Jersey client API uses the HttpURLConnection, so
is this something you can help with?

properties:

/*
Properties systemSettings = System.getProperties();
systemSettings.put("proxySet", "false");
systemSettings.remove("http.proxyHost");
systemSettings.remove("http.proxyPort");
Authenticator.setDefault(null);
*/

System.clearProperty("http.proxyHost");
System.clearProperty("http.proxyPort");
System.setProperty("proxySet", "false");
System.setProperty("http.nonProxyHosts", "*.eds.com");

Comment by sandoz [ 11/Jun/09 ]

Yes, the Jersey client API uses HttpURLConnection by default. I cannot help you
w.r.t. that issue unfortunately, but there may be a workaround, and instead use
the Apache HTTP client support.

See the dependencies document and the API here:

https://jersey.dev.java.net/source/browse/*checkout*/jersey/tags/jersey-1.1.0-ea/jersey/dependencies.html
https://jersey.dev.java.net/nonav/apidocs/1.1.0-ea/contribs/jersey-apache-client/index.html

Comment by gz4p9c [ 12/Jun/09 ]

I have solved this issue, but would like to pass on some info and a small
suggestion. It appears the default proxy selection process is different when
the app is built as a "java desktop application" in NB (swing). I was able to
successfully use "HttpURLConnection c = (HttpURLConnection)u.openConnection
(Proxy.NO_PROXY);" after adding the Proxy.NO_PROXY option. My suggestion is to
add the "Proxy" option to the Client.resource(...), so it can be passed on to
the lower level method(s). As a work around, I added a custom ProxySelector
class that just forces Proxy.NO_PROXY on all http/https connections. This
allowed me to use the current Jersey client with my swing app.

Comment by sandoz [ 16/Jun/09 ]

Glad you managed to work around it. I have changed the title of the issue.

Comment by sandoz [ 16/Jun/09 ]

Changing to enhancement.

Comment by Krystian Nowak [ 27/Nov/12 ]

Since Jersey's contrib Apache HTTP Client 4 currently does not support yet http.proxyHost and http.proxyPort settings as in standard http://docs.oracle.com/javase/6/docs/technotes/guides/net/proxies.html, so non-standard YrnoClientHttpClient4.HTTP_PROXY_SYSTEM_PROP has to be used.
But this is due to the fact of using Apache HTTP Client pre-4.2 version, which does not yet implement SystemDefaultHttpClient added by https://issues.apache.org/jira/browse/HTTPCLIENT-1128 in version 4.2 - see:
http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/client/SystemDefaultHttpClient.html

For now one would expect to be able to create not only ApacheHttpClient4 but also (following Apache HTTP convention) - SystemDefaultApacheHttpClient4





[JERSEY-1994] Content-Type is evaluated for 204 No Content Created: 01/Aug/13  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.0, 2.1
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: fdanek Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

JDK 1.6
Jersey 2.0 bundle and Jersey 2.1 bundle


Sprint: Triaged

 Description   

We consume a REST service using the Jersey client API.
The code we use to execute the GET request is:

MyEntity myEntity = webTarget.request(MediaType.APPLICATION_JSON_TYPE).get(MyEntity.class);

This works well if the response contains an entity (so the return value is not null).
For empty responses we get the following exception:

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=text/plain; charset=UTF-8, type=class com.mypkg.MyEntity, genericType=class com.mypkg.MyEntity.

Request/response for the null case are:

1 * Request received on thread main
1 > GET https://rest.test.com/myservice/rest/myentity/unknown
1 > Accept: application/json

2 * Response received on thread main
2 < 204
2 < Date: Thu, 01 Aug 2013 12:05:50 GMT
2 < Content-Length: 0
2 < Keep-Alive: timeout=15, max=100
2 < Connection: Keep-Alive
2 < Content-Type: text/plain; charset=UTF-8
2 < Server: Apache
2 < Cache-Control: max-age=0

As you can see the HTTP status code is 204.
I do not know why, but the Content-Type 'text/plain' is returned.
This seems to be the cause of the exception above.

The behavior I would expect is that the client first evaluates the HTTP status code and only if applicable evaluates the content related stuff.
So as for status 204 the HTTP spec clearly states that there must be no content in the body, the client should ignore all that content stuff (content-type, content-length, etc.).

Right now our work-around is to get the Response object, check the status code ourself and only if not 204 read the entity. It works but is not the way I expected the client API to work.



 Comments   
Comment by Miroslav Fuksa [ 22/Oct/13 ]

Which server deployment do you use? I have tried that with Grizzly where response headers are handled correctly. With simple-http container I am able to respond 204 with Content-Type defined.

If the client gets

  • status: 204
  • Content-Type defined (for example text/plain)
  • no entity

and there is no MessageBodyReader the exception is thrown.

This bug consists of two parts: fix the server (to not send the Content-Type when 204 is returned) and fix the client (no to throw the exception when 204 is returned with Content-Type defined but MBR cannot be found). Client cannot be probably done in ReaderInterceptorExecutor as we don't have information about response status.

MBR defines that input stream can be empty and in that case MBR could return an entity which represents an empty entity. So, I would try to execute MBR even the response status is 204. This is not in contradictory to the fact that HTTP spec says that the entity should not be present for 204. But I would not throw an exception because of the missing reader and return null. In my opinion, this should be the solution.

Comment by Miroslav Fuksa [ 22/Oct/13 ]

I have added an ignored test to org.glassfish.jersey.tests.e2e.common.NoEntityTest. Please see it when fixing.

Comment by Miroslav Fuksa [ 29/Oct/13 ]

I am moving this issue to the backlog. The fix consists of two parts (client and server) described above.





[JERSEY-2161] Add exceptions to the tracing Created: 22/Oct/13  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Critical
Reporter: Miroslav Fuksa Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: jersey-airport

 Description   

Tracing currently does not include information about exceptions. When exception in MBW is thrown the tracing with VERBOSE level looks like the following:

X-Jersey-Tracing-020=[MBW         [ ---- / 226.06 ms |  ---- %] [org.glassfish.jersey.message.internal.XmlCollectionJaxbProvider$General @1f00aff5] is skipped]
X-Jersey-Tracing-023=[WI          [ 0.00 / 355.42 ms |  0.00 %] [org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor @5a2d13c1 #3000] AFTER context.proceed()]
X-Jersey-Tracing-024=[WI          [ 0.00 / 355.46 ms |  0.00 %] [org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor @10bcc8f4 #10] AFTER context.proceed()]
X-Jersey-Tracing-021=[MBW         [ ---- / 226.09 ms |  ---- %] [org.glassfish.jersey.message.internal.XmlRootElementJaxbProvider$General @693e4a5a] is skipped]
Content-Length=[0]
X-Jersey-Tracing-022=[MBW         [129.20 / 355.34 ms | 34.19 %] WriteTo by [org.glassfish.jersey.moxy.json.internal.ConfigurableMoxyJsonProvider @2c8c7d6]]
X-Jersey-Tracing-002=[PRE-MATCH   [ 0.02 / 13.70 ms |  0.00 %] PreMatchRequest summary: 0 filters]
X-Jersey-Tracing-001=[START       [ ---- /  0.65 ms |  ---- %] Other request headers: user-agent=[Jersey/2.4-SNAPSHOT (HttpUrlConnection 1.6.0_65)] host=[localhost:9998] connection=[keep-alive]]
X-Jersey-Tracing-000=[START       [ ---- /  ---- ms |  ---- %] baseUri=[http://localhost:9998/] requestUri=[http://localhost:9998/resource] method=[GET] authScheme=[n/a] accept=[text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2] accept-encoding=n/a accept-charset=n/a accept-language=n/a content-type=n/a content-length=n/a]
Connection=[close]
Date=[Tue, 22 Oct 2013 14:56:35 GMT]
X-Jersey-Tracing-017=[MBW         [ ---- / 222.87 ms |  ---- %] Find MBW for type=[org.glassfish.jersey.tests.e2e.json.XmlTypeTest$Bean1] genericType=[org.glassfish.jersey.tests.e2e.json.XmlTypeTest$Bean1] mediaType=[[javax.ws.rs.core.MediaType @456c1227]] annotations=[@javax.ws.rs.GET(), @javax.ws.rs.Produces(value=[application/json])]]
X-Jersey-Tracing-016=[WI          [ 0.03 / 222.78 ms |  0.01 %] [org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor @5a2d13c1 #3000] BEFORE context.proceed()]
X-Jersey-Tracing-015=[WI          [ 0.02 / 222.71 ms |  0.00 %] [org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor @10bcc8f4 #10] BEFORE context.proceed()]
X-Jersey-Tracing-014=[RESP-FILTER [ 0.02 / 220.20 ms |  0.00 %] Response summary: 0 filters]
X-Jersey-Tracing-019=[MBW         [ ---- / 226.02 ms |  ---- %] [org.glassfish.jersey.server.validation.internal.ValidationErrorMessageBodyWriter @25e3bbd7] is skipped]
X-Jersey-Tracing-018=[MBW         [ ---- / 225.98 ms |  ---- %] [org.glassfish.jersey.moxy.json.internal.ConfigurableMoxyJsonProvider @2c8c7d6] IS writeable]
X-Jersey-Tracing-011=[REQ-FILTER  [ 0.01 / 20.35 ms |  0.00 %] Request summary: 0 filters]
X-Jersey-Tracing-010=[MATCH       [ 6.09 / 20.26 ms |  1.61 %] RequestMatching summary]
X-Jersey-Tracing-013=[INVOKE      [ ---- / 219.24 ms |  ---- %] Response: [org.glassfish.jersey.message.internal.OutboundJaxrsResponse @35a271f5 <200/SUCCESSFUL|OK|org.glassfish.jersey.tests.e2e.json.XmlTypeTest$Bean1 @3be7a755>]]
X-Jersey-Tracing-012=[INVOKE      [ 0.07 / 217.96 ms |  0.02 %] Resource [org.glassfish.jersey.tests.e2e.json.XmlTypeTest$Bean1Resource @2dabcea] method=[public org.glassfish.jersey.tests.e2e.json.XmlTypeTest$Bean1 org.glassfish.jersey.tests.e2e.json.XmlTypeTest$Bean1Resource.getBean1()]]
X-Jersey-Tracing-007=[MATCH       [ ---- / 16.24 ms |  ---- %] Matched resource: template=[resource] regexp=[/resource(/.*)?] matches=[/resource] from=[/resource]]
X-Jersey-Tracing-008=[MATCH       [ ---- / 19.13 ms |  ---- %] Matched method  : public org.glassfish.jersey.tests.e2e.json.XmlTypeTest$Bean1 org.glassfish.jersey.tests.e2e.json.XmlTypeTest$Bean1Resource.getBean1()]
X-Jersey-Tracing-009=[MATCH       [ ---- / 20.13 ms |  ---- %] Resource instance: [org.glassfish.jersey.tests.e2e.json.XmlTypeTest$Bean1Resource @2dabcea]]
X-Jersey-Tracing-003=[MATCH       [ ---- / 14.81 ms |  ---- %] Matching path [/resource]]
X-Jersey-Tracing-004=[MATCH       [ ---- / 14.88 ms |  ---- %] Pattern [/application\.wadl(/)?] is NOT matched]
X-Jersey-Tracing-005=[MATCH       [ ---- / 14.92 ms |  ---- %] Pattern [/application\.wadl(/.*)?] is NOT matched]
X-Jersey-Tracing-006=[MATCH       [ ---- / 15.01 ms |  ---- %] Pattern [/resource(/)?] IS selected]
X-Jersey-Tracing-026=[FINISHED    [ ---- / 355.55 ms |  ---- %] Response status: 200/SUCCESSFUL|OK]
X-Jersey-Tracing-025=[WI          [133.10 / 355.51 ms | 35.22 %] WriteTo summary: 2 interceptors]
X-Jersey-Tracing-028=[FINISHED    [ ---- / 377.89 ms |  ---- %] Response status: 500/SERVER_ERROR|Internal Server Error]
X-Jersey-Tracing-027=[RESP-FILTER [ 0.01 / 377.81 ms |  0.00 %] Response summary: 0 filters]

I miss there information that the exception was thrown. I would at least add this info. Additionally, it would be good to have exception stack trace (at least for the VERBOSE level).

Details:
If there would be any exception mapper, this will be probably listed in the tracing info. The problem is that there is no exception mapper and response 500 is processed. Therefore log info contains firstly 200 response status and then 500 response status.

The exception thrown is (not important for this task, but to list all needed information):

[Exception [EclipseLink-50013] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.JAXBException
Exception Description: The property or field itemCount on the class org.glassfish.jersey.tests.e2e.json.XmlTypeTest$Bean1 is required to be included in the propOrder element of the XmlType annotation.]
	at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:1021)
	at org.eclipse.persistence.jaxb.JAXBContext.<init>(JAXBContext.java:174)
	at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:165)
	at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:152)
	at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:112)
	at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:102)
	at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.getJAXBContext(MOXyJsonProvider.java:302)
	at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:787)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:243)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:230)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:149)
	at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:103)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:149)
	at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:88)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:149)
	at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1139)
	at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:557)
	at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:381)
	at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:371)
	at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:262)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
	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.process(Errors.java:267)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:318)
	at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:236)
	at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:983)
	at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:334)
	at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:209)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
	at java.lang.Thread.run(Thread.java:695)
Caused by: Exception [EclipseLink-50013] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.JAXBException
Exception Description: The property or field itemCount on the class org.glassfish.jersey.tests.e2e.json.XmlTypeTest$Bean1 is required to be included in the propOrder element of the XmlType annotation.
	at org.eclipse.persistence.exceptions.JAXBException.missingPropertyInPropOrder(JAXBException.java:250)
	at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.finalizeProperties(AnnotationsProcessor.java:883)
	at org.eclipse.persistence.jaxb.compiler.AnnotationsProcessor.processClassesAndProperties(AnnotationsProcessor.java:282)
	at org.eclipse.persistence.jaxb.compiler.Generator.<init>(Generator.java:150)
	at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:1017)
	... 32 more





[JERSEY-2172] No way to look up a resource by its URI Created: 28/Oct/13  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.4
Fix Version/s: None

Type: Improvement Priority: Critical
Reporter: cowwoc Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

In Jersey 1.0 we could look up a resource by URI using ResourceContext.matchResource(URI). There doesn't seem to be an equivalent functionality in Jersey 2.0.

Use-case: The request entity body references the URI of a resource. I need to convert this URI into a resource class, then drill down into its database id in order to honor the request.



 Comments   
Comment by cowwoc [ 28/Oct/13 ]

FYI, I tried asking this question on the mailing list and http://stackoverflow.com/q/17284419/14731 but got no answer.

Comment by cowwoc [ 28/Oct/13 ]

It looks like I want to be able to create UriInfo from an arbitrary URI but the only way to get a UriInfo is using ContainerRequestContext.getUriInfo(). I tried ContainerRequestContext.setRequestUri(uri) but it failed with:

java.lang.IllegalStateException: Method could be called only in pre-matching request filter.
	at org.glassfish.jersey.server.ContainerRequest.setRequestUri(ContainerRequest.java:329) ~[jersey-server-2.4.jar:na]

I can't use a request filter because I need to process this information inside resource methods (once I understand what kind of operation was invoked), besides which it sounds like this operation would be overkill for what I'm trying to accomplish.

Comment by cowwoc [ 05/Nov/13 ]

Here is an example of how I would use this functionality. Imagine an API with Rooms, Participants, and Connections. Participants are users who joined a Room. Users send messages to each other through Connections (two participants per connection).

POST /rooms/31298
{
  "from": "/rooms/31298/participants/31",
  "to": "/rooms/31298/participants/32"
}

creates a connection between participants 31 and 32. How is the server supposed to honor this request? In Jersey 1.0 I would resolve each URI back to a resource. Each resource contains the following methods:

long getId();
URI getUri();

So, once I've got the resource, I invoke getId() to get the database identifier and create the connection. When someone invokes GET /connections/321213 I convert the database id to a resource and from there invoke getUri(). I take the resulting URI and add it to the response body.

Comment by Marek Potociar [ 07/Nov/13 ]

Reclassified as improvement.

Comment by Marek Potociar [ 07/Nov/13 ]

I'm not sure I fully follow. How do you convert the database Id to a resource?

Would these 2 methods help in your use case?
https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/core/UriBuilder.html#fromResource(java.lang.Class)
https://jax-rs-spec.java.net/nonav/2.0/apidocs/javax/ws/rs/core/UriInfo.html#resolve(java.net.URI)

Comment by cowwoc [ 07/Nov/13 ]

Hi Marek,

> How do you convert the database id to a resource?

In the above example, I'd have something like this:

class RoomResource
{
  private final long id;
  private final UriBuilder uriBuilder;

  public RoomResource(RoomsResource parentResource, UriBuilder uriBuilder, long roomId)
  {
    this.parentResource = parentResource;

    // Each parent passes a child resource its URI
    this.uriBuilder = uriBuilder;
    this.id = roomId;
  }

public long getId()
{
  return id;
}

public URI getUri()
{
  return uri;
}

@POST
public Response RoomResource.createConnection(TwoParticipants participants)
{
  long fromParticipant = uriToId(participants.getFrom());
  long toParticipant = uriToId(participants.getTo());
  Connection connection = Connection.insert(fromParticipant, toParticipant);
  ConnectionResource connectionResource = getConnectionById(connection.getId());
  return Response.created(connectionResource.getUri()).build();
}

@Path("{connectionId}/")
public ConnectionResource getConnectionById(long id)
{
  return new ConnectionResource(this, uriBuilder.path(id + "/"), id);
}

Notice how I use both a conversion from URI to id and id to URI. As mentioned in https://java.net/projects/jersey/lists/users/archive/2013-11/message/62 I now realize that Jersey has no concept of what I call a HTTP Resource (meaning the concept of a resource independent of the response format). I'm looking for a mapping from URI to a resource, independent of the response format, and Jersey doesn't seem to have such a concept per-se. If it had such a concept, the question of how this feature should intersect with filters probably wouldn't be relevant because they wouldn't affect the URI to Resource mapping. Jersey 1.x ResourceContext.matchResource(URI) seemed to behave this way (although maybe not intentionally).

At this point, it's not clear how I can implement this without repeating the URI to Resource mapping twice (once for Jersey using @Path and sub-resource locators, once for my code that implements URI to Resource mapping).

Comment by cowwoc [ 20/Apr/14 ]

It doesn't seem to be possible to implement this without your help.

I tried using ResourceModel to implement this outside of Jersey but:

  1. We need to be able to invoke subresource locators in order to construct a resource
  2. But in order to figure out what arguments need to be passed into a subresource locator, we need to invoke Resource.getResourceLocator().getInvocable().getHandlingMethod().getValueProviders(serviceLocator)
  3. But PathParamValueFactoryProvider.provide() invokes getContainerRequest().getUriInfo().getPathParameters(decode).
  4. This means that the servicelocator we passed into step 2 must return a ContainerRequest for the URI we are looking up, not for the ongoing HTTP request.
  5. The problem is that we cannot create their own ContainerRequest. Invoking the constructor is simple enough, but the UriInfo field is initialized by ReferencesInitializer which is package protected.

It seems that all roads lead to Rome. Jersey needs to provide a mechanism to construct a UriInfo or ContainerRequest to an arbitrary URI.

If you know of another way, please point me in the right direction. I believe this is the only remaining feature preventing me from migrating to Jersey 2.

Comment by cowwoc [ 20/Apr/14 ]

Another approach would be to fix JERSEY-2485.

Comment by levwais [ 22/Apr/14 ]

Hey Guys,
This will be super useful for me.
I want to create a new endpoint that will get, as a request, a list of URIs (other API endpoints) and will run them in a batch.
The missing piece is to find a matching endpoint by a given URI which is something Jersey 1 had via ResourceContext.matchResource(URI) and now, in Jersey 2.x it is impossible.

Thanks,
Lev Waisberg
Jive Software

Comment by cowwoc [ 12/May/14 ]

Lev,

Take a look at http://stackoverflow.com/a/23620747/14731

It's ugly code, but it works. We can only hope that this will get folded into Jersey proper (so we can use this functionality in a cleaner fashion).





[JERSEY-2640] Method register(class, priority) is not retaining the default priority Created: 09/Sep/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.12
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: bodin Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

linux, tomcat8, openjdk 7, servlet 3.x


Sprint: Triaged

 Description   

Using the root ResourceConfig in a servlet 3.0 container, calling register(class, priority) has the same effect as calling register(class).

Summary as I see it

  1. The classes are registered correctly in a ComponentBag.
  2. That component bag is passed to new RuntimeConfig and a copy is made.
  3. At the end of the constructor the classes are registered again (externalClasses).
  4. It appears this second registration wins out over the original.

I should note that this works fine with the annotations. You must not use annotations to recreate this scenario.

Since the ordering of the filters is arbitrary in this bug, you may have to reverse the priorities to see that the ordering of the println doesn't change.

@ApplicationPath("/rest")
public class APIApplication extends ResourceConfig {
	public APIApplication() {

		//switching the 1 and 2 below does not reorder the filters, ordering appears to be completely based on a java Set, which is arbitrary.
		register(Filter1.class, 1);
		register(Filter2.class, 2);
		register(HelloEndpoint.class);
	}
	public static class Filter1 implements ContainerRequestFilter {
		public void filter(ContainerRequestContext request) {			
			System.out.println("Filter 1");			
		}
	}
	public static class Filter2 implements ContainerRequestFilter {
		public void filter(ContainerRequestContext request) {			
			System.out.println("Filter 2");			
		}
	}
	
	@Path("/hello")
	public static class HelloEndpoint {		
		@GET @Produces({MediaType.TEXT_PLAIN})
		public String sayHello(){		
			return "Hello World";		
		}
	}
}


 Comments   
Comment by bodin [ 09/Sep/14 ]

Another comment - it appears in the constructor private RuntimeConfig(final ResourceConfig original) the ResourceConfig passed in is a RuntimeConfig. Inspecting original.state it does not contain the custom filters, instead the original.application.state has all of the model classes registered, which appear to be missed on the copy of the Config in super(original). This causes the second registration of the filters to miss that they have already been configured.

Comment by Adam Lindenthal [ 13/Oct/14 ]

Hi Bodin,

thanks for submitting the issue. I am moving it to backlog, so that we can take a look at it in one of the future sprints.

Regards,
Adam





[JERSEY-2913] oauth1-server excluding all 'application/x-www-form-urlencoded' requests with Content-Type parameters from OAuth1 signature base string Created: 14/Jul/15  Updated: 25/Jan/16

Status: Reopened
Project: jersey
Component/s: security
Affects Version/s: 2.0
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: fkrauthan Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

There is an issue with the oauth1-server package that is not treating requests with a content type like application/x-www-form-urlencoded; charset=UTF-8.



 Comments   
Comment by fkrauthan [ 14/Jul/15 ]

I've created a pull request to fix this issue: https://github.com/jersey/jersey/pull/181





[JERSEY-2978] StringIndexOutOfBoundsException thrown from UriTemplateParser Created: 28/Sep/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: None
Affects Version/s: 2.21
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: komusubi_ Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Linux, JDK1.8, Dropwizard 0.8.4


Sprint: Triaged

 Description   

.StringIndexOutOfBoundsException thrown from
org.glassfish.jersey.uri.internal.UriTemplateParser.processLiteralCharacters
(UriTemplateParser.java:282)

when end of uri character "%", thrown exception below

} else if (c == '%') {
-> final char c1 = s.charAt(i + 1);
final char c2 = s.charAt(i + 2);



 Comments   
Comment by komusubi_ [ 30/Sep/15 ]

create pull request
https://github.com/jersey/jersey/pull/199





[JERSEY-3005] javax.ws.rs.client.ResponseProcessingException is never thrown. Created: 18/Nov/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.22.1
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: puce Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: client
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Sprint: Triaged

 Description   

My analysis so far is as following:
AbstractRootElementJaxbProvider throws subclasses of WebApplicationException instead of an IOException:
https://jersey.java.net/project-info/2.22.1/jersey/project/jersey-media-jaxb/xref/org/glassfish/jersey/jaxb/internal/AbstractRootElementJaxbProvider.html

At least in the latest version this handled somewhat in JerseyInvocation, where WebApplicationException gets catched and wrapped by a ResponseProcessingException.

https://github.com/jersey/jersey/blob/master/core-client/src/main/java/org/glassfish/jersey/client/JerseyInvocation.java#L858

This is wakwards since the nested exception provides a wrong HTTP status code (eg. "HTTP 400 Bad Request", where the request itself was succesful.

In the end the nested WebApplicationException gets unwrapped again:
https://github.com/jersey/jersey/blob/master/core-client/src/main/java/org/glassfish/jersey/client/JerseyInvocation.java#L690

So I think the best thing would be if the AbstractRootElementJaxbProvider class would throw IOException.

The case of a thrown WebApplicationException should never arise when calling response.readEntity (translate method). So the catch clause should be removed and it should be made sure this case never arises (otherwise it would still be catched by the Exception catch statement).

The unwrapping of the cause of the ProcessingException in the translate method also seems wrong in some cases (e.g. when there is no cause). Why not just set the ProcessingException itself as cause?

The IllegalStateException is not handled specially while ProcessingException is. Seems inconsistent.

And last but not least the WebApplicationException should not be unwrapped in the invoke method. Again, I think WebApplicationException should never be the cause of a ProcessingException anyway.



 Comments   
Comment by puce [ 18/Nov/15 ]

I don't seem to have enough rights to fix the typos...

Comment by puce [ 18/Nov/15 ]

OK, according to the Javadoc, the readFrom method of a MessageBodyReader may throw a WebApplicationException, which seems strange as this seems only to make sense on the server side when parsing request messages.

But the same classes are also used on client side to parse response messages, which happens after the webservice has been called (which might be successful or not) and thus readFrom method should not affect the HTTP status code in this case.

http://docs.oracle.com/javaee/7/api/javax/ws/rs/ext/MessageBodyReader.html#readFrom-java.lang.Class-java.lang.reflect.Type-java.lang.annotation.Annotation:A-javax.ws.rs.core.MediaType-javax.ws.rs.core.MultivaluedMap-java.io.InputStream-

Comment by puce [ 19/Nov/15 ]

You should be able to reproduce this issue by writing a JAX-RS client which calls a GET request and tries to unmarshal the response with JAXB using:
https://docs.oracle.com/javaee/7/api/javax/ws/rs/client/SyncInvoker.html#get-java.lang.Class-

and

                <dependency>
			<groupId>org.glassfish.jersey.media</groupId>
			<artifactId>jersey-media-jaxb</artifactId>
			<version>${jersey.version}</version>
		</dependency>

where the response provided by the server does contain a different content than expected -> call was successful, but unmarshalling fails -> should throw a ResponseProcessingException not a WebApplicationException

Comment by puce [ 20/Nov/15 ]

The same issue also happens if you call: response.readEntity(MyJaxbClass.class)

javax.ws.rs.BadRequestException: HTTP 400 Bad Request
	at org.glassfish.jersey.jaxb.internal.AbstractRootElementJaxbProvider.readFrom(AbstractRootElementJaxbProvider.java:136)
	at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:256)
	at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:235)
	at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155)
	at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1085)
	at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874)
	at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:808)
	at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:326)
	at org.glassfish.jersey.client.InboundJaxrsResponse$1.call(InboundJaxrsResponse.java:115)
	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.process(Errors.java:228)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:419)
	at org.glassfish.jersey.client.InboundJaxrsResponse.runInScopeIfPossible(InboundJaxrsResponse.java:267)
	at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:112)
	at <some class>
	at <some class>
	at <some class>
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:94)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
	at java.lang.reflect.Method.invoke(Method.java:619)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at com.github.tomakehurst.wiremock.junit.WireMockStaticRule$1.evaluate(WireMockStaticRule.java:55)
	at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:110)
	at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
Caused by: javax.xml.bind.UnmarshalException
 - with linked exception:
[Exception [EclipseLink-25008] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor with default root element foo was not found in the project]
	at org.eclipse.persistence.jaxb.JAXBUnmarshaller.handleXMLMarshalException(JAXBUnmarshaller.java:1072)
	at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:326)
	at org.glassfish.jersey.jaxb.internal.XmlRootElementJaxbProvider.readFrom(XmlRootElementJaxbProvider.java:140)
	at org.glassfish.jersey.jaxb.internal.AbstractRootElementJaxbProvider.readFrom(AbstractRootElementJaxbProvider.java:134)
	... 41 more
Caused by: Exception [EclipseLink-25008] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor with default root element foo was not found in the project
	at org.eclipse.persistence.exceptions.XMLMarshalException.noDescriptorWithMatchingRootElement(XMLMarshalException.java:162)
	at org.eclipse.persistence.internal.oxm.record.SAXUnmarshallerHandler.startElement(SAXUnmarshallerHandler.java:305)
	at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
	at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
	at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source)
	at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
	at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
	at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
	at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
	at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
	at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
	at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
	at org.eclipse.persistence.internal.oxm.record.XMLReader.parse(XMLReader.java:243)
	at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:401)
	at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:654)
	at org.eclipse.persistence.internal.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:581)
	at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:323)
	... 43 more

A ProcessException would be expected in this case.

Comment by puce [ 20/Nov/15 ]

Here is the stack trace of the first case, where readEntity gets called by JerseyInvocation$Builder.get :

javax.ws.rs.BadRequestException: HTTP 400 Bad Request
	at org.glassfish.jersey.jaxb.internal.AbstractRootElementJaxbProvider.readFrom(AbstractRootElementJaxbProvider.java:136)
	at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:256)
	at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:235)
	at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155)
	at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1085)
	at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874)
	at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:808)
	at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:326)
	at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:803)
	at org.glassfish.jersey.client.JerseyInvocation.access$700(JerseyInvocation.java:92)
	at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:700)
	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.process(Errors.java:228)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
	at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:696)
	at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:420)
	at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:316)
	at <some class>
	at <some class>
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:94)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
	at java.lang.reflect.Method.invoke(Method.java:619)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at com.github.tomakehurst.wiremock.junit.WireMockStaticRule$1.evaluate(WireMockStaticRule.java:55)
	at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:110)
	at com.intellij.junit4.JUnit4TestRunnerUtil$IgnoreIgnoredTestJUnit4ClassRunner.runChild(JUnit4TestRunnerUtil.java:341)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:94)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
	at java.lang.reflect.Method.invoke(Method.java:619)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: javax.xml.bind.UnmarshalException
 - with linked exception:
[Exception [EclipseLink-25008] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor with default root element foo was not found in the project]
	at org.eclipse.persistence.jaxb.JAXBUnmarshaller.handleXMLMarshalException(JAXBUnmarshaller.java:1072)
	at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:326)
	at org.glassfish.jersey.jaxb.internal.XmlRootElementJaxbProvider.readFrom(XmlRootElementJaxbProvider.java:140)
	at org.glassfish.jersey.jaxb.internal.AbstractRootElementJaxbProvider.readFrom(AbstractRootElementJaxbProvider.java:134)
	... 47 more
Caused by: Exception [EclipseLink-25008] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.XMLMarshalException
Exception Description: A descriptor with default root element foo was not found in the project
	at org.eclipse.persistence.exceptions.XMLMarshalException.noDescriptorWithMatchingRootElement(XMLMarshalException.java:162)
	at org.eclipse.persistence.internal.oxm.record.SAXUnmarshallerHandler.startElement(SAXUnmarshallerHandler.java:305)
	at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
	at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
	at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source)
	at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
	at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
	at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
	at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
	at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
	at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
	at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
	at org.eclipse.persistence.internal.oxm.record.XMLReader.parse(XMLReader.java:243)
	at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:401)
	at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:654)
	at org.eclipse.persistence.internal.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:581)
	at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:323)
	... 49 more

In this case a ResponseProcessingException would be expected containing the response object with the correct status code.

Comment by puce [ 23/Nov/15 ]

Related issue: JERSEY-2468





[JERSEY-3054] Memory-leak after jersey upgrade from 2.17 to 2.22.1 Created: 10/Feb/16  Updated: 10/Feb/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.22.1
Fix Version/s: None

Type: Bug Priority: Critical
Reporter: bruge Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: memory-leak
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)



 Description   

After upgrading Jersey from 2.17 to 2.22.1 we have been observing a memory leak in our application that forces us to restart the production servers regularly. After inspecting a heap dump we found out so far, that the hk2 library might be the problem for that (see attached files).



 Comments   
Comment by bruge [ 10/Feb/16 ]

Since i can't attach files, I have to provide links instead:
http://pltzchn.de/heapdump1.png
http://pltzchn.de/heapdump2.png





[JERSEY-235] WADL generation should support producing multiple mime/types Created: 09/Mar/09  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: tools
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: cquiroz Assignee: Unassigned
Resolution: Unresolved Votes: 3
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issuezilla Id: 235
Tags: wadl

 Description   

The current ant/maven tasks to generate wadl can be enhanced by means of
extended tags on the java docs.

For example to document the response for a particular resource of a given
media-type you can add the tags
@response.representation.200.doc
@response.representation.200.example

However, the current implementation does not support the case where a resource
has more than one representation type, for example using the tage

@Produces(

{"text/xml", "application/json"}

)

In this case the documentation task will pick only one of them for the WADL file

Ideally you should be able to create javadoc tags that are specific to different
media types

Carlos






[JERSEY-351] Parameter Validation Created: 18/Aug/09  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: dirkm Assignee: Unassigned
Resolution: Unresolved Votes: 7
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All
URL: http://n2.nabble.com/Required-parameters-on-a-Resource-td3446928.html


Issuezilla Id: 351

 Description   

Add more flexible parameter validation to Jersey.

In particular, the solution should at least include the ability to check if a
parameter is present and raise an error if is not.
In general and eventually the solution should allow flexible parameter validation.

Possible solutions:

1) Jersey supports an @Required annotation; or

2) Exposes a lower-level abstraction of MultivaluedParameterExtractor
(which is an internally used interface):

public interface MultivaluedParameterExtractor

{ Object extract(MultivaluedMap<String, String> parameters); }

public interface MultivaluedParameterExtractorProvider { }

public interface MultivaluedParameterExtractorWorkers { }

and the same type of pattern can be utilized.

3) One can utilize AOP method-level interceptors to support @Required
and check for a null value. This solution is much better if one needs to take
into account more than one value.

I also wonder if there is a more general approach to parameter
validation we can apply with the bean validation framework.



 Comments   
Comment by ccamel [ 01/Feb/11 ]

This feature will be great.

I think it would be interesting to use a set of annotations derived from JSR-305.





[JERSEY-399] Add support for @required attribute on a parameter Created: 27/Oct/09  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: loizos Assignee: Unassigned
Resolution: Unresolved Votes: 10
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: Macintosh


Issuezilla Id: 399

 Description   

Jersey (or JAX-RS) does not currently allow us to set whether a parameter is
required or not. It is difficult to make assumptions on whether a param is
required (even in the case of form params since regexps can be used in clever
ways). It would be useful if parameters could be annotated with @Required and if
the parameter is absent a 400 response will be returned.

This should also be set in WADL generation.






[JERSEY-408] Get Matrix Parameter from current path segment Created: 02/Nov/09  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 1.1.1-ea
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: geoff_hendrey Assignee: Unassigned
Resolution: Unresolved Votes: 5
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: Macintosh


Issue Links:
Dependency
blocks JERSEY-1370 Problem invoking service with nested ... Closed
blocks JERSEY-1548 MatrixParam present in sub-resource i... Closed
Issuezilla Id: 408

 Description   

The @MatrixParam annotation will only detect matrix parameters when they are the
last thing in the URL. For example:

.../X;a=b will work

but .../X;a=b/ will not work

and .../X;a=b/Y/ will not work

Paul's suggestion to address this would be:

1) The ability to get the current path segment or segments associated with the
resource; and

2) a qualifier on @MatrixParam to declare that the matrix parameter is
associated with the current path segment
(or the last path segment in the current set).



 Comments   
Comment by tvf [ 17/Feb/12 ]

I'd like to see @MatrixParam supporting this as being able to use MatrixParams embedded in the URI is one of the main advantages of using them at all.

IMO @MatrixParam should always handle the matrix params at the end of the currently matched path. Whether or not other matrix parameters come later in the URI should be of no relevance for this.

Comment by Jakub Podlesak [ 21/Oct/13 ]

Moved to unplanned, as this should be fixed soon.

Comment by cowwoc [ 22/Oct/13 ]

Please see my (related) proposal here: https://java.net/jira/browse/JAX_RS_SPEC-3

Comment by emailnbw [ 13/Nov/13 ]

Whats the status on this? I need my MatrixParameters in sub resources

Comment by cowwoc [ 06/Jun/14 ]

Jakub,

8 months have elapsed. Do you plan on fixing this anytime soon?





[JERSEY-473] Access client port and IP address from HttpRequestContext Created: 17/Feb/10  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: sandoz Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: Macintosh


Issuezilla Id: 473

 Description   

Currently the only way to obtain the client IP address and port is by injecting
HttpServletRequest.

We need to support a method on HttpRequestContext implementations of which can
defer to Servlet or say the low-level Grizzly API.

Low-level Grizzly request has:

request.remoteAddr().toString();
request.getRemotePort();



 Comments   
Comment by sandoz [ 17/Feb/10 ]

Clarification use:

GrizzlyRequest.getRemoteAddr()

Comment by spektom [ 22/Aug/13 ]

For a while, I'm using this hack to get the remote IP information: http://stackoverflow.com/a/18378248/398309

Comment by mikaelstaldal [ 11/Sep/14 ]

In the context of JAX-RS 2 and Jersey 2, It would make sense to add a method for this to javax.ws.rs.core.Request. Perhaps something for JAX-RS 2.1?

In the meantime, it can be added to org.glassfish.jersey.server.ContainerRequest





[JERSEY-551] Improved serialization of java.util.Map Created: 22/Jun/10  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: media
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: romixlev Assignee: Unassigned
Resolution: Unresolved Votes: 3
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All
URL: http://old.nabble.com/Custom-mapping-for-Maps-in-JAXB-ts28779221r0.html


Attachments: Java Source File JsonMapAdapter.java     Java Source File JsonMapAdapter.java    
Issuezilla Id: 551

 Description   

Currently, to serialize java.util.Map objects to JSON, one needs to write a
special @XmlJavaTypeAdapter annotation and usually covert the map into list of
(key,value) entires, which are then marshalled/unmarshalled by JAXB.
The representation for a key/value pair produced by this approach usually looks
like this:

{"key": "MyKey", "value" : "MyValue"}

This is not very natural for JSON, as

{"MyKey":"MyValue"}

would be a more usual
JSON-like representation. Unfortunately, this JSON-friendly representation
cannot be easily produced by jersey-json, because it works via JAXB and JAXB
cannot produce this out of the box easily, as it relies on XML Schemas and this
representation requires XML tag names that are dynamic, which is impossible.

Therefore, it would be nice to introduce the possibility to serialize Maps into
a natural JSON format.

Please find attached a class called JsonMapAdapter.
It can be used like this to achieve the desired effect:

@XmlRootElement(name="YourClassElementName")
class YourClass {
...

@XmlElement(name="YourMapElementName")
// Here is the trick: Use use special map adapter for maps (see below)
@XmlJavaTypeAdapter(JsonMapAdapter.class)
private Map<String,String> yourMap = new LinkedHashMap<String,String>();

...
}

Please see this mailing list discussion for more information:
http://old.nabble.com/Custom-mapping-for-Maps-in-JAXB-ts28779221r0.html

NOTE: This approach seems to work nicely for Map<String,String>. But if values
are JAXB-annotated classes, it most likely would not work out of the box. The
way to solve this issue still needs to be investigated.



 Comments   
Comment by romixlev [ 22/Jun/10 ]

Created an attachment (id=131)
XML type adapter implementation for producing JSON friendly format from java.util.Map

Comment by romixlev [ 25/Jun/10 ]

Created an attachment (id=133)
New version of JsonMapAdapter that supports also JAXB-annotated classes as Values of Maps

Comment by romixlev [ 25/Jun/10 ]

>NOTE: This approach seems to work nicely for Map<String,String>. But if values
>are JAXB-annotated classes, it most likely would not work out of the box. The
>way to solve this issue still needs to be investigated.

I attached a new version of the JsonMapAdapter class, which tries to address the
mentioned limitation. It seems to work for me on a bunch of use-cases. In
particular, values inside maps can be @XmlRootElement types. And this new
version also supports @XmlRootElement, where name or namespace annotation
parameters are not specified.

An important point for mapped notation is not to forget to call the xml2JsonNs
in the builder with a complete set of namespace used by your JAXB classes, as
namespace information is otherwise lost in the mapped notation.

Please test if it works for you and provide input about discovered problems.

TODO: Right now, unmarshalling would only work for a value of class C, if at
least one object of class C was marshalled before as a value of the map. So,
first marshal, then unmarshal. The reason for this limitation is due to the fact
that JsonMapAdapter needs to be able to map qualified XML element names to the
JAXB annotated classes and JAXBContexts. And at the moment this mapping is done
implicitly during marshalling.
Alternatively, one can think about explicit APIs for developers to provide such
a mapping at run-time to the generic JsonMapAdapter.

Comment by mike_meessen [ 28/Nov/10 ]

romixlev, your solution looks like a good starting point!

I ran into an issue though:
in your "marshal" method, the following line fails if the key is numeric:

Element keyValueElement = doc.createElement(entry.getKey().toString());

entity.getKey().toString() produces e.g. "4", which is not a valid xml entity and causes:

SEVERE: org.w3c.dom.DOMException: INVALID_CHARACTER_ERR: An invalid or illegal XML character is specified.
SEVERE: at com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl.createElement(CoreDocumentImpl.java:618)

Any idea how to fix this? If I change the line to the following, it works but output is obviously wrong:

Element keyValueElement = doc.createElement("x" + entry.getKey().toString());

All in all, XML isn't Json and having to jump through it ends up being a real pain :/

Comment by Paul Merlin [ 24/Feb/11 ]

@mike_meessen I ran into the very same issue, it is impossible to use a string key starting with a number. In case of UUIDs it works only when the UUID start with a letter.

From what I understand it's impossible to solve the issue except by removing JAXB from the equation.

That's a real pitty that JAX-RS 1 cannot produce simple json like that. I don't know about JAX-RS 2 but if it's still based on JAXB the problem will remain.

I hope someone can prove us wrong and tell us "there is a way and this is ...".

Regards





[JERSEY-1456] Allow encoded slashes for JAX-RS application by default Created: 20/Jul/11  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.0-m13
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: mkarg Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Win7 Pro SP1 64 Bit de_DE



 Description   

GlassFish does not allow encoded slashes in URLs by default. It is told that this would be for security reasons. But, encoded slashes are allowed by default for "admin-listener". I suspect the reason is that somebody noticed that there now is a JAX-RS based admin interface at that port which otherwise will not work.

So it is doubtful why user's JAX-RS application are still not allowed to receive encoded slashes, as the implementation (Jersey) has no security problems to handle them. People are forced to find out how to enable this explicitly (in fact I did not find it in the manuals at all but needed to ask in a forum, where someone told me the cryptic spell to cast, so GlassFish will magically work as virtually all JAX-RS deployers and application vendors wants it to work like:

 asadmin set
 configs.config.server-config.network-config.protocols.protocol.http-listener-1.http.encoded-slash-enabled=true

).

I want to propose two things to reduce the level of torture one have to bear:

(1) The deployment manual should clearly contain that above code line and it should be marked in a colourful way that everbody will directly find it when about to deploy a JAX-RS application on GlassFish.

(2) JAX-RS applications by default should be allowed to receive encoded slashes. A JAX-RS application prodiver is coding according to the JAX-RS specification, which does not prevent slashes, and nobody at the Jersey team so far mentioned any problems with slashes in the Jersey product. The risk covered by the prevention of slash, in my opinion, mostly exists in Servlet applications. But, again, a JAX-RS application is not a servlet by definition (the Jersey container is one, but that is not suffering from that security problem with slashes).



 Comments   
Comment by Tom Mueller [ 20/Jul/11 ]

Marek, can you please take a look at this one. If you aren't the right person, do you know who is?

Comment by Marek Potociar [ 07/Dec/11 ]

Hi Tom,
Not sure what to do about this. I am not aware of any security issues with URLs containing encoded slashes in JAX-RS apps.

Is there a way in GF to automatically allow encoded slashes for URLs handled by the Jersey container? To me it seems that the configuration mentioned above is not granular enough. IOW, it's either enabled or disabled for all containers attached handling the requests on the particular listener.

Comment by mkarg [ 10/Jul/12 ]

What is the current status of this issue?

Comment by Marek Potociar [ 06/Mar/13 ]

I'm moving the issue to backlog so that we can follow up on it after 2.0 release.





[JERSEY-1767] Jersey Client needs performance testing Created: 05/Mar/13  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core, performance
Affects Version/s: 2.0-m13
Fix Version/s: None

Type: Task Priority: Major
Reporter: Jason Lee Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The Jersey client does not have any performance testing coverage. I'm filing this task per Jakub's request.






[JERSEY-1799] Add suspend and resume support for the simple container Created: 18/Mar/13  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: containers
Affects Version/s: 2.0-m13, 2.0
Fix Version/s: None

Type: Task Priority: Major
Reporter: gallagher_niall Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I have attached a patch to get suspend and resume working properly with SimpleContainer. I have also added a new test for this.



 Comments   
Comment by gallagher_niall [ 18/Mar/13 ]

diff --git a/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java b/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java
index 15bdef6..c194a4a 100644
— a/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java
+++ b/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java
@@ -47,15 +47,23 @@ import java.security.Principal;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import java.util.logging.Logger;

-import javax.ws.rs.core.SecurityContext;
-
import javax.inject.Inject;
import javax.inject.Provider;
+import javax.ws.rs.core.SecurityContext;

+import org.glassfish.hk2.api.PerLookup;
+import org.glassfish.hk2.api.ServiceLocator;
+import org.glassfish.hk2.api.TypeLiteral;
+import org.glassfish.hk2.utilities.Binder;
+import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.internal.MapPropertiesDelegate;
import org.glassfish.jersey.internal.inject.ReferencingFactory;
import org.glassfish.jersey.internal.util.ExtendedLogger;
@@ -70,18 +78,13 @@ import org.glassfish.jersey.server.internal.ConfigHelper;
import org.glassfish.jersey.server.spi.Container;
import org.glassfish.jersey.server.spi.ContainerLifecycleListener;
import org.glassfish.jersey.server.spi.ContainerResponseWriter;
+import org.glassfish.jersey.server.spi.ContainerResponseWriter.TimeoutHandler;
import org.glassfish.jersey.server.spi.RequestScopedInitializer;
-
-import org.glassfish.hk2.api.PerLookup;
-import org.glassfish.hk2.api.ServiceLocator;
-import org.glassfish.hk2.api.TypeLiteral;
-import org.glassfish.hk2.utilities.Binder;
-import org.glassfish.hk2.utilities.binding.AbstractBinder;
-
import org.simpleframework.http.Address;
import org.simpleframework.http.Request;
import org.simpleframework.http.Response;
import org.simpleframework.http.Status;
+import org.simpleframework.util.thread.Daemon;

/**

  • Simple Jersey HTTP Container.
    @@ -132,14 +135,20 @@ public final class SimpleContainer implements org.simpleframework.http.core.Cont

private volatile ApplicationHandler appHandler;
private volatile ContainerLifecycleListener containerListener;
+ private final DelayQueue<SuspendTimer> suspendQueue;
+ private final SuspendMonitor suspendMonitor;

private final static class Writer implements ContainerResponseWriter {
+ private final AtomicReference<SuspendTimer> reference;
+ private final DelayQueue<SuspendTimer> queue;
private final Response response;
private final Request request;

  • Writer(Request request, Response response) {
    + Writer(Request request, Response response, DelayQueue<SuspendTimer> queue) { + this.reference = new AtomicReference<SuspendTimer>(); this.response = response; this.request = request; + this.queue = queue; }

@Override
@@ -169,12 +178,33 @@ public final class SimpleContainer implements org.simpleframework.http.core.Cont

@Override
public boolean suspend(long timeOut, TimeUnit timeUnit, TimeoutHandler timeoutHandler) {

  • throw new UnsupportedOperationException("Method suspend is not supported by the container.");
    + SuspendTimer suspendTimer = reference.get();
    +
    + if(suspendTimer == null)
    Unknown macro: {+ suspendTimer = new SuspendTimer(this, response, timeOut, timeUnit, timeoutHandler);+ reference.set(suspendTimer);+ + if(timeOut > 0) { + queue.offer(suspendTimer); + }+ }

    + return true;
    }

@Override
public void setSuspendTimeout(long timeOut, TimeUnit timeUnit) throws IllegalStateException {

  • throw new UnsupportedOperationException("Method suspend is not supported by the container.");
    + SuspendTimer suspendTimer = reference.get();
    +
    + if(suspendTimer == null) { + throw new IllegalStateException("Response has not been suspended yet"); + }

    + if(queue.remove(suspendTimer))

    Unknown macro: {+ suspendTimer.setDelay(timeOut, timeUnit);+ + if(timeOut > 0) { + queue.offer(suspendTimer); + }+ }

    }

@Override
@@ -220,11 +250,124 @@ public final class SimpleContainer implements org.simpleframework.http.core.Cont
throw new ContainerException(error);
}
}
-
+ }
+
+ private final static class SuspendTimer implements Delayed {
+
+ private ContainerResponseWriter responseWriter;
+ private TimeoutHandler timeoutHandler;
+ private Response response;
+ private volatile long time;
+
+ public SuspendTimer(ContainerResponseWriter responseWriter, Response response, long delay, TimeUnit timeUnit, TimeoutHandler timeoutHandler)

{ + this.time = getTime() + timeUnit.toNanos(delay); + this.responseWriter = responseWriter; + this.timeoutHandler = timeoutHandler; + this.response = response; + }

+
+ public Response getResponse()

{ + return response; + }

+
+ public ContainerResponseWriter getContainerResponseWriter()

{ + return responseWriter; + }

+
+ public TimeoutHandler getTimeoutHandler()

{ + return timeoutHandler; + }

+
+ private long getTime()

{ + return System.nanoTime(); + }

+
+ public long getDelay(TimeUnit unit)

{ + return unit.convert(time - getTime(), TimeUnit.NANOSECONDS); + }

+
+ public void setDelay(long delay, TimeUnit unit)

{ + this.time = getTime() + unit.toNanos(delay); + }

+
+ public int compareTo(Delayed other) {
+ SuspendTimer entry = (SuspendTimer) other;
+
+ if(other == this)

{ + return 0; + }

+ return compareTo(entry);
+ }
+
+ private int compareTo(SuspendTimer entry) {
+ long diff = time - entry.time;
+
+ if(diff < 0)

{ + return -1; + }

else if(diff > 0)

{ + return 1; + }

+ return 0;
+ }
+ }
+
+ public static class SuspendMonitor extends Daemon {
+
+ private final DelayQueue<SuspendTimer> delayQueue;
+ private final AtomicBoolean active;
+
+ public SuspendMonitor(DelayQueue<SuspendTimer> delayQueue)

{ + this.active = new AtomicBoolean(true); + this.delayQueue = delayQueue; + }

+
+ public void stop()

{ + active.set(false); + }

+
+ @Override
+ public void run() {
+ while(active.get()) {
+ try {
+ SuspendTimer suspendTimer = delayQueue.poll(5L, TimeUnit.SECONDS);
+
+ if(suspendTimer != null) {
+ TimeoutHandler timeoutHandler = suspendTimer.getTimeoutHandler();
+ ContainerResponseWriter responseWriter = suspendTimer.getContainerResponseWriter();
+ Response response = suspendTimer.getResponse();
+
+ if(!response.isCommitted())

{ + SuspendTimeoutNotifier timeout = new SuspendTimeoutNotifier(responseWriter, timeoutHandler); + timeout.start(); + }

+ }
+ }catch(Throwable e)

{ + logger.log(Level.SEVERE, "Could not notify of timeout.", e); + Thread.yield(); + }

+ }
+ }
+ }
+
+ private static class SuspendTimeoutNotifier extends Daemon {
+
+ private ContainerResponseWriter responseWriter;
+ private TimeoutHandler timeoutHandler;
+
+ public SuspendTimeoutNotifier(ContainerResponseWriter responseWriter, TimeoutHandler timeoutHandler)

{ + this.responseWriter = responseWriter; + this.timeoutHandler = timeoutHandler; + }

+
+ @Override
+ public void run()

{ + timeoutHandler.onTimeout(responseWriter); + }

+
}

public void handle(final Request request, final Response response)

{ - final Writer responseWriter = new Writer(request, response); + final Writer responseWriter = new Writer(request, response, suspendQueue); final URI baseUri = getBaseUri(request); final URI requestUri = baseUri.resolve(request.getTarget()); @@ -324,12 +467,17 @@ public final class SimpleContainer implements org.simpleframework.http.core.Cont containerListener.onReload(this); containerListener = ConfigHelper.getContainerLifecycleListener(appHandler); }

+
+ void onServerStop()

{ + this.suspendMonitor.stop(); + }

/**

  • Inform this container that the server was started. This method must be implicitly called after
  • the server containing this container is started.
    */
    void onServerStart() { + this.suspendMonitor.start(); this.containerListener.onStartup(this); }

@@ -340,6 +488,8 @@ public final class SimpleContainer implements org.simpleframework.http.core.Cont

  • @param application Jersey application to be deployed on Grizzly container.
    */
    SimpleContainer(final ApplicationHandler application) {
    + this.suspendQueue = new DelayQueue<SuspendTimer>();
    + this.suspendMonitor = new SuspendMonitor(suspendQueue);
    this.appHandler = application;
    this.containerListener = ConfigHelper.getContainerLifecycleListener(application);

diff --git a/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java b/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java
index d0b00ed..a5b68a8 100644
— a/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java
+++ b/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java
@@ -39,25 +39,24 @@
*/
package org.glassfish.jersey.simple;

+import java.io.Closeable;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.URI;
+
+import javax.net.ssl.SSLContext;
+
import org.glassfish.jersey.internal.ProcessingException;
import org.glassfish.jersey.server.ApplicationHandler;
import org.glassfish.jersey.server.ContainerFactory;
import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.server.internal.ConfigHelper;
-import org.glassfish.jersey.server.spi.ContainerLifecycleListener;
import org.simpleframework.http.core.Container;
import org.simpleframework.http.core.ContainerServer;
import org.simpleframework.transport.Server;
import org.simpleframework.transport.connect.Connection;
import org.simpleframework.transport.connect.SocketConnection;

-import javax.net.ssl.SSLContext;
-import java.io.Closeable;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.net.URI;
-
/**

  • Factory for creating and starting Simple server containers. This returns
  • a handle to the started server as {@link Closeable}

    instances, which allows
    @@ -111,7 +110,7 @@ public final class SimpleContainerFactory {
    *

  • @param address the URI to create the http server. The URI scheme must be
  • equal to "https". The URI user information and host
  • * are ignored If the URI port is not present then port 143 will be
    + * are ignored If the URI port is not present then port 443 will be
  • used. The URI path, query and fragment components are ignored.
  • @param context this is the SSL context used for SSL connections
  • @param config the resource configuration.
    @@ -157,7 +156,7 @@ public final class SimpleContainerFactory {
    *
  • @param address the URI to create the http server. The URI scheme must be
  • equal to "https". The URI user information and host
  • * are ignored If the URI port is not present then port 143 will be
    + * are ignored If the URI port is not present then port 443 will be
  • used. The URI path, query and fragment components are ignored.
  • @param context this is the SSL context used for SSL connections
  • @param container the container that handles all HTTP requests
    @@ -180,7 +179,7 @@ public final class SimpleContainerFactory {
    if (!scheme.equalsIgnoreCase("https")) { throw new IllegalArgumentException("The URI scheme should be 'https' when using SSL"); }
  • defaultPort = 143; // default HTTPS port
    + defaultPort = 443; // default HTTPS port
    }
    int port = address.getPort();

@@ -198,6 +197,26 @@ public final class SimpleContainerFactory {
} catch (IOException ex)

{ throw new ProcessingException("IOException thrown when trying to create simple server", ex); }
  • return connection;
    + return new ClosableContainer(container, connection);
    + }
    +
    + private static final class ClosableContainer implements Closeable {
    +
    + private final SimpleContainer container;
    + private final Connection connection;
    +
    + public ClosableContainer(SimpleContainer container, Connection connection) { + this.connection = connection; + this.container = container; + }

    +
    + @Override
    + public void close() throws IOException

    Unknown macro: {+ try { + connection.close(); + } finally { + container.onServerStop(); + }+ }

    }
    }

Comment by gallagher_niall [ 18/Mar/13 ]

/*

  • DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    *
  • Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
    *
  • The contents of this file are subject to the terms of either the GNU
  • General Public License Version 2 only ("GPL") or the Common Development
  • and Distribution License("CDDL") (collectively, the "License"). You
  • may not use this file except in compliance with the License. You can
  • obtain a copy of the License at
  • http://glassfish.java.net/public/CDDL+GPL_1_1.html
  • or packager/legal/LICENSE.txt. See the License for the specific
  • language governing permissions and limitations under the License.
    *
  • When distributing the software, include this License Header Notice in each
  • file and include the License file at packager/legal/LICENSE.txt.
    *
  • GPL Classpath Exception:
  • Oracle designates this particular file as subject to the "Classpath"
  • exception as provided by Oracle in the GPL Version 2 section of the License
  • file that accompanied this code.
    *
  • Modifications:
  • If applicable, add the following below the License Header, with the fields
  • enclosed by brackets [] replaced by your own identifying information:
  • "Portions Copyright [year] [name of copyright owner]"
    *
  • Contributor(s):
  • If you wish your version of this file to be governed by only the CDDL or
  • only the GPL Version 2, indicate your decision by adding "[Contributor]
  • elects to include this software in this distribution under the [CDDL or GPL
  • Version 2] license." If you don't indicate a single choice of license, a
  • recipient has the option to distribute your version of this file under
  • either the CDDL, the GPL Version 2 or to extend the choice of license to
  • its licensees as provided above. However, if you add GPL Version 2 code
  • and therefore, elected the GPL Version 2 license, then the option applies
  • only if the new code is made subject to such option by the copyright
  • holder.
    */
    package org.glassfish.jersey.test.simple;

import static org.junit.Assert.assertEquals;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.Context;

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.simple.SimpleContainer;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import org.simpleframework.http.Request;
import org.simpleframework.http.Response;

/**

  • Test class for {@link SimpleContainer}

    .
    *

  • @author Arul Dhesiaseelan (aruld@acm.org)
  • @author Miroslav Fuksa (miroslav.fuksa at oracle.com)
    */
    public class SimpleContainerSuspendTest extends JerseyTest {

/**

  • Creates new instance.
    */
    public SimpleContainerSuspendTest() { super(new SimpleTestContainerFactory()); }

@Override
protected ResourceConfig configure()

{ return new ResourceConfig(Resource.class); }

/**

  • Test resource class.
    */
    @Path("one")
    public static class Resource {

private final Request request;
private final Response response;

public Resource(@Context Request request,
@Context Response response)

{ this.request = request; this.response = response; }

/**

  • Test resource method.
    *
  • @return Test simple string response.
    */
    @GET
    public void call(@Suspended final AsyncResponse response) {
    new Thread(new Runnable() {
    @Override
    public void run()
    Unknown macro: { try { Thread.sleep(5000); response.resume("get"); } catch(Exception e) { e.printStackTrace(); } }

    }).start();
    }
    }

@Test
/**

  • Test {@link Simple HttpServer}

    container.
    */
    public void testSimpleContainerTarget()

    { int status = target().path("one").request().get().getStatus(); assertEquals("Response status unexpected.", 200, status); }

    }

Comment by Marek Potociar [ 19/Mar/13 ]

To accept the patch we need a signed OCA. Please see here: http://jersey.java.net/contribute/

Comment by gallagher_niall [ 19/Mar/13 ]

I have already signed and submitted this a few years back. I am the original author of the SimpleContainer framework.





[JERSEY-1950] Enable Jersey/Guice integration via HK2 Guice Bridge Created: 24/Jun/13  Updated: 20/Jan/16

Status: Open
Project: jersey
Component/s: extensions
Affects Version/s: 2.0
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: jwells Assignee: Unassigned
Resolution: Unresolved Votes: 52
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Dependency
blocks HK2-121 Guice-servlet integration Open
Related
is related to JERSEY-2184 Ability to inject ServletContext into... Closed
is related to JERSEY-1957 Implement Spring integration for Jers... Closed
is related to HK2-139 @Hk2Inject does not work on the const... Open

 Description   

The HK2 Guice Bridge is available, but there may be more work needed in Jersey in order to enable it.



 Comments   
Comment by cowwoc [ 24/Jun/13 ]

This issue is related to https://java.net/jira/browse/HK2-39 and https://java.net/jira/browse/HK2-121

To reiterate, here is what we had in Jersey 1.0:

Container
\-> GuiceFilter (Guice: initialize request scope)
  \-> GuiceServletContextListener (Guice: initialize the Guice injector)
    \-> JerseyServletModule (Jersey: bind Jersey types to Guice module)
      \-> GuiceContainer (Jersey: redirect incoming requests to resource classes)

In other words, we created a Guice injector first and initialized Jersey second.

In Jersey 2.0 we have a circular reference. We need to initialize Injector before ServletContainer (otherwise @RequestScoped isn't initialized), but we need to initialize ServletContainer before Injector (otherwise we can't get a reference to ServiceLocator).

Comment by vokiel [ 15/Aug/13 ]

I've been reading the various issues on Guice with Jersey 2.0 & HK2 and I have to say I'm a bit confused as to what the bridge allows currently and what it doesn't allow. I'm trying to get Guice-Persist to work with Jersey, but yes it just won't inject what the module defines (factories and such).

If I just use the bridge as is and install a JpaPersistModule into the HK2 bridge, shouldn't it be able to inject an EntityManager from the Guice definition in my resources afterward? All that without having to use GuiceFilter & the Servlet plumbing of Guice? Isn't this just adaptation?

What sm I missing or what's the status?

Comment by cowwoc [ 17/Aug/13 ]

Jersey 2.0 doesn't support Guice, period.

Development is being held up on the Jersey end of things, not HK2.

Anyone wishing to help should take a look at how Spring integration was added in JERSEY-1957 and try to replicate the technique for Guice.

Comment by cowwoc [ 27/Sep/13 ]

I finally figured out how to wedge Guice support into Jersey 2 (mostly through trial and error). Can someone from the Jersey team please review and publish the following documentation as part of the official user guide?


1. Add GuiceFilter and ServletContainer to web.xml:

    <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>

    <filter>
        <filter-name>JerseyApplication</filter-name>
        <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.mycompany.MyApplication</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>JerseyApplication</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

2. Note that GuiceFilter must show up before ServletContainer.
3. Define an application as follows:

public class MyApplication extends ResourceConfig {

    @Inject
    public MyApplication(ServiceLocator serviceLocator) {
        // Register root resources, then...
        
        // Instantiate Guice Bridge
        GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);

        GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
        Injector injector = Guice.createInjector(new MyModule());
        guiceBridge.bridgeGuiceInjector(injector);
    }
}

4. Define a Guice module as follows:

public class MyModule extends AbstractModule {

    @Override
    protected void configure() {
        // Configure Guice as you normally would, then...

        install(new ServletModule());
    }
}

5. ServletModule defines the "request" scope. GuiceFilter creates/destroys the scope on each incoming request.


Let's begin by amending the documentation, and then we can follow up by adding a sample application and unit tests that mirror the Spring module.

Comment by jwells [ 27/Sep/13 ]

That's a gr8 solution. I'd still like to see a more integrated solution though...

Comment by reinert [ 27/Sep/13 ]

It is not possible to just substitute H2K to Guice?

I don't like the idea of two DI containers working together. I would rather prefer just using Guice for managing every DI issue in my application.

Comment by cowwoc [ 27/Sep/13 ]

@jwells, what did you have in mind?
@reinert, I don't think Jersey gives us an option. I believe it forces the use of HK2.

Comment by cowwoc [ 27/Oct/13 ]

Bad news. The above solution won't work. It only initializes one direction of HK2's bi-directional bridge.

I am beyond frustrated with this, having spent days trying to get it to work.

@jwells, please contact me by email (cowwoc at bbs.darktech.org). I'd like to resolve this issue once and for all over chat. Playing tag over the issue tracker is not working out.

Comment by cowwoc [ 28/Oct/13 ]

I found a way to beat the circular dependency for Injector. You can create the main Injector before the Application. Once you're inside Application, you create a child injector and pass in Hk2Module(serviceLocator) as follows: injector.createChildInjector(new Hk2Module(serviceLocator))

Now both Guice and HK2 are happy. This moves us in the right direction but it's still not a working solution:

1. There is no clean way to pass the root Injector into the Application class due to http://stackoverflow.com/q/19596592/14731. Currently I'm passing the variable using a public singleton, which is ugly.
2. There are problems mixing Guice and HK2 types. See HK2-139.

I will continue working to resolve this.

Comment by jontro [ 04/Nov/13 ]

@cowwoc

Would you mind trying out the solution outlined in https://java.net/jira/browse/HK2-121 ?

Comment by cowwoc [ 04/Nov/13 ]

@jontro

I replied to your solution, in HK2-121. Let's keep the discussion there to reduce noise for everyone else watching this issue.

Comment by cowwoc [ 07/Dec/13 ]

Proposal:

  1. Isolate all HK2-specific bindings into reusable "factories".
  2. Extract all HK2-specific code into its own module. jersey-core would only use JSR 330 to @Inject but it wouldn't do the actual binding or construction of the ServiceLocator. Instead of Application creating ServiceLocator, ServiceLocator would create the Application (more on this below).
  3. The user add the HK2, Guice or Spring module to the classpath at built-time.
  4. At startup these implementation would bind against the factories from step 1, inject the Application class, answer all subsequent @Inject requests.

The beauty of this is that Jersey would depend on JSR 330 instead of HK2 directly, and wouldn't need to manage any DI frameworks (as it did in 1.0).

Jersey committers: what do you think of this proposal?

Comment by cowwoc [ 14/Dec/13 ]

Can someone please change the title of this issue from "Enable Jersey/Guice integration via HK2 Guice Bridge" to "Guice support"? I don't think we'll be able to use the HK2 bridge for that.

Comment by jontro [ 05/Feb/14 ]

I would just like to add that I support @cowwoc completely. After a couple of months now since switching to jersey 2.x from the 1.x version it really feels cumbersome developing with both hk2 and guice.

Is it possible to reach a consensus on how this should move forward?

Comment by bowenwr [ 06/Apr/14 ]

I'm also voicing my support for moving forward on this issue.

Comment by djxak [ 06/May/14 ]

I think Jersey need to be DI framework agnostic.

For example I have a maven module in my application with JPA persistence classes. Entities and DAOs. DAOs implemented with Guice. They receive request-scoped EntityManager by Guice DI, have methods with @Transactional annotation (by guice-persist) etc.

Now I want to use this DAOs in my new REST module. For this I need to inject them to appropriate Jersey Resources. I don't want to rewrite all my DAOs with HK2. They already used in another UI module of my application. And HK2 doesn't provide functionality similar to guice-persist (request scoped UnitOfWork, @Transactional interceptor).

Comment by jitterted [ 06/May/14 ]

I've voted for this, but I also wanted to comment that because of this issue alone, I may be forced to switch to another JAX-RS provider (namely RESTEasy, which works quite well with Guice, thank you very much). Obviously I'd rather not do that, but HK2 is really getting in my way.

Comment by aldenquimby [ 06/May/14 ]

@jitterted i was able to get things working by following this HK2 comment. It's not great, but should work until the Jersey guys finally get around to tackling this issue

Comment by sugis [ 06/May/14 ]

I too, after many happy years of Jersey use, had to switch to RESTeasy over this issue

Comment by natros [ 06/May/14 ]

I start to feel you pain over this issue. I have a large code base that dependes on jersey 1.x and can't simple switch to Resteasy.

Comment by jkidd [ 16/Dec/14 ]

@cowwoc +1
As long as the support for Guice in Jersey 2.x is so cumbersome, I myself will not be willing to switch to Jersey 2. Using/handling one DI framework is enough, using two DI frameworks is pointing towards spaghetti.

Comment by vshankri [ 16/Jul/15 ]

We wanted to use "asycn servlet" so want to upgrade to Jersey 2.x but this is such a huge draw back that GUICE is not supported. Currently we use GUICE and JERSEY 1.x; so it has been really tough so far. I hope Jersey starts supporting GUICE

Comment by gmussi [ 20/Aug/15 ]

Hello,

Why is Jersey so dependent of HK2? Shouldnt DI and Rest be two different things? Do I miss something here?
I use jersey 1.x and Guice heavily accross my applications, and would like to switch to 2.x, but like this, it is impossible at the moment.

My vote is for an official and well-maintained Guice support, as in the previous version

Comment by superbull [ 19/Jan/16 ]

Hello,
Is there any one in the jersey team care about this issue?
It seems it is the most voted issue.

Comment by Marek Potociar [ 19/Jan/16 ]

Guice support is not the priority for the core Jersey team at the moment.

I can see two options how to get this feature in:
1. Get Guice owners to contribute a support module
2. Community contribution. Jersey is an open-source project and since the issue has 52 votes, chances are that there is someone out there in the community who cares enough about this feature to implement it and contribute it back to the project as a Jersey extension pull request.

Comment by cowwoc [ 19/Jan/16 ]

Marek,

This issue cannot be solved without design-level changes in Jersey. Even if someone from the community were to contribute such a pull request, you wouldn't accept it (you implied as much in past mailing list discussion). There is no magical way to provide a Guice implementation that is completely abstracted away by HK2 without Jersey needing to be aware of it (the HK2 and Guice designs do not match and it causes the problems mentioned above). I already tried and gave up for this reason.

Comment by sugis [ 19/Jan/16 ]

As a long-time voter on this issue, we also tried to contribute a fix to this issue. We used Jersey 1 + Guice with great success, but wanted JAX-RS 2.0. We ran into the same issues cowwoc mentioned (complex implementation, unclear path to contributing such a complex change upstream) and eventually decided that migrating to RESTEasy was a simpler task than fixing Jersey, and that is what we ended up doing. We were sad to leave as Jersey had served us well, but were really forced to because of this issue.

Comment by husayt [ 19/Jan/16 ]

I remember that excitement. How much did we expect Jersey 2. We were so excited. but there was this nasty surprise when we tried to migrate over.

I can argue, that with HK2 it is not Jersey anymore. This is a different product, and it is altogether misleading to call it Jersey 2. It would better be called HKersey.

Marek, you need to admit to us and to yourself Jersey is dead, so that we can move one and you can continue developing HKersey.

It is easier to migrate from Jersey to RestEasy than to HKersey.

I am not being sarcastic, but your two points above are offensive to all the people on this thread.

Lot's of people tried to find a way to integrate Guice with HKersey, and all failed due to tight coupling of HK2. So rather than admitting, that the way HK2 was built into Jersey was shambles you are coming with inadequate excuses.

I don't even mention you suggesting Guice owners to contribute. Come on... Really, so it's Guice is guilty now.
BTw, Is there any other DI framework HKersey can work with? Maybe Dagger or Spring?

Comment by jwells [ 20/Jan/16 ]

I guess I'm not fully understanding what exactly does not work. Many people have used the guice/jersey bridge to interoperate as much as guice will allow. One good example is here:

http://stackoverflow.com/questions/32449706/guice-jersey-integration-injects-null-objects/32458999#32458999

Perhaps this is just a documentation issue? If there are specific features that do not work they should probably be broken out into separate bugs.

Comment by sugis [ 20/Jan/16 ]

It's hard to pin down exactly which things are broken, because of the futility of the task.

Say you were trying to port a small application from a Jersey 1.x+Guice codebase to Jersey2.x+Guice – the very first thing you'll find, a number of previously working constructor injections fail:
https://java.net/jira/browse/HK2-139

Fails because HK2 and Guice don't have exactly the same bindings. (In fact, Guice expects the set of bindings to be immutable, whereas HK2 changes it dynamically.)

Opened in 2013. Blocked on a Guice RFE, no real hope of getting the Guice team to change this, and even if they do it wouldn't be in a release until who-knows-when. Guice is infamously slow to evolve, or even release desperately-needed bugfix versions.

Even if it does get fixed – you're still in the bizarre position of running two competing DI frameworks. There's going to be more problems. It's bizarre to me that Jersey even depends on HK2 so strongly.

The whole point of JSR330 is to be DI-framework independent until the end consumer selects a product to use. But instead Jersey integrates HK2 to tightly that we suddenly can't use our existing Guice-based code – which we have a lot of time invested in and expertise with – we must instead start looking at replacing Guice, or fixing the subtly-broken bridge.

Another option, that I (and sounds like cowwoc) personally think is better, would be if Jersey was separated from HK2 somewhat and could run inside of Guice. The OSGI features and whatnot that require dynamism are great, but a lot of people (very intentionally) don't run e.g. OSGI and prefer immutable service configurations. But making that separation is a lot of work, and we have day-jobs...

RESTEasy offered us a path out, and we took it. I remember after spending a number of hours on this, I started to wonder how easy switching was. Turned out to be a relatively easy upgrade path. So we switched and stopped looking. Sounds like cowwoc did too (by moving to Pouch instead of Guice).

Just reading through the tickets there's a ton of specialized Guice and HK2 knowledge both required to tackle the problem, so the number of people who could possibly contribute it is very small. Any work I did at least is now somewhere on the dusty shelf.

Anyway sorry for the long-winded comment, was just hoping to better explain how I saw the situation.

Comment by jwells [ 20/Jan/16 ]

So JSR-330 did not achieve any sort of interoperability except for a very limited set of use cases. Very limited. I'm told this was because of bickering between the various DI players (Spring, Guice, JBoss, etc).

Because of the essential failure of JSR-330 to be comprehensive enough to support any complex use cases JSR-299 (CDI) was created. It is a lot better and a lot more complete but has other issues such as only truly working in a container environment (which is being fixed). A lot (but certainly not all) of hk2 is based on the CDI model.

So I would say that the whole point of JSR-330 was not really to allow for DI framework independence, or if it was, that it failed at that. The only purpose JSR-330 serves now is to provide a few (a very few!) common annotations and API that other specs can use (such as CDI).

Comment by cowwoc [ 20/Jan/16 ]

sugis summarized my position quite well.

I have a lot of respect for jwells and his work, but there is absolutely no technical way to get Jersey's current design to integrate perfectly against any other engine but HK2, and that is simply not okay.

There is no technical reason for Jersey to bind itself so tightly against HK2. The arrangement we had in Jersey1 worked perfectly well. We aren't asking Oracle to support multiple DI engines. We are asking for Jersey to operate against an interface and allow the community to contribute different implementations of that interface.

Final point: it is unreasonable for you to expect other DI engines (such as Guice) to add features whose main purpose is to help users to migrate away (use other engines). No one in their right mind would waste their time implementing this... Every DI engine I have ever encountered operates under two basic assumptions:

1. It is the only DI engine being used.
2. The DI engine injects values into the application (Jersey), not the other way around.

Jersey's design needs to internalize these points and provide a solution that works accordingly.





[JERSEY-1982] @PreDestroy not invoked on root resource Created: 20/Jul/13  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.0
Fix Version/s: None

Type: Bug Priority: Major
Reporter: spamdaemon Assignee: petrjanouch
Resolution: Unresolved Votes: 2
Labels: evaluation-needed
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

It seems that Jersey 2 no longer invokes @PreDestroy on a root resource when used with the JDK's bundled http server (JdkHttpServerFactory). @PostConstruct is properly as expected.

This was working as expected in Jersey 1.x. Is this no longer the case? Is there a work-around?



 Comments   
Comment by spamdaemon [ 20/Jul/13 ]

I don't know how to attach anything here. So I'll just cut and paste a little example:

import java.net.HttpURLConnection;
import java.net.URI;
import java.util.concurrent.atomic.AtomicInteger;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

import org.glassfish.jersey.jdkhttp.JdkHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;

import com.sun.net.httpserver.HttpServer;

public class SimpleServer {

	private static AtomicInteger COUNTER = new AtomicInteger(0);

	@Path("/")
	public static class Endpoint {

		@GET
		public String get() {
			return "Hello, World";
		}

		@PreDestroy
		public void preDestroy() {
			System.err.println("preDestroy");
			COUNTER.decrementAndGet();
		}

		@PostConstruct
		public void postConstruct() {
			COUNTER.incrementAndGet();
			System.err.println("postConstruct");
		}

	};

	public static void main(String[] argv) throws Exception {
		String uri = "http://localhost:8080/";
		ResourceConfig config = new ResourceConfig(Endpoint.class);

		HttpServer server = JdkHttpServerFactory.createHttpServer(
				URI.create(uri), config);

		for (int i = 0; i < 3; ++i) {
			HttpURLConnection con = (HttpURLConnection) URI.create(uri).toURL()
					.openConnection();
			System.err.println("ResponseCode : " + con.getResponseCode());
			con.disconnect();
		}
		server.stop(1);
		System.err.println("COUNTER :" + COUNTER.get());
		System.exit(COUNTER.get());
	}
}
Comment by spamdaemon [ 27/Aug/13 ]

Doesn't work with 2.2 either.

Comment by spamdaemon [ 04/Sep/13 ]

I tried this now with grizzly, but still no luck. Is there something else I need to do to get this to work in an embedded server??

Comment by spamdaemon [ 04/Sep/13 ]

I've finally worked around this using a WriterInterceptor. I made my root resources Closeable and simple close them in after the request has been written.
This seems to work fine for now.

Comment by spamdaemon [ 05/Sep/13 ]

So, the interceptor didn't work either,because it's not invoked when there is no content to be written.

After seriously searching I've realized this can no longer be done without relying on Jersey. The way to do this seems to be as described here: http://comments.gmane.org/gmane.comp.java.jersey.user/3087

Comment by Miroslav Fuksa [ 25/Oct/13 ]

Jersey 2 does not call @PreDestroy nor @PostConstruct for standard resources. These methods are called for CDI beans and for Application class.

Check the org.glassfish.jersey.server.CloseableService. You can inject it to your resource method, resource or provider using @Context annotation and then register your Closeable (using add() method) which will be called when request is finished.

Comment by spamdaemon [ 25/Oct/13 ]

Actually, it does call @PostConstruct (at least at the time of writing this issue) which I think should have been paired with a @PreDestroy.

At any rate, I did indeed go the route with the cleanup handler.

Comment by Miroslav Fuksa [ 29/Oct/13 ]

You are right. For standard JAX-RS resources PostConstruct is called but not PreDestroy. This should be fixed and PreDestroy methods should also be called.

Note: when implementing please make sure to handle correctly singleton and request scopes.

Comment by Stephan202 [ 31/Dec/13 ]

To be clear: this affects not just resources, but other JAX-RS @Providers (such as ContainerResponseFilter implementations) as well. (I.e., @PostConstruct is called, but @PreDestroy isn't.)

Comment by Stephan202 [ 15/Sep/14 ]

This issue was mostly resolved by JERSEY-2574, but not completely: Feature instances are still "left out".

Tangentially related is the fact that the jersey-test-framework-provider-inmemory doesn't support @PreDestroy at all (while the Jetty and Grizzly providers do). Not a deal breaker, but unfortunate.





[JERSEY-1999] Consider choosing the response media type of matched resource method for BV error response entity. Created: 02/Aug/13  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: extensions
Affects Version/s: 2.1
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Michal Gajdos Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Consider the following resource method:

@Produces(MediaType.APPLICATION_XML)
public MyResult placeOrder(@Valid final Order order) {
    // ...
}

and a request that matches this method. If the Accept header of the method looks like text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 then the content type of the (BV error) entity in response would be text/html.






[JERSEY-2118] Jersey should specify what constitutes a "suitable constructor" Created: 27/Sep/13  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.2
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: cowwoc Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Jersey throws the following exception:

java.lang.NoSuchMethodException: Could not find a suitable constructor in com.mycompany.jersey2guice.JerseyApplication class.
	at org.glassfish.jersey.internal.inject.JerseyClassAnalyzer.getConstructor(JerseyClassAnalyzer.java:189)
[...]

Expected behavior: explain what constitutes a "suitable constructor" in the exception message so developers know what needs to get fixed. Either link to a more detailed explanation or describe it inline.

Also, it would be useful if you provided more contextual information, such as "Found constructors X, Y, Z. Was looking for A, B or C"



 Comments   
Comment by cowwoc [ 26/Oct/13 ]

Two comments:

  1. It looks like the error messages are coming from hk2 so you might have to redirect this bug report there.
  2. Please pay special attention to constructors annotated with @Inject. It is a common mistake to import com.google.Inject instead of javax.inject.Inject. Currently, org.jvnet.hk2.internal.Utilities.hasInjectAnnotation() checks for javax.inject.Inject and throws an error if two constructors are annotated with @Inject. I suggest throwing an error if a constructor is annotated with @Inject that does not resolve to javax.inject.Inject in order to help users catch errors. As far as I know, each class only uses one type of @Inject at a time so we are unlikely to run into false positives.
Comment by sinzone [ 22/Mar/14 ]

+1. What is a suitable constructor?

In my case the constructor in my resource/controller required some arguments, I removed them and now everything works. I guess Jersey's reflection can't initialize the class if there are some arguments, because obviously it doesn't know what to put there. This wasn't clear at a first look.

Comment by minfrin [ 25/Aug/14 ]

This just bit me as well, +1 on a proper error message with no weasel words.





[JERSEY-2139] The org.glassfish.jersey.apache.connector.ApacheConnector cannot be fully configured (e.g., retry handler) because the HttpClient is not accessible. Created: 11/Oct/13  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: connectors
Affects Version/s: 2.3.1, 2.4
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: seanl Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Dependency
depends on JERSEY-2229 Upgrade ApacheConnector to use Apache... Closed
Related
is related to JERSEY-2835 Add new ApacheClientProperties.DISABL... Open

 Description   

The ApacheConnector API has a design omission in that it does not allow the user to create and provide a configured HttpClient. In Jersey 1.7.x we were able to create an HttpClient, assign a retry handler directly, and provide the HttpClient to the Jersey client to use.

In Jersey 2.3.1, the ApacheConnector creates the HttpClient (a deprecated version of it) that the user cannot modify. The user can retrieve said client, but the HttpClient interface does not expose a configure it, it's essentially immutable. To make matters worse, this version of Jersey depends on httpclient 4.2.5 rather than 4.3. There have been many important changes and deprecations in 4.3 which impact the ApacheConnector design.

A good fix would be to provide an additional constructor ApacheConnector(HttpClient httpclient, Configuration config). I would also strongly recommend upgrading to depend on httpclient 4.3, removing deprecations, and refactoring as necessary.



 Comments   
Comment by seanl [ 22/Oct/13 ]

I am confused about the downgrading of priority and the change from Bug to Improvement. According to Jira:
Bug: A problem which impairs or prevents the functions of the product.
Improvement: An improvement or enhancement to an existing feature or task.
Major: Major loss of function.
Minor: Minor loss of function, or other problem where easy workaround is present.

Using the retry capability of HttpClient is a core capability for building more reliable systems. We use it extensively in our infrastructure. This capability was available in Jersey 1.7 so arguably this is a regression.

By downgrading it, are you saying there is an easy workaround?

Comment by Michal Gajdos [ 23/Oct/13 ]

Fair point about the priority, changing back to Major, but the task as a whole seems to me more like an Improvement (and by this I don't mean to make this issue any less important).

Comment by seanl [ 23/Oct/13 ]

Thanks gentlemen!

Comment by seanl [ 04/Dec/13 ]

Team, I see this issue is in the backlog. Would it expedite if I contributed a solution? I don't want to duplicate work if it is already occurring. If contributing is ok, should I rewrite ApacheConnector using HttpClient 4.3 instead of 4.2.5?

Comment by Michal Gajdos [ 04/Dec/13 ]

Let me get back to you tomorrow regarding this issue. I am currently working on JERSEY-2123 how big changes I am going to make, I should be smarter tomorrow.

Comment by Michal Gajdos [ 06/Dec/13 ]

We're currently reviewing patch that'll bring HttpClient 4.3 into Jersey. Anyways the connector mechanism will go through some changes so even though nobody is working on this issue right now so, please, wait until situation is more stable (we'll be working on connectors probably in 2.6).

Comment by seanl [ 06/Dec/13 ]

Thanks for the update Michal.

Comment by saacharya [ 15/Jul/15 ]

What's the status of this issue? Thanks.





[JERSEY-2239] Unable to parse "If-None-Match" header value Created: 21/Nov/13  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.4.1
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: lucianb Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Windows 7 Ultimate Service Pack 1 64bit


Tags: etag

 Description   

If If-None-Match Header Etag content is sent without the quotes like c27b74582676d4cca1e35d3fd2171d5b , the request fail
If the content is sent with quotes like "c27b74582676d4cca1e35d3fd2171d5b" everything goes well.

The exception thrown:

Nov 21, 2013 8:10:03 PM org.glassfish.jersey.server.ServerRuntime$Responder mapException
WARNING: WebApplicationException cause:
org.glassfish.jersey.message.internal.HeaderValueException: Unable to parse "If-None-Match" header value: "c27b74582676d4cca1e35d3fd2171d5b"
	at org.glassfish.jersey.message.internal.InboundMessageContext.exception(InboundMessageContext.java:335)
	at org.glassfish.jersey.message.internal.InboundMessageContext.getIfNoneMatch(InboundMessageContext.java:396)
	at org.glassfish.jersey.server.ContainerRequest.evaluateIfNoneMatch(ContainerRequest.java:713)
	at org.glassfish.jersey.server.ContainerRequest.evaluatePreconditions(ContainerRequest.java:615)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at com.zeroturnaround.javarebel.BZ.invoke(JRebel:1062)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:151)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:171)
	at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:152)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:367)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:349)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:106)
	at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:259)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
	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.process(Errors.java:267)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:318)
	at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:236)
	at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:983)
	at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:361)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:372)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:335)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:218)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
	at org.apache.catalina.core.StandardContextValve.__invoke(StandardContextValve.java:123)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
	at org.apache.catalina.core.StandardHostValve.__invoke(StandardHostValve.java:171)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1686)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.text.ParseException: Error parsing entity tag
	at org.glassfish.jersey.message.internal.MatchingEntityTag.valueOf(MatchingEntityTag.java:86)
	at org.glassfish.jersey.message.internal.HttpHeaderReader$1.create(HttpHeaderReader.java:298)
	at org.glassfish.jersey.message.internal.HttpHeaderReader$1.create(HttpHeaderReader.java:294)
	at org.glassfish.jersey.message.internal.HttpHeaderReader.readMatchingEntityTag(HttpHeaderReader.java:311)
	at org.glassfish.jersey.message.internal.InboundMessageContext.getIfNoneMatch(InboundMessageContext.java:394)


 Comments   
Comment by Michal Gajdos [ 25/Nov/13 ]

This behaviour is compliant with HTTP 1.1 spec (see [1]):

Entity tags are used for comparing two or more entities from the same requested resource. HTTP/1.1 uses entity tags in the ETag (section 14.19), If-Match (section 14.24), If-None-Match (section 14.26), and If-Range (section 14.27) header fields. The definition of how they are used and compared as cache validators is in section 13.3.3. An entity tag consists of an opaque quoted string, possibly prefixed by a weakness indicator.

 entity-tag = [ weak ] opaque-tag
 weak       = "W/"
 opaque-tag = quoted-string

A "strong entity tag" MAY be shared by two entities of a resource only if they are equivalent by octet equality.

A "weak entity tag," indicated by the "W/" prefix, MAY be shared by two entities of a resource only if the entities are equivalent and could be substituted for each other with no significant change in semantics. A weak entity tag can only be used for weak comparison.

An entity tag MUST be unique across all versions of all entities associated with a particular resource. A given entity tag value MAY be used for entities obtained by requests on different URIs. The use of the same entity tag value in conjunction with entities obtained by requests on different URIs does not imply the equivalence of those entities.

[1] http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.11

Comment by Michal Gajdos [ 25/Nov/13 ]

Moving to backlog and changing to improvement to see whether we could do something to make this more convenient.

Comment by runarb [ 28/Feb/14 ]

I think that we should expect a 400 Bad Request in this case.
The HeaderValueException could be caught in

ContainerRequest.evaluateIfNoneMatch(EntityTag eTag)

and a ResponseBuilder of 400 should be returned.

It feels wrong having to deal with this exception when "trusting" evaluateIfNoneMatch(..) to take care of handling the entity tag.

What do you think?

Comment by avsokolov [ 24/Aug/15 ]

I always get Bad Request, here is example of code:

    @GET
    public Response getTemplate4CustomSkin(@Context final Request request)
    {
        EntityTag eTag = new EntityTag("123456789");
        Response.ResponseBuilder responseBuilder = request.evaluatePreconditions(eTag);
        if (responseBuilder == null)
        {
            System.out.printf("is null");
        }
        else
        {
            System.out.printf("is not null");
        }
        return Response.ok(data.inputStream, data.mimeType).tag(eTag).build();
    }
 }

    @Test
    public void testGetFileEtagIsNotChanged() throws UnsupportedEncodingException
    {
        Client client = ClientBuilder.newClient();
        WebTarget target = client.target("someUrl");
        EntityTag eTag = new EntityTag("123456789");
        Response response = target.request().get();
        //send request 2nd time with 
        response = target.request().header("If-None-Match", response.getEntityTag()).get();
        //same result 
        //response = target.request().header("If-None-Match", response.getEntityTag().getValue()).get();
        Assert.assertEquals(eTag, response.getEntityTag());
    }

// the following code always throws an exception inside of org.glassfish.jersey.message.internal.HttpHeaderReaderImpl.java class:
    private char getNextCharacter(boolean skipWhiteSpace) throws ParseException {
        ....
        // this line of code always throws it:
        if(this.index >= this.length) {
            throw new ParseException(LocalizationMessages.HTTP_HEADER_END_OF_HEADER(), this.index);
        } else {
            return this.header.charAt(this.index);
        }
    }

I run tests via arquillian, dependency versions:

        <!--Arquillian JUnit integration: -->
        <dependency>
            <groupId>org.jboss.arquillian.junit</groupId>
            <artifactId>arquillian-junit-container</artifactId>
            <version>1.1.8.Final</version>
            <scope>test</scope>
        </dependency>
        <!--glassfish-embedded:-->
        <dependency>
            <groupId>org.glassfish.main.extras</groupId>
            <artifactId>glassfish-embedded-all</artifactId>
            <version>4.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jboss.arquillian.container</groupId>
            <artifactId>arquillian-glassfish-embedded-3.1</artifactId>
            <version>1.0.0.CR4</version>
            <scope>test</scope>
        </dependency>

How can I resolve it? How can I send a request with "If-None-Match" header inlcuded and don't get an exception?





[JERSEY-2291] Support @Immediate services by default Created: 21/Dec/13  Updated: 08/Dec/15

Status: Reopened
Project: jersey
Component/s: core
Affects Version/s: 2.5.1
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: jwells Assignee: Unassigned
Resolution: Unresolved Votes: 5
Labels: None
Remaining Estimate: 2 days
Time Spent: 1 hour
Original Estimate: 1 hour

Issue Links:
Related
is related to JERSEY-2979 ImmediateThread memory leak Resolved

 Description   

HK2 has added a new feature called @Immediate services. These are services that are started as soon as they are bound into the system. It would be nice for Jersey to support this scope/context pair by default out of the box. This would be very similar to the PerThread scope/context pair that Jersey already supports out of the box.

Here is a request from the community to support this feature:

http://stackoverflow.com/questions/20713086/what-corresponds-to-aseagersingleton-in-hk2-in-jersey-2/20721765#20721765



 Comments   
Comment by Adam Lindenthal [ 07/Sep/15 ]

https://github.com/jersey/jersey/pull/173

Comment by Adam Lindenthal [ 18/Sep/15 ]

Merged, thanks for contributing!

Comment by Adam Lindenthal [ 18/Sep/15 ]

That was actually meant for Jord - the author of the pull request on github. To you, John, thanks for reporting !

Comment by Stepan Vavra [ 06/Oct/15 ]

We had to disable Immedate Scope HK2 feature due to several issues with ImmediateThreads (tracked as HK2-280). As a result, @Immediate services do not work by default anymore.

Comment by Stepan Vavra [ 16/Nov/15 ]

I just wanted to give it a quick shoot but without a success. With 2.4.0-b33, the problem still remains. Threads are left behind on application undeploy, and also jersey-client creation implies new thread for immediate services. I'm not saying though it won't be possible to do fine tuning and make it work in jersey by default. It will require more time than just an hour...





[JERSEY-2324] Asynchronous ContainerRequestFilter using ManagedAsync Created: 11/Jan/14  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: aldenquimby Assignee: Unassigned
Resolution: Unresolved Votes: 3
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: async, filter

 Description   

A ContainerRequestFilter cannot be executed asynchronously.

A very common use case for this filter would be an authorization check, but if that check goes to an external service or to a database, benefits from @ManagedAsync are lost because only resource methods are invoked asynchronously.

This is very tricky because a PreMatching filter could change the request from a @ManagedAsync resource method to a non-async method, or visa-versa. Maybe any filters that are not PreMatching should be offloaded to the ExecutorService if the matching resource method has @ManagedAsync? Or maybe an entirely new type of filter should be introduced for this case, one that's basically an HK2 AOP MethodInterceptor?



 Comments   
Comment by aldenquimby [ 11/Jan/14 ]

StackOverflow question about this: http://stackoverflow.com/q/20556200/1415732

Comment by aldenquimby [ 19/Jan/14 ]

I've tried a lot of things to get around this problem, and found one really hacky solution.

Guice AOP - failed
Though I got Guice injection working with Jersey 2.5 (a feat in itself!), I could not get Guice to create the resource classes, so AOP does not work on resource methods. This is a well known problem.

HK2 AOP - failed
HK2 just recently released this feature, and it appears Jersey does not support this yet because I could not get it working. I'm waiting on an answer to this stackoverflow comment before pursuing this farther.

Monitoring - worked
Registering an ApplicationEventListener that calls my authorization service on RequestEvent RESOURCE_METHOD_START appears to work. This event is triggered by the ManagedAsync thread, which is what I need. Though this works, it is clearly unsafe, as the Jersey docs say to only use event listening for monitoring, and not any actual work.

Comment by aldenquimby [ 09/Mar/14 ]

UPDATE

I got this working with HK2's AOP. You can see roughly what I did here: http://stackoverflow.com/q/22275562/1415732.

I've since expanded my solution, and added a registerAsyncFilter to my implementation of ResourceConfig. This registers the filter with my bound HK2 InterceptionService, which runs the filter as a MethodInterceptor right before the method is invoked. Unlike normal ContainerRequestFilter's, these are now run on the @ManagedAsync thread created by Jersey, which is exactly what I need.

I would be happy to share more of my solution if anyone else is struggling with a ContainerRequestFilter and @ManagedAsync.





[JERSEY-2405] Add support for Spring Framework 4 and newer Created: 13/Feb/14  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: extensions
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Vetle Leinonen-Roeim Assignee: Unassigned
Resolution: Unresolved Votes: 3
Labels: spring
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: spring

 Description   

org.glassfish.jersey.ext:jersey-spring3 should be updated to use Spring 4 (or org.glassfish.jersey.ext:jersey-spring4 should be introduced), and the Spring examples should be updated.



 Comments   
Comment by herau [ 01/Aug/14 ]

any news about Spring 4 integration ?

Comment by Vetle Leinonen-Roeim [ 01/Aug/14 ]

We use Jersey2 with Spring 4, and it works great. Not sure if any action here is needed, really.

Comment by Michael Osipov [ 01/Aug/14 ]

There is nothing particular about Spring 4. Swap the JARs and your are done. I have patched Jersey, available on Github.

Comment by herau [ 15/Aug/14 ]

What are the maven artifacts if for The version 2 of jersey ? Did i still must exclude sping library as i currently done with The 1.18 version ?

Comment by Michael Osipov [ 16/Aug/14 ]

herau, wrong place to ask. Read the manual or go to the mailing list.

Comment by gciuloaica [ 31/Aug/15 ]

Hi,

I have added a pr, introducing org.glassfish.jersey.ext:jersey-spring4. The code is identical with the one in spring3 module. I did not found any issues so far.

https://github.com/jersey/jersey/pull/192

Comment by Michael Osipov [ 01/Sep/15 ]

I see no reason to duplicate the code. The module should be renamed to spring only and depend on 4.x by the end of the year.

Comment by gciuloaica [ 01/Sep/15 ]

end of the year, seems to wait a long time to get it. Until than all the iterations of jersey will fetch both 3.x and 4.x dependencies. For one of my clients I have build a framework that integrates jersey with netty, and spring4. My client want to release this month so I will have to maintain/release a custom version of jersey. Code duplication is a problem on long term but if you keep it for few months, removing one copy it should not be a problem. Or maybe to release spring ext with 4.x dependency earlier?

Comment by Vetle Leinonen-Roeim [ 01/Sep/15 ]

You don't need to wait, the spring3 module works fine with Spring 4 - at least it did when I used it until late last year.

Comment by gciuloaica [ 01/Sep/15 ]

excluding the dependencies and replacing them with spring 4.x ones, works just fine. I have closed the PR as unnecessary.





[JERSEY-2428] SslContext and HostVerifier not passed on nonPreemptive auth Created: 28/Feb/14  Updated: 25/Jan/16

Status: In Progress
Project: jersey
Component/s: core
Affects Version/s: 2.6
Fix Version/s: None

Type: Bug Priority: Major
Reporter: rickyepoderi Assignee: petrjanouch
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

OS:
Linux 3.12-1-amd64 #1 SMP Debian 3.12.9-1 (2014-02-01) x86_64 GNU/Linux

JAVA:
java version "1.7.0_25"
OpenJDK Runtime Environment (IcedTea 2.3.10) (7u25-2.3.10-1~deb7u1)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)



 Description   

The SslContext and the HostVerifier are not passed when the WS is using a BASIC authentication and nonPreemptive is used. The request is repeated (with authorization header) but both settings are not passed, so the second attempt with BASIC header can fail because security reasons (SSL certs or hostname verification).

This is a sample code for testing:

    static public void main(String[] args) throws Exception {
        ClientBuilder clientBuilder = ClientBuilder.newBuilder();
        SSLContext sc = SSLContext.getInstance("SSL");
        TrustManager[] trustAllCerts = {new InsecureTrustManager()};
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HostnameVerifier allHostsValid = new InsecureHostnameVerifier();
        Client client = clientBuilder.sslContext(sc).hostnameVerifier(allHostsValid).build();
        client.register(HttpAuthenticationFeature.basicBuilder()
                // comment this line or not to checl the bug
                .nonPreemptive()
                .credentials("ricky", "Kiosko_00").build());
        Response response = client.target("https://localhost:8181/jaxrs-sample")
                .path("webresources")
                .path("hellows")
                .path("sayhello")
                .queryParam("name", "ricky")
                .request()
                .get();
        if (response.getStatusInfo().getFamily().equals(Response.Status.Family.SUCCESSFUL)) {
            System.out.println(response.readEntity(String.class));
        } else {
            throw new Exception(String.format("HTTP error (%d): %s", response.getStatus(), 
                    response.getStatusInfo().getReasonPhrase()));
        }
    }

I have check the code of version 2.6 and the issue is quite issue to fix. Here it is a tentative patch:

*** ./org/glassfish/jersey/client/authentication/HttpAuthenticationFilter.java.ORIG	2014-02-28 10:48:41.678462757 +0100
--- ./org/glassfish/jersey/client/authentication/HttpAuthenticationFilter.java	2014-02-28 10:48:13.322008734 +0100
*************** class HttpAuthenticationFilter implement
*** 296,302 ****
       *
       */
      static boolean repeatRequest(ClientRequestContext request, ClientResponseContext response, String newAuthorizationHeader) {
!         Client client = ClientBuilder.newClient(request.getConfiguration());
          String method = request.getMethod();
          MediaType mediaType = request.getMediaType();
          URI lUri = request.getUri();
--- 296,306 ----
       *
       */
      static boolean repeatRequest(ClientRequestContext request, ClientResponseContext response, String newAuthorizationHeader) {
!         Client client = ClientBuilder.newBuilder()
!             .hostnameVerifier(request.getClient().getHostnameVerifier())
!             .sslContext(request.getClient().getSslContext())
!             .withConfig(request.getConfiguration())
!             .build();
          String method = request.getMethod();
          MediaType mediaType = request.getMediaType();
          URI lUri = request.getUri();

As you see the repeatRequest method now uses SslContext, HostnameVerifier and the configuration of the original request. With this patch my simple testcase works no matter it is preemptive or not.



 Comments   
Comment by Miroslav Fuksa [ 04/Mar/14 ]

Hi,

thanks for the bug report and for the patch proposal. I am moving the issue to the backlog.

Mira

Comment by mirko.beine@arsinventionis.de [ 04/Feb/15 ]

This also applies to digest auth, obviously. If I'd create a PR, is there any chance this fix would make it into the next release?





[JERSEY-2431] "21.1. Implementing Custom Injection Provider" Instructions Can Lead to PermGen Error Created: 03/Mar/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: docs
Affects Version/s: 2.6
Fix Version/s: None

Type: Bug Priority: Major
Reporter: saden Assignee: Adam Lindenthal
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

JDK 7, Linux 32bit


Sprint: Triaged

 Description   

Section 21.1 of the documentation may have been intended to be generic instructions on how to create custom injection, unfortunately HttpSession use-case could lead to PermGen error. If the current instructions are followed injection of HttpSession result in the creation of a new proxy class every time. This can lead to PermGen error unless jvm class unloading is enabled (UseConcMarkSweepGC/CMSClassUnloadingEnabled jvm args). While this may seem reasonable a better solution is to proxy the HttpSession object and create it in the RequestScope.

Change the documentation from this:

import org.glassfish.hk2.utilities.binding.AbstractBinder;
...
 
public class MyApplication extends ResourceConfig {
 
    public MyApplication() {
 
        ...
 
        register(new AbstractBinder() {
            @Override
            protected void configure() {
                bindFactory(HttpSessionFactory.class).to(HttpSession.class);
            }
        });
    }
}

to this:

import org.glassfish.hk2.utilities.binding.AbstractBinder;
...
 
public class MyApplication extends ResourceConfig {
 
    public MyApplication() {
 
        ...
 
        register(new AbstractBinder() {
            @Override
            protected void configure() {
                bindFactory(HttpSessionFactory.class).to(HttpSession.class)
                     .proxy(true).proxyForSameScope(false).in(RequestScoped.class);
            }
        });
    }
}

Note that WebComponentBinder class does the above for various request scoped objects (i.e. HttpServletRequest).



 Comments   
Comment by saden [ 03/Mar/14 ]

Perhaps the section can be split into two sections:
a) Custom RequestScoped Injection Provider
b) Custom HK2 Injection Provider.

Comment by Michal Gajdos [ 04/Mar/14 ]

Moving to backlog. Note: should be considered for the next release.





[JERSEY-2437] Priority for ExceptionMappers are not used Created: 07/Mar/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core, extensions
Affects Version/s: 2.6
Fix Version/s: None

Type: Bug Priority: Major
Reporter: lillesand Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: exception, exceptionshandl, mvc

 Description   

The ExceptionMapperFactory does not consider priorities for different registered ExceptionMappers. This means that if you have two registered ExceptionMappers for the same Exception, which one is used will be random.

This is made worse by the fact that MvcFeature registers it's own ExceptionMapper for Exception. So, if you use MvcFeature and want to register your own ExceptionMapper for Exception, you might end up using ErrorTemplateExceptionMapper, and you might end up using your own.



 Comments   
Comment by lillesand [ 07/Mar/14 ]

Sorry, accidentally submitted the issue before I was done writing it up. Let me know if there are any details that are missing or wrong.

Comment by tomasz.kalkosinski [ 21/Dec/15 ]

It's still an issue in 2.22.1. This bug is related to JERSEY-2722.





[JERSEY-2444] X-Forwarded-* aware UriInfo.getBaseBuilder Created: 11/Mar/14  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.7
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Vetle Leinonen-Roeim Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

As far as I can see, UriInfo.getBaseBuilder() does not return a builder that is aware of headers like X-Forwarded-For or X-Forwarded-Proto.
It would be great to be able to control this. It seems that the UriBuilder is created is container-specific - for instance, here it is created in a servlet context: https://github.com/jersey/jersey/blob/master/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/ServletContainer.java#L518 The headers are still the same in any context, though.

The benefit here is that this will prevent developers from having to manually handle this in their resources, making both developing and deploying Jersey applications easier.






[JERSEY-2451] Ability to run as Filter that ignores unhandled requests Created: 16/Mar/14  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.7
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: cowwoc Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Please add a new feature alongside FEATURE_FILTER_FORWARD_ON_404 that would behave as follows:

When Jersey is configured to run as a filter, it should not modify the ServletResponse unless the request matches a registered resource class/method. If a match occurs, the ServletResponse should contain what the class/method returned, but otherwise the ServletResponse should get passed (unmodified) to the next filter in the chain.

This differs from FEATURE_FILTER_FORWARD_ON_404/FILTER_FORWARD_ON_404 in that the latter:

  1. Passes control to the next filter in the chain if a registered resource returns 404
  2. Modifies the response code before passing ServletResponse to the next filter in the chain

The proposed feature would not do any of this.

I can't use PROPERTY_WEB_PAGE_CONTENT_REGEX/FILTER_STATIC_CONTENT_REGEX because I don't know ahead of time what URL will match subsequent filter(s). I wish to map all filters to the same context path and have them delegate to the next filter if they can't handle the request themselves.

Please add this feature to both Jersey 1 and 2. I can file a duplicate feature request for separate versions if you wish.



 Comments   
Comment by cowwoc [ 24/Apr/14 ]

Just to be 100% clear: I am expecting you to figure out whether the requested URI was dispatched to a resource method, which is not the same as checking for a 404 response because it's possible for a resource method to get invoked but subsequently return 404. In the latter case, FILTER_FORWARD_ON_404 would forward on the request but this new feature would not.





[JERSEY-2453] Jersey support for OAuth2.0 server-side provider Created: 18/Mar/14  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: security
Affects Version/s: 2.7
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: icode Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I need OAuth 2.0 provider . please!



 Comments   
Comment by Marek Potociar [ 26/Mar/14 ]

Moving to backlog.





[JERSEY-2467] ResourceModel not complete for sub resources Created: 01/Apr/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.6
Fix Version/s: None

Type: Bug Priority: Major
Reporter: gdavison Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Linux, JDK 7


Attachments: Zip Archive SubResourceModelMoreSpecific.zip    

 Description   

So I am trying to vist the model provided by ExtendedResourceConfig; but I am finding that the information for sub resources is missing. The example attached to this issue is suppose to create a map of Resource class to path to aid the delcarative linking code; but it only iterates down one level.

This means that the output of the code is:

GET ..../root
class project1.SubResource : /root/

{sub}

rather than the expected

GET ..../root
class project1.SubResource : /root/{sub}

class project1.SubSubResource : /root/

{sub}

/

{subsub}

Note that the single resource method for the GET operation is also missing from the SubResource Resource instance. This may or may not be part of the same issue; but would ideally be fixed at the same time.






[JERSEY-2479] Support conversin of enums with JAXB's @XmlEnum Created: 16/Apr/14  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.7
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Michael Osipov Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The string to enum converter relies on the enum valueOf method. This does not play well with enums created by xjc or annotated with @XmlEnum. This improvement should detect that annotation and use the fromValue method rather than the valueOf method.



 Comments   
Comment by yan_shi [ 15/Dec/14 ]

I encountered the same issue and found it here http://stackoverflow.com/questions/19977002/jersey-2-enum-as-method-parameter-throws-exception/27491386#27491386.
But I think it is not because it didn't call fromValue(). Every Enum has a valueOf() so I think using valueOf is OK.
The real reason is in the org.eclipse.persistence.jaxb.JAXBContext, they didn't initiate the DEFAULT_VALIDATION_EVENT_HANDER with DefaultValidationEventHandler(), instead they implemented it in this way:
protected static final ValidationEventHandler DEFAULT_VALIDATION_EVENT_HANDER = new ValidationEventHandler() {
public boolean handleEvent(ValidationEvent event)

{ return event.getSeverity() < ValidationEvent.FATAL_ERROR; }

};

So only FATAL ERROR will be processed and validation error will be ignore. It is different to DefaultValidationEventHandler, in which with ERROR level event it will also return false.

Comment by Michael Osipov [ 15/Dec/14 ]

Using valueOf is not OK because the example from SO is too simple. If you have customized your Enum or the XML value does not match the Java value, it need the valueOf. Creating a ParamConverter for every single Enum is not a solution. Hell knows who deleted my answer and downvoted it.





[JERSEY-2485] ValueFactoryProvider implementations parse relative to ContainerRequest instead of the Resource Created: 20/Apr/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.7
Fix Version/s: None

Type: Bug Priority: Major
Reporter: cowwoc Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: unplanned

 Description   

ValueFactoryProvider implementations (MatrixParamValueFactoryProvider, PathParamValueFactoryProvider, QueryParamValueFactoryProvider and WebTargetValueFactoryProvider) look up the parameter values relative to getContainerRequest().getUriInfo() instead of relative to the associated Resource.

This blocks implementing JERSEY-2172.



 Comments   
Comment by cowwoc [ 20/Apr/14 ]

To clarify, I am invoking:

ExtendedResourceContext resourceContext = serviceLocator.getService(ExtendedResourceContext.class);
Resource rootResource = resourceContext.getResourceModel().getRootResources().get(0);
Resource childResource = rootResource.getChildResources().get(0);
Factory<?> valueProvider = childResource.getResourceLocator().getInvocable().getValueProviders(serviceLocator).get(0);

I expect the valueProvider to return the value of the first parameter of the resource locator of childResource, but instead it returns value for the resource that matched the current HTTP request.

I believe you will need to change getValueProviders() to take a URI parameter to be parsed. Otherwise, move Invocable.getValueProviders() to UriInfo.getValueProviders() because it is misleading in its current form (the method doesn't actually return values relative to the invocable but rather relative to UriInfo).





[JERSEY-3016] Unable to inject custom type to Application constructor Created: 07/May/14  Updated: 07/Dec/15

Status: Reopened
Project: jersey
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: hubick Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: incomplete

 Description   

If you provide an AutoDiscoverable Factory for a custom type, you won't be able to inject that type as a parameter to your Application constructor.

This worked in Jersey 1.x.



 Comments   
Comment by hubick [ 07/May/14 ]

That is, in Jersey 1.x, you could inject a type from an InjectableProvider listed in META-INF/services/jersey-server-components.

Comment by Michal Gajdos [ 12/May/14 ]

Can you describe your use-case so we can look for another way of solving this as well?

Injecting into constructor of Application subclass is limited. You can inject CDI beans via @Inject, you can inject some JAX-RS contracts via @Context but injecting other contracts may be weak because much work regarding the injection is done after an instance of Application is created. This is the case of AutoDiscoverables.

Comment by hubick [ 20/May/14 ]

For example, I have an abstract "ResourceLocator" class used by clients to get access to configuration or other resources, and which uses the NIO WatchService to fire events if those resources change. I have a concrete implementation for the Sevlet environment (built on ServletContext.getResource()), could have one for the command-line environment (built on Class.getResource()), etc. My Application constructor injects a ResourceLocator and uses it to construct itself and, importantly, the singleton objects it provides.

I'm guessing there's a reason for not initializing all HK2, Jersey, and custom AutoDiscoverable's first, and then initializing the Application and it's getClasses() and getSingletons() after?

Comment by Michal Gajdos [ 30/Jul/14 ]

What server are you encountering this issue on?

Comment by hubick [ 30/Jul/14 ]

I'm using org.glassfish.jersey.servlet.ServletContainer under Tomcat 7.

Comment by Michal Gajdos [ 30/Jul/14 ]

OK, thanks. I guess you don't have enabled CDI. I've run into similar issue so I am trying to find similarities with your use-case.

Comment by hubick [ 30/Jul/14 ]

I'm currently using a @Context annotation. It's been a few months, but I thought either @Inject also wouldn't work or would tie my code to Jersey or something.

Comment by Marek Potociar [ 07/Dec/15 ]

This is really an enhancement request

Comment by Marek Potociar [ 07/Dec/15 ]

IMHO, this should be solved in HK2 directly. Some kind of SPI that pre-configures any ServiceLocator created. Moving to HK2.

Comment by jwells [ 07/Dec/15 ]

I think the use of a ServiceLocatorListener (https://hk2.java.net/2.4.0-b34/apidocs/org/glassfish/hk2/api/ServiceLocatorListener.html) would solve this problem. People can add a listener, the listener will be called anytime a ServiceLocator is created and can then be used to do whatever is needed to the ServiceLocator

Comment by jwells [ 07/Dec/15 ]

I think there is a feature that already covers this request

Comment by hubick [ 07/Dec/15 ]

That sounds like Jersey then needs a ServiceLocatorListener implementation to support this? Can this be assigned back to Jersey instead of being closed? Thanks.

Comment by jwells [ 07/Dec/15 ]

OK, re-assigning to Jersey to see if they want to use the hk2 feature





[JERSEY-2539] Jersey Client send Cookie with ',' separator, who is deprecated Created: 09/Jun/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.9
Fix Version/s: None

Type: Bug Priority: Major
Reporter: chneuvtepeu Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: client, cookies

 Description   

Hi,

I use WebResourceFactory to create a resource for my client :

WebResourceFactory.newResource(MyResource.class, client.target(url))

I have a method with cookies in my resource:

String notification(@CookieParam("session_id") long sessionId, @CookieParam("session_token") String sessionToken,
String notification);

Then cookies are sent with a "," separator. Who seems to be an obsolete RFC (2965 vs 6265)

You can see new RFC here : http://tools.ietf.org/html/rfc6265#section-4.1

Discution on spray project here : https://github.com/spray/spray/issues/869

I try to path jersey by myself to submit a PR, but it can't compile on my computer :

diff --git i/core-client/src/main/java/org/glassfish/jersey/client/HttpUrlConnector.java w/core-client/src/main/java/org/glassfish/jersey/client/HttpUrlConnector.java
index b32d8a6..db289c2 100644
--- i/core-client/src/main/java/org/glassfish/jersey/client/HttpUrlConnector.java
+++ w/core-client/src/main/java/org/glassfish/jersey/client/HttpUrlConnector.java
@@ -351,7 +351,7 @@ class HttpUrlConnector implements Connector {
                 boolean add = false;
                 for (Object value : headerValues) {
                     if (add) {
-                        b.append(',');
+                        b.append(';');
                     }
                     add = true;
                     b.append(value);

So, I'm not sure there is no side effect.



 Comments   
Comment by Miroslav Fuksa [ 11/Jun/14 ]

Hi,

thanks for the bug report and proposal for fix. I am not sure the fix is 100% correct... this would influence also http headers which should use ',' as separator.

I am moving the issue to the backlog.

thanks
Mira





[JERSEY-2542] a @BeanParam w/ @FormParam on Date type member can't parse ISO dates Created: 09/Jun/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.0, 2.0.1, 2.1, 2.2, 2.3, 2.3.1, 2.4, 2.4.1, 2.5, 2.5.1, 2.6, 2.7, 2.8, 2.9
Fix Version/s: None

Type: Bug Priority: Major
Reporter: derekm00re Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: 2 days
Time Spent: Not Specified
Original Estimate: 2 days
Environment:

Linux (Fedora 19), Tomcat 7.0.47, Eclipse 4.3.1, Jersey 2.8, Java 1.7


Status Whiteboard:

I have a comprehensive fix with unit tests started here:
https://github.com/derekm/jersey/commits/fix-httpdateformat

I needed only ISO date for my purposes, but as I read through the various RFCs they called in many other alternative date formats by reference or by ABNF, so I'm looking to contribute more than just ISO date parsing (ISO date being partial ISO 8601 timestamps as in ECMAScript ISO date, XSD dateTime, or RFC3339).

Tags: beanparam, beans, common, date, date-time, formparam, httpdateformat, message

 Description   

I'm created dual-use JAXB and BeanParam value objects to unify my JSON/XML and x-www-form-urlencoded code paths. I have value objects where members are annotated with both @XmlElement for JSON/XML input/output and @FormParam for x-www-form-urlencoded input.

Where @FormParam members are of data type Date, Jersey's form processing code can only parse HTTP cookie- and header-style date strings and not the ISO date strings produced by JAXB's JSON/XML output, producing exceptions like the following:

stack trace
SEVERE: Servlet.service() for servlet [Unt1l REST Service] in context with path [/unt1l] threw exception [A MultiException has 3 exceptions.  They are:
1. org.glassfish.jersey.server.ParamException$FormParamException: HTTP 400 Bad Request
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of org.unt1l.rest.api.Event errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on org.unt1l.rest.api.Event
] with root cause
java.text.ParseException: Unparseable date: "2014-01-06T00:00:00Z"
        at java.text.DateFormat.parse(DateFormat.java:357)
        at org.glassfish.jersey.message.internal.HttpDateFormat.readDate(HttpDateFormat.java:135)
        at org.glassfish.jersey.server.internal.inject.ParamConverters$DateProvider$1.fromString(ParamConverters.java:201)
        at org.glassfish.jersey.server.internal.inject.AbstractParamValueExtractor.convert(AbstractParamValueExtractor.java:138)
        at org.glassfish.jersey.server.internal.inject.AbstractParamValueExtractor.fromString(AbstractParamValueExtractor.java:129)
        at org.glassfish.jersey.server.internal.inject.SingleValueExtractor.extract(SingleValueExtractor.java:83)
        at org.glassfish.jersey.server.internal.inject.FormParamValueFactoryProvider$FormParamValueFactory.provide(FormParamValueFactoryProvider.java:122)
        at org.glassfish.jersey.server.internal.inject.ParamInjectionResolver.resolve(ParamInjectionResolver.java:134)
        at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:232)
        at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:255)
        at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:414)
        at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:456)
        at org.glassfish.jersey.server.internal.inject.BeanParamValueFactoryProvider$BeanParamValueFactory.provide(BeanParamValueFactoryProvider.java:103)
        at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:81)
        at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:121)
        at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:152)
        at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:104)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:387)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:331)
        at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:103)
        at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:269)
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
        at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
        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.process(Errors.java:267)
        at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:297)
        at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:252)
        at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1023)
        at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:372)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:382)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:345)
        at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:220)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
        at org.apache.tomcat.util.net.AprEndpoint$SocketWithOptionsProcessor.run(AprEndpoint.java:2367)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
        at java.lang.Thread.run(Thread.java:744)


 Comments   
Comment by Jakub Podlesak [ 11/Jun/14 ]

Derek,

Could you please sign the OCA, so that we could leverage your fix?
Please see here for details: http://www.oracle.com/technetwork/community/oca-486395.html

Thanks in advance!

~Jakub

Comment by Jakub Podlesak [ 11/Jun/14 ]

Moving to backlog as this needs OCA signed, which is not likely to happen until the current version is released.
Once the OCA is signed, the provided patch could be taken more-less as is after fixing minor issues (lines commented out, one-liner block in for cycle (which is missing curly braces), etc..)

Comment by derekm00re [ 11/Jun/14 ]

I have signed and submitted OCA to oracle-ca_us@oracle.com & Marek Potociar <marek.potociar@oracle.com>.

It is also available here:
https://drive.google.com/file/d/0BygZ-6LZQW1PbDJkSHdpSU1VRlZyUzNJMGFnYXM3WC1SYm9Z/edit

Comment by derekm00re [ 12/Jun/14 ]

I think I'm ready to issue a pull request from my branch here:

https://github.com/derekm/jersey/tree/fix-httpdateformat

I added a perhaps paranoid piece of code here:
https://github.com/derekm/jersey/commit/535f47ccff10bc0452ee8013000eb5e41247ee47
to ensure that only the largest parse position for a given date is added to the map of valid parsings, in case I missed any edge cases with my date patterns or in case someone else adds more patterns and more nuance later.

The commit history for my branch shows the work as I've completed it:

  • I've cleaned-up code for coding standards and to remove debugging code.
  • I've refactored the patterns and tests to check for correctness and completeness.
  • I've added a PREFERRED_DATE_FORMAT_PATTERN because I consolidated a few patterns into the one RFC1123_DATE_FORMAT_PATTERN, breaking it for use with getPreferredDateFormat() which needs to be in conformance with HTTP/1.0 and HTTP/1.1 RFCs (which requires 4-digit year and 'GMT' zone, despite RFC-1123 saying implementations SHOULD use numeric zones).




[JERSEY-2547] Need a replacement for JResponse<?> in order to provide metadata for the WADL/ Schema generator Created: 12/Jun/14  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.9
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: gdavison Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

In Jersey 1.x you could have a method return JResponse<Type> rather than Response as this would allow the WADL generator to introspect the return value for a method to generate the right representation information.

In Jersey 2.x the only way to get this to work is to return Type and then throw a WebApplicationException in every case which is not a very pleasing design.

Ideally we would return to a JResponse like solution because it provides compile time checking, an alternative would be some kind of annotation; but of course this is not type safe.

The annotation could also be applied to any exceptions throw although it would be possible to extra type information if JReponse or similar came back as a subclass of WebApplicationException is used:

public WebErrorException extends WebApplicationException
{
public WebErrorException(JResponse<ErrorBean> respose)

{ super(response); }

public JResponse<ErrorBean> getReponse()

{ super.getResponse(); }

}

For error types, we probably need some way of specifying error code in some way. It would be possible to provide run time code at leaf that would verify the status of the response against the annotated code.






[JERSEY-2583] Reuse of HttpClientContext in ApacheConnector Created: 11/Jul/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: connectors
Affects Version/s: 2.10.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Herr-Herner Assignee: Unassigned
Resolution: Unresolved Votes: 3
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to JERSEY-2754 JERSEY-2736: Impossible to define Con... Open
Tags: connector, connectors
Sprint: Triaged

 Description   

I am using two-way SSL authentication in combination with the ApacheConnector. To get things properly working, I had to modify the sources so that the created HttpClientContext (line 458) is reused, otherwise a new SSL handshake is initiated which causes a lot of overhead.

Is it possible to add that behavior?



 Comments   
Comment by Herr-Herner [ 11/Jul/14 ]

Just for clarification: Every call to the ApacheConnector in the ssl scenario causes a new handshake!

Comment by Herr-Herner [ 14/Jul/14 ]

Just thought about a proper solution... The reusement of the HttpClientContext does not work when different target hosts are addressed because we cannot share the connection information between different hosts. Different target hosts require each their own ssl connection. We can reuse HttpClientContext only when the same host is addressed. Have a look here: http://hc.apache.org/httpcomponents-client-4.4.x/tutorial/html/advanced.html. What we can do is to offer the capability to pass an instance of UserTokenHandler to the HttpClientBuilder. An implementation could extend the default implementation by holding a HashMap mapping the target host, extracted from the HttpClientContext, to the user token received from the extended default implementation if the table does not contain a mapping. But we get a memory leak... How can be ensure that mappings are removed when the connection is closed. What are your thoughts? Is there a better solution?

Comment by Michal Gajdos [ 21/Jul/14 ]

I guess we can use rather some kind of cache instead of a map where token would expire after a certain amount of time (which would lead to a new handshake). Moving to backlog.

Comment by rognor [ 12/Sep/14 ]

The default setting is to maintain a pool per route, so why can't the default be to reuse a connection based on a userType in the context?
I found no way to control this from the outside but by changing this I could force reuse of SSL connections in a nicely manner.

Comment by Herr-Herner [ 24/Sep/14 ]

That sounds interesting... Could you please provide a more detailed description of your idea.

Comment by rognor [ 24/Sep/14 ]

Assuming that reuse of connection should be the default I'd say that the userType in the HttpClientContext should be set from the connector. This way the pool will be able to pick up any already existing connection that isn't leased.
But I suppose this also needs to be configurable so that the userType is taken from the principal as it looks like it is meant to be. Not sure though on how to inject this in the connector but Im sure we can find a good way
This configuration wont be available if you replace the connection manager with lets say the Basic one. But that can probably be clearly documented so users wont run into such problems.

Comment by Herr-Herner [ 26/Sep/14 ]

I am a little bit confused... With 'userType' you actually mean 'userToken', right? I t think with the help of 'UserTokenHandler' offered by the Apache HttpClient, we are able to bind a HttpContext to a specific token, but the question is: How should the API look like? The JerseyClient is not bound to a specific remote endpoint and so there must be something given from the outside that tells an implementation of 'UserTokenHandler' to use which token in combination with which remote endpoint. I think, the best and most flexible way would be to extend the current Apache Connector API in the form that it allows to pass an implementation of 'UserTokenHandler' to the Apache HttpClient. What do you think?

Comment by rognor [ 26/Sep/14 ]

Yeah, my bad. It is userToken.
When looking in the MainClientExec I think it looks like the UserTokenHandler is used later than the actual connection request is done. At request time userToken still is null.
When you say that you will bind the HttpContext to the token, where can that be done?

I'm not sure that the flexibility we're looking at really is needed. As I understand it userToken is supposed to be connected to a user Principal so that should perhaps be configurable. The default can use any value, just to enable connection reuse.

I think the current issue is as in the default jersey connector, where the implementation results in a cache miss when trying to adhere to the keep-alive header.
That code is very different but the pool lookup fails in a similar way there as well.

Comment by ok2c [ 16/Feb/15 ]

According to the HTTP/1.1 protocol spec persistent connections are expected to be state-less and therefore re-usable by different HTTP sessions. In two cases (two way SSL and NTLM) however persistent connections acquire a particular security context and become associated with a particular user identity. HttpClient 4.x intentionally treats such connections differently for security reasons. By default HttpClient chooses to not re-use a state-full connection instead of handing it out to the wrong user by mistake. HttpClient expects the caller to inform it that requests are logically related and are to be executed on behalf of the same user or within the same security context. This is usually accomplished by simply passing the same HttpContext instance to the HttpClient#execute call. So, ideally the caller should be able to pass an HttpContext instance along with the HttpRequest. If that is not possible due to API restrictions an alternative solution could be to always pre-populate HttpContext with a token representing a particular user based on the security context maintained by ApacheConnector. if ApacheConnector does not support different user identities one could also choose to disable connection state tracking altogether.

Oleg

Comment by Herr-Herner [ 16/Feb/15 ]

Is it right, that a stateful HttpClientContext can only be reused when you talk to the same endpoint (host and port)? Would you say, that a cache mapping the endpoint (host and port) to a HttpClientContext is a feasible soultion?

Comment by ok2c [ 16/Feb/15 ]

Not necessarily. It think it is perfectly valid for a HTTP session to span across multiple hosts (via a redirect, for instance).

One also needs to be careful about thread-safely here and to make sure that HttpClientContext instances do not end up used concurrently by multiple threads. While HttpContext classes are perfectly thread-safe they may contain attributes that are not. A cache of immutable user tokens per endpoint may actually work quite well.

Oleg

Comment by Herr-Herner [ 16/Feb/15 ]

Ok.. That sounds interesting. I think the most flexible solution would be to offer the possibility to pass into the ApacheProvider an implementation of e.g. UserTokenRequestHandler, that is used to associate a UserToken to a HttpContext and a HttpUriRequest. A CachedUserTokenRequestHandler could then use a cache of immutable user tokens per endpoint. A default implementation like DefaultUserTokenRequestHandler could return null as it is stated in the Apache docs to indicate that the HttpUriRequest is not user-specific.

Comment by Herr-Herner [ 21/Dec/15 ]

There was already a pull request started for fixing this issue. Maybe it is an adequate solution. Have a look here: https://github.com/jersey/jersey/pull/157





[JERSEY-2610] NPE when using async from groovy with untyped closure Created: 11/Aug/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.11
Fix Version/s: None

Type: Bug Priority: Major
Reporter: simon_buettner Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

JDK 7



 Description   

When trying to issue a post using the async method a NullPointerException is thrown by the JerseyInvocation class. Here is an example groovy script which show the issue. It can be executed right away. All dependencies will be resolved by your groovy installation.

@Grapes([
    @Grab(group='org.glassfish.jersey.core', module='jersey-client', version='2.11'),
    @Grab(group='com.google.guava', module='guava', version='17.0')
])
import javax.ws.rs.client.Client
import javax.ws.rs.client.ClientBuilder
import javax.ws.rs.client.InvocationCallback
import javax.ws.rs.client.WebTarget
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import com.google.common.util.concurrent.JdkFutureAdapters

Client client = ClientBuilder.newBuilder().build()
WebTarget webTarget = client.target('https://api.mailgun.net/v2/samples.mailgun.org/messages')

/**
 * Fails to execute request.
 *
 * here: /org/glassfish/jersey/client/JerseyInvocation.java
 * Line: 867
 * Reason: ReflectionHelper.getParameterizedTypeArguments(pair) returns null for groovy closure
 */
def call1 = webTarget.request().async().post(null, [
    completed: { Object response -> println response },
    failed: { Throwable t -> System.err.println(t) }
] as InvocationCallback)

/**
 * Executes request (but fails due to authorization issues, not relevant here)
 */
def call2 = webTarget.request().async().post(null, new InvocationCallback<Object>() {
    @Override
    void completed(Object o) {
        println o
    }

    @Override
    void failed(Throwable throwable) {
        System.err.println(throwable)
    }
})

ExecutorService executorService = Executors.newSingleThreadExecutor()
def listenableCall1 = JdkFutureAdapters.listenInPoolThread(call1, executorService)
listenableCall1.addListener({ }, executorService)

def listenableCall2 = JdkFutureAdapters.listenInPoolThread(call2, executorService)
listenableCall2.addListener({
    client.close()
    executorService.shutdown()
}, executorService)


 Comments   
Comment by Adam Lindenthal [ 01/Sep/14 ]

Hi Simon,
thanks for reporting this, I am moving the issue to our backlog, so that we can plan it for one of the future sprints.

Comment by Stepan Vavra [ 21/Dec/15 ]

Triaged. Lets check if this is still reproducible; otherwise, it will be closed.
Sorry for the delay.
Please do not hesitate to contribute to this by submitting your own pull request on Github.





[JERSEY-2615] Annoying Warning that class cannot be instanciated Created: 15/Aug/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: rebach Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I'm registering an nested singleton Object written in Scala as Singleton
component in a JAX-RS Application.

This an extract of the Scala code

class Activator  {
 [...]
  final val path = "admin/renderlets/overview"
  @Path(path)
  object RenderletsOverview {
    @GET def get() = {

The object RenderletsOverview is returned by getSingletons() of the
Application.

Everything works fine. Except for an annoying warning on the console:

May 29, 2014 11:50:11 PM org.glassfish.jersey.server.ApplicationHandler
initialize
INFO: Initiating Jersey application, version Jersey: 2.2 2013-08-14
08:51:58...
May 29, 2014 11:50:11 PM org.glassfish.jersey.server.ApplicationHandler
bindProvidersAndResources
WARNING: Component of class class [...]Activator$RenderletsOverview$ cannot
be instantiated and will be ignored.

The warning seems to be pointless as Jersey gets the object as instance, so it doesn't need to instantiate the class. In fact, despite the warning the root-resource works and can be accessed over the web.

(Original mailing list mail: https://java.net/projects/jersey/lists/users/archive/2014-05/message/78)



 Comments   
Comment by Miroslav Fuksa [ 27/Aug/14 ]

Hi,

how do you initialize your JAX-RS application? Do you use package scanning or you provide only instance of Application class? Can you please provide more details about JAX-RS app setup?

I have searched the Jersey code and find out that you can get this warning when for example your class is not a static class, abstract or has private modifier, etc. See this check from Resource class:

public static boolean isAcceptable(Class<?> c) {
        return !((c.getModifiers() & Modifier.ABSTRACT) != 0
                || c.isPrimitive()
                || c.isAnnotation()
                || c.isInterface()
                || c.isLocalClass()
                || (c.isMemberClass() && (c.getModifiers() & Modifier.STATIC) == 0));
    }

if this method returns false on your class then you get this warning. I am not a scala developer and I do not know how your class RenderletsOverview is translated into byte code. Does it create a public static class inside of Activator or does it create a local non-static class? Such a class could be found by package scanning and Jersey tries to register it and instantiated. And it fails. In parallel the instance of the same class is registered correctly. Now I am only guessing what could be wrong.

thanks
Mira

Comment by rebach [ 27/Aug/14 ]

Hi Mira,

I do not do any package scanning I just provide an app returning the singleton. It is used as follows:

ServletContainer container = new ServletContainer(
                ResourceConfig.forApplication(app));

If I look at the generated source created from the bytecode I see:

public class Activator implements org.osgi.framework.BundleActivator {

[...]

    @javax.ws.rs.Path(value = "admin/renderlets/overview")
    public class RenderletsOverview$ {

        @javax.ws.rs.GET
        public org.apache.clerezza.rdf.utils.GraphNode get() {
     ....

The actual binary can be found here: http://repo1.maven.org/maven2/org/apache/clerezza/platform.typerendering.gui/0.2/platform.typerendering.gui-0.2.jar

I assume it gets the warning because jersey wants inner classes to be static. But Jersey has no reason for this limitation, in fact things works well (apart from the warning) .

Comment by Miroslav Fuksa [ 27/Aug/14 ]

Hi,

thanks for the quick response. It could be the problem with local class as you say. If it is the case then we should not print the warning if we don't need to instantiate it.

I am moving the issue to the backlog.

thanks
Mira

hint for fixing the issue: reproduce the problem with the java local java class passed as a instance and remove the warning. The check for local class is valid only for resources registered as classes.

Comment by jontejj [ 07/Feb/15 ]

This warning is also logged when an interface that actually is working (through injecting an instance of it through hk2-guice) is used. I think isAcceptable needs to consider injectable resources as well.





[JERSEY-2618] Declarative linking for JSON produces incorrect result while working fine for XML. Created: 18/Aug/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: examples
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: yurip Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Tomcat 7.52, Java 1.7


Tags: JSON,, jersey, moxy

 Description   

I was trying to follow the declarative linking example: http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22declarative-linking%22

Here is my code:

@InjectLink(   
        resource = FolderResource.class,  
        method = "query",   
        style = Style.ABSOLUTE,   
        bindings = {@Binding(name = "requestCount", value="99")   
        },   
        rel = "${rel}"  
)   
@XmlJavaTypeAdapter(Link.JaxbAdapter.class)
@XmlAttribute 
private Link href;

When I run it, i am getting this:

.....
       "href": "javax.ws.rs.core.Link$JaxbLink@41a741a7",
.....

instead of the actual link.

If I use a String type instead of Link and don't use @XmlJavaTypeAdapter(Link.JaxbAdapter.class), I am getting a correct link but without query parameters.



 Comments   
Comment by Stepan Vavra [ 21/Dec/15 ]

Triaged. Let's check if this problem still remains.
Sorry for the delay.





[JERSEY-2627] Resource Reload Throw Exception Created: 25/Aug/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: containers
Affects Version/s: 2.11
Fix Version/s: None

Type: Bug Priority: Major
Reporter: icode Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Sprint: Triaged

 Description   

Container.reload(rc) at ContainerRequestFilter or MessageBodyWriter

19:23:53.964 [Grizzly-worker(10)] WARN o.g.grizzly.http.server.HttpHandler - GRIZZLY0200: Service exception
org.glassfish.hk2.api.MultiException: A MultiException has 1 exceptions. They are:
1. java.lang.IllegalStateException: ServiceLocatorImpl(__HK2_Generated_1,2,1706339275) has been shut down

at org.jvnet.hk2.internal.FactoryCreator.getFactoryHandle(FactoryCreator.java:80) ~[hk2-locator-2.3.0-b05.jar:na]
at org.jvnet.hk2.internal.FactoryCreator.dispose(FactoryCreator.java:110) ~[hk2-locator-2.3.0-b05.jar:na]
at org.jvnet.hk2.internal.SystemDescriptor.dispose(SystemDescriptor.java:481) ~[hk2-locator-2.3.0-b05.jar:na]
at org.glassfish.jersey.process.internal.RequestScope$Instance.remove(RequestScope.java:512) ~[jersey-common-2.11.jar:na]
at org.glassfish.jersey.process.internal.RequestScope$Instance.release(RequestScope.java:529) ~[jersey-common-2.11.jar:na]
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:299) ~[jersey-common-2.11.jar:na]
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:254) ~[jersey-server-2.11.jar:na]
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1028) ~[jersey-server-2.11.jar:na]
at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:365) ~[jersey-container-grizzly2-http-2.10.1.jar:na]
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201) ~[grizzly-http-server-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175) ~[grizzly-http-server-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.http.server.HttpHandlerChain.doHandle(HttpHandlerChain.java:223) ~[grizzly-http-server-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235) ~[grizzly-http-server-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) ~[grizzly-framework-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284) ~[grizzly-framework-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201) ~[grizzly-framework-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133) ~[grizzly-framework-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112) ~[grizzly-framework-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) ~[grizzly-framework-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561) ~[grizzly-framework-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) ~[grizzly-framework-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) ~[grizzly-framework-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) ~[grizzly-framework-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) ~[grizzly-framework-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565) ~[grizzly-framework-2.3.16.jar:2.3.16]
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545) ~[grizzly-framework-2.3.16.jar:2.3.16]
at java.lang.Thread.run(Thread.java:724) ~[na:1.7.0_25]
Caused by: java.lang.IllegalStateException: ServiceLocatorImpl(__HK2_Generated_1,2,1706339275) has been shut down
at org.jvnet.hk2.internal.ServiceLocatorImpl.checkState(ServiceLocatorImpl.java:2182) ~[hk2-locator-2.3.0-b05.jar:na]
at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetServiceHandle(ServiceLocatorImpl.java:580) ~[hk2-locator-2.3.0-b05.jar:na]
at org.jvnet.hk2.internal.ServiceLocatorImpl.getServiceHandle(ServiceLocatorImpl.java:573) ~[hk2-locator-2.3.0-b05.jar:na]
at org.jvnet.hk2.internal.FactoryCreator.getFactoryHandle(FactoryCreator.java:77) ~[hk2-locator-2.3.0-b05.jar:na]
... 26 common frames omitted



 Comments   
Comment by cowwoc [ 27/Aug/14 ]

The problem has to do with server shutdown, not reload. I am getting this while shutting down the server at the end of a unit test, reload() is never invoked.

We're not going to be able to reproduce/fix this issue without the help from Jersey committers. Please add as much information as possible about the incoming request when this exception occurs.

Comment by cowwoc [ 27/Aug/14 ]

Also, I believe this is a regression in version 2.11. I don't recall ever getting it in 2.09 (I upgraded from 2.09 to 2.11).

Comment by icode [ 28/Aug/14 ]
            resourceConfig.registerInstances(new ContainerRequestFilter() {

                @Override
                public void filter(ContainerRequestContext containerRequestContext) throws IOException {
                    container.reload();
                }
            });
Comment by icode [ 28/Aug/14 ]

all test code, pls set logger level to warn. all request get a 500 http status

package org.glassfish.jersey.examples.reload;

import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.spi.Container;
import org.glassfish.jersey.server.spi.ContainerLifecycleListener;

import javax.annotation.Priority;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import java.io.*;
import java.net.URI;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Reload example application.
 *
 * A {@link ContainerLifecycleListener container listener} gets registered
 * with the application. Upon application startup notification, the listener schedules
 * a new {@link TimerTask timer task} to check a text file called {@code resources}
 * every 2 seconds. When the text file change is detected, the application gets reloaded with
 * a new {@link ResourceConfig resource configuration} including all
 * resource classes listed in that file.
 *
 * @author Jakub Podlesak (jakub.podlesak at oracle.com)
 */
public class App {

    private static final Logger LOGGER = Logger.getLogger(App.class.getName());
    private static final URI BASE_URI = URI.create("http://localhost:8080/flights/");
    public static final String ROOT_PATH = "arrivals";

    static Container container;

    public static void main(final String[] args) {
        try {
            LOGGER.info("Resource Config Reload Jersey Example App");

            final ResourceConfig resourceConfig = new ResourceConfig(ArrivalsResource.class);
            resourceConfig.registerInstances(new ContainerLifecycleListener() {
                @Override
                public void onStartup(final Container container) {
                    App.container = container;
                }

                @Override
                public void onReload(final Container container) {
                    System.out.println("Application has been reloaded!");
                }

                @Override
                public void onShutdown(final Container container) {
                    // ignore
                }
            });

            resourceConfig.register(ReloadFilter.class);

            final HttpServer server = GrizzlyHttpServerFactory.createHttpServer(BASE_URI, resourceConfig);

            System.out.println(String.format("Application started.\nTry out %s%s\nHit enter to stop it...", BASE_URI, ROOT_PATH));
            System.in.read();
            server.shutdownNow();
        } catch (final IOException ex) {
            Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    @PreMatching
    @Priority(0)
    public static class ReloadFilter implements ContainerRequestFilter {

        @Override
        public void filter(ContainerRequestContext containerRequestContext) throws IOException {
            container.reload();
        }
    }
}
Comment by icode [ 28/Aug/14 ]

jersey 2.9 not have this issuse

Comment by cowwoc [ 28/Aug/14 ]

@icode,

Thank you! So now we've established this is a regression relative to version 2.9 and provided a minimal testcase.

Comment by Adam Lindenthal [ 13/Oct/14 ]

Thanks, guys. Moving to backlog.

Comment by cowwoc [ 05/Nov/14 ]

I am running into JERSEY-2627 and JERSEY-2622 very frequently (multiple times per run of unit tests). Can you please increase the priority of these issues? It's very annoying trying to differentiate between stack-traces related to actual test failures and these false positives.

Comment by Stepan Vavra [ 21/Dec/15 ]

Triaged. Let's check if this problem still remains.
In case you feel strongly about the issue, please consider contributing a fix by submitting a Github pull request.





[JERSEY-2682] Accessing response metadata with jersey-client async Created: 10/Oct/14  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.13
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: mikaelstaldal Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: client

 Description   

Consider using jersey-client in async mode with an InvocationCallback<Order>. Order is a custom domain object for which we have a MessageBodyReader available.

Invocation invocation = client.target(someURL).request().buildGet();
invocation.submit(new InvocationCallback<Order> {
    public void completed(Order order) { 
        // I want to access response metadata here
        process(order);
    }
    public void failed(Throwable throwable) { 
        error();
    }
});

I want to access the response metadata (available in javax.ws.rs.core.Response) when the response is successful. I might want to know the exact HTTP status code (200, 201 or 202), or read some HTTP response header (such as ETag, Location).

I can accomplish this by using InvocationCallback<Response> and then do readEntity() on the Response. But as far as I know, this won't be properly asynchronous since Response.readEntity() may block on reading the full response from the network.

This can be solved by either provide the Response object to the InvocationCallback.success() method, or to provide an asynchronous version of the Response.readEntity() method.



 Comments   
Comment by mikaelstaldal [ 16/Oct/14 ]

I have a proposal.

Create a new interface InvocationCallback2 (feel free to come up with a better name):

public interface InvocationCallback2<RESPONSE> {
    public void completed(RESPONSE response, javax.ws.rs.core.Response underlyingResponse);
    public void failed(Throwable throwable);
}

and add a new method to javax.ws.rs.client.Invocation:

    public <T> Future<T> submit(InvocationCallback2<T> callback);
Comment by Jakub Podlesak [ 14/Jan/15 ]

The functionality you are asking should be covered with a non-blocking I/O based client.
The work on this new feature is in progress.

Comment by Jakub Podlesak [ 14/Jan/15 ]

Moving to backlog, as it is not clear which particular version will introduce the NIO based client. As i mentioned earlier, work on this feature is in progress already.

Comment by Marek Potociar [ 22/Jan/15 ]

I have looked at the issue and I’m not sure I understand the problem you are pointing out:

1.{{ InvocationCallback<Order>}} is run from some other thread (i.e. asynchronously) that has issued the request
2. The callback is only invoked AFTER the Response.readEntity(Order.class) has completed. So having an InvocationCallback<Response> and invoking Response.readEntity(..) inside is not making things worse.

Perhaps you are looking for a non-blocking I/O API support, which is planned for the next release of JAX-RS? Something like {{Response.readEntity(Order.class, order ->

{ … }

)}} ?
Btw. do you know that you can easily check the response code from a JAX-RS ClientResponseFilter ?





[JERSEY-2685] Document breaking change for custom request parameter converter in migration guide Created: 13/Oct/14  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: docs
Affects Version/s: 2.13
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: nobeh5 Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The discussion in JERSEY-2665 revealed that Jersey 2.x documentation in Section 3.2 documents how to use "customer request parameter" converters in @*Param.

However, in Jersey 1.x, it was possible to use "message body readers/writers" for such use case although not specifically documented in JAX-RS 1.0 specification.

This ticket requests to make explicit reference to this breaking change from Jersey 1.x to Jersey 2.x for the users.



 Comments   
Comment by Adam Lindenthal [ 13/Oct/14 ]

Thanks for opening, moving to backlog in order to be able to plan it for one of the future sprints.





[JERSEY-2690] GF: Fail to lookup EJB that is declared in war module of an EAR Created: 21/Oct/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: containers
Affects Version/s: 2.10, 2.13
Fix Version/s: None

Type: Bug Priority: Major
Reporter: gray Assignee: Unassigned
Resolution: Unresolved Votes: 9
Labels: pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Glassfish 4.1 (jersey module version 2.10.4)



 Description   

When declare EJB to be JAX-RS endpoint inside war module that included in EAR like this:

@Stateless
@Path("/user")
@Produces(MediaType.APPLICATION_JSON)
public class UsersResource {
...

Name of the war module is "op-client"
I got following exception in the logs:

[2014-10-20T18:56:53.226+0200] [glassfish 4.1] [WARNING] [] [org.glassfish.jersey.gf.ejb.internal.EjbComponentProvider] [tid: _ThreadID=31 _ThreadName=http-listener-1(5)] [timeMillis: 1413824213226] [levelValue: 900] [[
  An instance of EJB class, com.mycompany.opclient.rest.UsersResource, could not be looked up using simple form name. Attempting to look up using the fully-qualified form name.
javax.naming.NamingException: Lookup failed for 'java:app/someothermodule/UsersResource' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: No object bound to name java:app/someothermodule/UsersResource]
	at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:491)
	at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:438)
	at javax.naming.InitialContext.lookup(InitialContext.java:411)
	at javax.naming.InitialContext.lookup(InitialContext.java:411)
	at org.glassfish.jersey.gf.ejb.internal.EjbComponentProvider.lookupSimpleForm(EjbComponentProvider.java:378)
....

Note that lookup is complains about "someothermodule" not "op-client". Earlier in the logs though there is following message:

[2014-10-20T18:08:29.484+0200] [glassfish 4.1] [INFO] [AS-EJB-00054] [javax.enterprise.ejb.container] [tid: _ThreadID=44 _ThreadName=admin-listener(4)] [timeMillis: 1413824909484] [levelValue: 800] [[
  Portable JNDI names for EJB UsersResource: [java:global/earmodule/op-client/UsersResource, java:global/earmodule/op-client/UsersResource!com.mycompany.opclient.rest.UsersResource]]]

Which means that bean was successfully discovered and registered and should be available for lookup. Evaluating expression with proper name for lookup at breakpoint in EjbComponentProvider confirms that.
Digging deeper into the problem I've found that patch that was made to fix this issue (325a2f214e093859d41d81f9f06652c169a03aa4) introduced following code in registerEjbInterceptor method of EjbComponentProvider:

    private void registerEjbInterceptor() {
        try {
            final Object interceptor = new EjbComponentInterceptor(locator);
            initialContext = getInitialContext();
            final EjbContainerUtil ejbUtil = EjbContainerUtilImpl.getInstance();
            final ApplicationInfo appInfo = ejbUtil.getDeployment().get((String)initialContext.lookup("java:app/AppName"));
            final List<String> tempLibNames = new LinkedList<String>();
            for 
(ModuleInfo moduleInfo : appInfo.getModuleInfos()) {
                final String jarName = moduleInfo.getName();
                if (jarName.endsWith(".jar")) {
                    final String moduleName = jarName.substring(0, jarName.length() - 4);
                    tempLibNames.add(moduleName);
....

Note jarName.endsWith(".jar") part. This check for file extension basically prevents all beans that live inside "*.war" being discovered when doing cycle in lookupSimpleForm method:

    private static Object lookupSimpleForm(InitialContext ic, String name, EjbComponentProvider provider) throws NamingException {
        if (provider.libNames.isEmpty()) {
            String jndiName = "java:module/" + name;
            return ic.lookup(jndiName);
        } else {
            NamingException ne = null;
            for (String moduleName : provider.libNames) {
                String jndiName = "java:app/" + moduleName + "/" + name;

because now we never see war file in provider.libNames collection. This breaks my and not only my (https://java.net/jira/browse/GLASSFISH-21114) application and should be fixed.



 Comments   
Comment by Adam Lindenthal [ 22/Oct/14 ]

Hi Gray,

thanks for creating the issue. I am moving it to backlog, so that we can plan it for one of the future sprints.

Regards,
Adam

Comment by Sparksis [ 14/Jan/15 ]

Hi Adam,

Is there an ETA on when this could be revisited? As is glassfish 4.1 does not support JAX-RS with @Stateless EJBs in web archives.

Thanks,

Comment by lberteau [ 22/Jan/15 ]

Hi everyone,

If it may help, I have noticed that I have this issue within 32 bits environnements.
The same code works fine within a 64 bits JDK.

Don't have a clue about the reasons, but that's what I observed.

Regards,
Laurent

Comment by MarvinEmilBrach [ 08/Mar/15 ]

posssible workaround: replace @Stateless with:
@javax.enterprise.context.RequestScoped
@javax.enterprise.context.ApplicationScoped
@javax.enterprise.context.ConversationScoped // NOT tested
@javax.enterprise.context.SessionScoped // NOT tested

Comment by Adam Lindenthal [ 19/May/15 ]

https://github.com/jersey/jersey/pull/162





[JERSEY-2722] ExceptionMapperFactory should take into account priority of mappers as set by @Priority annotation Created: 03/Dec/14  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: media
Affects Version/s: 2.13
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: sarxos Assignee: Unassigned
Resolution: Unresolved Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:
  • OpenJDK 7 (1.7.0_65)
  • CentOS 6
  • Jetty Embedded 9.x


 Description   

Hello Jersey Team,

After upgrading from 2.6 to 2.13 I discover issue with Jersey exception mappers. I do have my own exception mapper defined for JsonMappingException (among many other mappers), but whenever I send invalid JSON, the Jersey is using default exception mapper that comes registered with JacksonFeature (see logs below):

Request:

2014-12-03 13:14:59,540 [qtp880578076-30] INFO  com.github.sarxos.elm.Application - 15 * Server has received a request on thread qtp880578076-30
15 > POST https://x.x.x.x:8443/xxx/api/register
15 > Content-Type: application/json; charset=UTF-8
{
"t":"abba",
"s":44444,
}

And the response:

2014-12-03 13:14:59,549 [qtp880578076-30] DEBUG org.glassfish.jersey.tracing.general - EXCEPTION_MAPPING Exception mapper [com.fasterxml.jackson.jaxrs.base.JsonMappingExceptionMapper @499ca5ec] maps [com.fasterxml.jackson.databind.JsonMappingException @6600e06] ('Numeric value (44444) out of range of Java byte
 at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@2eda6dd2; line: 3, column: 10] (through reference chain: com.github.sarxos.elm.Device["s"])') to <400/CLIENT_ERROR|Bad Request> [ 0.09 ms]
2014-12-03 13:14:59,550 [qtp880578076-30] INFO  com.github.sarxos.elm.Application - 16 * Server responded with a response on thread qtp880578076-30
16 < 400
16 < Content-Type: text/plain
Numeric value (44444) out of range of Java byte
 at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@2eda6dd2; line: 3, column: 10] (through reference chain: com.github.sarxos.elm.Device["s"])

This fragment is important:

Exception mapper [com.fasterxml.jackson.jaxrs.base.JsonMappingExceptionMapper @499ca5ec] maps [com.fasterxml.jackson.databind.JsonMappingException @6600e06] 

I can clearly see, that Jersey is using default JsonMappingExceptionMapper instead of my own mapper I created especially for this purpose.

I suspect that the effect I'm observing is caused by the enhancement implemented by JERSEY-2283 in 2.7, commit 4f04eda4079305b8f5b357902de7d9e09c581d34.

I'm unable to reproduce it on the development environment (Ubuntu 14, Oracle Java 8, Eclipse), but on the test environment (CentOS 6, OpenJDK 7) it is reproducible in 100% cases. I suspect that JARs order or class loading time is important here. In the Jersey ExceptionMapperFactory these two mappers (custom one I expect to be used, and a default one) has the same inheritance distance calculated, so I guess that it's safe to assume that the first one found will be always returned and there is no other order rule here.

Therefore, due to above, maybe it's worth to consider adding e.g. @Piority annotation value to be compared when distance for all available mappers of the same type is exactly the same? What do you think?



 Comments   
Comment by Jakub Podlesak [ 09/Dec/14 ]

Until this gets implemented, you should be able to use https://jersey.java.net/apidocs/2.13/jersey/org/glassfish/jersey/spi/ExtendedExceptionMapper.html to workaround the issue.

Comment by sarxos [ 10/Dec/14 ]

Jakub,

Thank you. For now I w/a this by adding this piece of code in my ResourceConfig:

@Inject
public MyResourceConfig(ServiceLocator locator) {
	// w/a for JERSEY-2722
	register(JacksonJaxbJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class);
	// ...
}

This is to skip the code from if block from line 81 in JacksonFeature.java.

Comment by gdemecki [ 09/Oct/15 ]

@Jakub what is the correct usage of the ExtendedExceptionMapper?

I'm asking because with ExtendedExceptionMapper I've failed to override built-in exception mappers:

  • com.fasterxml.jackson.jaxrs.base.JsonParseExceptionMapper
  • com.fasterxml.jackson.jaxrs.base.JsonMappingExceptionMapper

Only workaround given by @sarxos worked fine for me.

Comment by tomasz.kalkosinski [ 21/Dec/15 ]

This is still an issue in 2.22.1. In effect you cannot implement your own ExceptionMapper that implements ExceptionMapper<ValidationException> interface. Default ValidationExceptionMapper is always first on list and logic in ExceptionMapperFactory#find always prefers first one found.

Jakub Podlesak you cannot use ExtendedExceptionMapper because ExceptionMapperFactory#isPreferredCandidate can use it only if sameDistance is different, not equal.

I cannot workaround that and remove ValidationExceptionMapper from processing ValidationException.





[JERSEY-2734] FilesScanner Tokenizer does not work well with input containing delimiter characters Created: 21/Dec/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.13, 2.14
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Philipp91 Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Windows 7, Java 8



 Description   

this.files = new File[Tokenizer.tokenize(fileNames, Tokenizer.COMMON_DELIMITERS).length];
for (int i = 0; i < files.length; i++)

{ files[i] = new File(fileNames[i]); }

This code has multiple problems:

  • The result of Tokenizer.tokenize is not used, only the length is taken. For the input "someFile;anotherFile", this leads to a ArrayIndexOutOfBoundsException, because the files-Array has size 2, but only fileNames[0] can be read, which won't even resolve to a file, because it has not been split.
  • COMMON_DELIMITERS contains the space character, which can easily be contained in a single file name. On Windows, this is quite common with "C:\Program Files\...".


 Comments   
Comment by Jakub Podlesak [ 22/Dec/14 ]

Although the issue does not contain a real use case, the code is indeed wrong and should be fixed.





[JERSEY-2736] Impossible to define ConnectionReuseStrategy using ApacheConnector Created: 25/Dec/14  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: connectors
Affects Version/s: 2.13
Fix Version/s: None

Type: Bug Priority: Major
Reporter: TheTweak07 Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

There is no way to define ConnectionReuseStrategy for Apache client (using ApacheConnector) through client config, and the fact that ApacheConnector is creating HttpClientBuilder with default value for boolean "systemProperties" (which is "false"), makes it impossible to use "http.keepAlive" system property.



 Comments   
Comment by TheTweak07 [ 25/Dec/14 ]

For Jersey client with ApacheConnector of course.

Comment by Stepan Vavra [ 21/Dec/15 ]

Triaged.
Let's try to implement this improvement.

Additionally, in case you feel strongly about the issue, please consider contributing a fix by submitting a Github pull request.





[JERSEY-2744] @Resource injection doesn't work when Jersey & CDI are used in standalone mode Created: 01/Jan/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: containers
Affects Version/s: 2.15
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Michal Gajdos Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

See PerApplicationBeanTest in cdi-webapp example. @Resource injection will not work on SE, need to add a custom extension to make this work with Grizzly.



 Comments   
Comment by Adam Lindenthal [ 14/Jan/15 ]

Moving to backlog.





[JERSEY-2747] Update Migration Guide Created: 05/Jan/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: docs
Affects Version/s: 2.14
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Michal Gajdos Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

By Guillaume Drouet:






[JERSEY-2754] JERSEY-2736: Impossible to define ConnectionReuseStrategy using ApacheConnector Created: 13/Jan/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: connectors
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Jakub Podlesak Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: ahc, apache
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to JERSEY-2583 Reuse of HttpClientContext in ApacheC... Open

 Description   

There is no way to define ConnectionReuseStrategy for Apache client (using ApacheConnector) through client config, and the fact that ApacheConnector is creating HttpClientBuilder with default value for boolean "systemProperties" (which is "false"), makes it impossible to use "http.keepAlive" system property.






[JERSEY-2758] Add support for nested generics to ConfigurableMoxyJsonProvider Created: 19/Jan/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: media
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: lasselassi Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: moxy, pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

When using Moxy to generate JSON responses, types with nested generics (e.g. Collection<TypeA<TybeB>>) do not work, leading to an error being logged:

ERROR [main] MessageBodyWriter not found for media type=application/json, type=class java.util.ArrayList, genericType=java.util.Collection<foo.TypeA<foo.TypeB>>. (at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:245))

This is a known Moxy issue with nested generics which has unfortunately been unresolved since July 2013: https://bugs.eclipse.org/bugs/show_bug.cgi?id=413809

I suspected issue JERSEY-2443 might be caused by the same problem.

We have successfully fixed this problem in production with a patched version of ConfigurableMoxyJsonProvider overwriting MOXyJsonProvider::getDomainClass, as described in the original Moxy issue (comment #2). This way there is no need to wait for this issue to be fixed in Moxy.

I have created a pull request: https://github.com/jersey/jersey/pull/134



 Comments   
Comment by Libor Kramolis [ 19/Jan/15 ]

Signed OCA submitted to 'oracle-ca_us@oracle.com' by Lasse. Waiting for confirmation by Oracle.

Comment by Libor Kramolis [ 28/Jan/15 ]

OCA confirmed.





[JERSEY-2762] Support Declarative Linking Annotations on Methods Created: 23/Jan/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: rpeterson Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: declarative-linking, pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently the @InjectLink and the @InjectLinks annotations have a @Target that is limited to types (Field & Type). In cases where the response object is an interface, and specifically an interface that is represented as a Proxy instance, the annotations can't be used since there are no field declarations on an interface.

This is a request to full support the annotations when they appear on the "getters" within the interface (assuming a corresponding setter is available).



 Comments   
Comment by rpeterson [ 23/Jan/15 ]

Pull Request has been created at https://github.com/jersey/jersey/pull/137





[JERSEY-2765] Add support for bean validation groups Created: 29/Jan/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: extensions
Affects Version/s: 2.15
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: brendan.doyle@intl.verizon.com Assignee: Unassigned
Resolution: Unresolved Votes: 2
Labels: bean-validation
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently Jersey does not support bean validation groups, (see here )

Can this feature be considered ?



 Comments   
Comment by Michal Gajdos [ 03/Feb/15 ]

Hi Brendan,

thank you for your suggestion. We'd certainly like to have support for Bean Validation groups - I'll try to estimate the effort and based on that we'll consider implementing it (but I guess it won't be available very soon). If you were willing to contribute such support let me know, we can try to do this together.

In the meantime - moving to backlog.

Michal

Comment by kheleniu [ 26/Nov/15 ]

Hi Michal,

I needed support for validation groups in our project so I made some small changes to Jersey bean-validation to support those. It's a bit dirty solution because it's done using ValidationInterceptor, but I could add the same logic to DefaultConfiguredValidator to make it cleaner and contribute a patch, if you would like to have this feature added. Actually it wasn't even that much of an effort after I figured out how the bean-validation works .

Kari





[JERSEY-2767] @Path regexp too greedy Created: 29/Jan/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.13
Fix Version/s: None

Type: Bug Priority: Major
Reporter: xwibao Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Oracle JDK 1.8.0_31
GlassFish v4.1 b13 nightly 12-15-2014



 Description   

Imagine we have the following REST resource. We want the @GET method handle URLs like both "/1" and "/1/foo", so we use a regexp in @Path:

    @GET
    @Path("/{id}{name: (/\\w+)?}")
    public String get(@PathParam("id") Long id, @PathParam("name") String name) {
        LOG.log(Level.INFO, "GET {0} {1}", new Object[]{id, name});
        return "Foo";
    }

    @DELETE
    @Path("/{id}")
    public void delete(@PathParam("id") Long id) {
        LOG.log(Level.INFO, "DELETE {0}", id);
    }

The @GET method works, but @DELETE gets broken (405 Method Not Allowed). Seems like @GET mapping shadows that of @DELETE, and the request is being routed to @GET handler despite HTTP method annotation.



 Comments   
Comment by xwibao [ 29/Jan/15 ]

Also tested on TomEE (CXF) and WildFly (RESTEasy) - works OK.

I've noticed some other minor differences:

  • if the optional part is present (ex. "/1/foo"), the "name" param value is:
    • TomEE: foo
    • GF: /foo
    • WF: /foo
  • if absent:
    • TomEE: null
    • GF: empty string
    • WF: empty string

If needed, I can supply a working NetBeans project (though I don't see how to attach files here)

Comment by Michal Gajdos [ 03/Feb/15 ]

Thank you for filing the issue, moving to backlog for now.





[JERSEY-2780] Provide option to opt out from MEDIA_TYPE_MAPPINGS Created: 09/Feb/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.11
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: Michael Osipov Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I have configured MEDIA_TYPE_MAPPINGS for my Jersey apps. Unfortunately, this causes some trouble with a generic upload service in my app.

@PUT
@Path("files/{filename}")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response uploadFile(
    @PathParam("filename") @NotNull @Size(max = 240) String filename, DataSource dataSource)

If someone uploads .../files/file.xml the extension is chopped of.

There should be some opt-out to this. Otherwise one has to disable this feature. This is what I did.

Here is the SO question for this.






[JERSEY-2785] Use StAX instead of SAX for JAXB Created: 11/Feb/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: media
Affects Version/s: 2.16
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: evnp Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: jaxb
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Is it possible to change SAXSource to StAX XMLInputFactory in org.glassfish.jersey.message.internal.XmlRootElementJaxbProvider?

JAXB RI use woodstox StAX implementation if possible because it has great perfomance advantages, so adding woodstox jar to classpath will increase XML marshalling and unmarshalling speed.



 Comments   
Comment by Michal Gajdos [ 18/Feb/15 ]

Can you, please, elaborate more? I mean can you point us to some performance overview of these two approaches?

Comment by evnp [ 19/Feb/15 ]

See http://stackoverflow.com/questions/11773649/java-xml-parser-performance-sun-java-streaming-xml-parser-sjsxp-vs-woodsto/11782775#11782775 for example. For my private xml data this is true: woodstox is faster than default stax implementation and aalto is bit faster than woodstox.





[JERSEY-2788] Stuck in loop in ResourceConfig.scanClasses Created: 12/Feb/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.15, 2.16
Fix Version/s: None

Type: Bug Priority: Major
Reporter: jstrom Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: osgi, scanning
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Jersey 2.15, and 2bc1fcb
Apache Karaf 3.0.3


Sprint: Triaged

 Description   

Hi,
I'm new with Jersey and I'm trying to run a jersey/grizzley based server in the Apache Karaf OSGI container.

In short, I have a resource directory with static files (well, only one so far) in the JAR. When ResourceConfig scans, it gets stuck in an infinite loop on this directory.

In long:

I have a pretty basic project, which fails to load. The relevant code is more or less from the tutorials:

log.info("Hello, starting!");
final ResourceConfig rc = new ResourceConfig().packages("testproject");
return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);

I use basic iPOJO component to get something runnable.
In addition, i have a directory with static files under "testproject/www".

During component activation, I get stuck inside createHttpServer forever:

Name: [iPOJO] pool-1-thread-1
State: RUNNABLE
Total blocked: 9  Total waited: 3

Stack trace: 
org.glassfish.jersey.server.ResourceConfig.scanClasses(ResourceConfig.java:905)
org.glassfish.jersey.server.ResourceConfig._getClasses(ResourceConfig.java:849)
org.glassfish.jersey.server.ResourceConfig.getClasses(ResourceConfig.java:755)
org.glassfish.jersey.server.ResourceConfig$RuntimeConfig.<init>(ResourceConfig.java:1184)
org.glassfish.jersey.server.ResourceConfig$RuntimeConfig.<init>(ResourceConfig.java:1157)
org.glassfish.jersey.server.ResourceConfig.createRuntimeConfig(ResourceConfig.java:1153)
org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:322)
org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:289)
org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.<init>(GrizzlyHttpContainer.java:331)
org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory.createHttpServer(GrizzlyHttpServerFactory.java:119)
asd.Main.startServer(Main.java:55)
asd.Main.__M_start(Main.java:89)
asd.Main.start(Main.java)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.apache.felix.ipojo.util.Callback.call(Callback.java:237)
org.apache.felix.ipojo.util.Callback.call(Callback.java:193)
org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallback.call(LifecycleCallback.java:86)
org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler.__M_stateChanged(LifecycleCallbackHandler.java:162)
org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler.stateChanged(LifecycleCallbackHandler.java)
org.apache.felix.ipojo.InstanceManager.setState(InstanceManager.java:560)
org.apache.felix.ipojo.InstanceManager.start(InstanceManager.java:440)
org.apache.felix.ipojo.ComponentFactory.createInstance(ComponentFactory.java:179)
org.apache.felix.ipojo.IPojoFactory.createComponentInstance(IPojoFactory.java:319)
   - locked org.apache.felix.ipojo.ComponentFactory@46737f42
org.apache.felix.ipojo.IPojoFactory.createComponentInstance(IPojoFactory.java:240)
org.apache.felix.ipojo.extender.internal.linker.ManagedType$InstanceSupport$1.call(ManagedType.java:312)
org.apache.felix.ipojo.extender.internal.linker.ManagedType$InstanceSupport$1.call(ManagedType.java:306)
org.apache.felix.ipojo.extender.internal.queue.JobInfoCallable.call(JobInfoCallable.java:114)
java.util.concurrent.FutureTask.run(FutureTask.java:262)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:745)

This was on jersey 2.15. I tried master, same issue. Modified the code a bit to see what's going on (patch against master):

index edc3c24..bd52cbd 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ResourceConfig.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ResourceConfig.java
@@ -887,6 +887,7 @@ public class ResourceConfig extends Application implements Configurable<Resource
             while (resourceFinder.hasNext()) {
                 final String next = resourceFinder.next();
                 if (afl.accept(next)) {
+                                                LOGGER.log(Level.INFO, "Loading resource "+next+" from finder "+rfs.getClass()+" -> " + rfs);
                     final InputStream in = resourceFinder.open();
                     try {
                         afl.process(next, in);
@@ -894,12 +895,14 @@ public class ResourceConfig extends Application implements Configurable<Resource
                         LOGGER.log(Level.WARNING, LocalizationMessages.RESOURCE_CONFIG_UNABLE_TO_PROCESS(next));
                     } finally {
                         try {
+                                                LOGGER.log(Level.INFO, "Closing instream for "+next);
                             in.close();
                         } catch (final IOException ex) {
                             LOGGER.log(Level.FINER, "Error closing resource stream.", ex);
                         }
                     }
-                }
+                }else
+                                                LOGGER.log(Level.INFO, "Not loading resource "+next+" from finder "+rfs.getClass()+" -> " + rfs);
             }
         }

This gives me the following output:

2015-02-12 14:42:15,170 | INFO  |  pool-1-thread-1 | Main                             | 146 - testproject - 1.0.0.SNAPSHOT | Hello, starting!
2015-02-12 14:42:15,170 | INFO  |  pool-1-thread-1 | ResourceConfig                   | 269 - org.glassfish.jersey.core.jersey-server - 2.16.0.SNAPSHOT | Not loading resource /asd/www/ from finder class java.util.HashSet -> [org.glassfish.jersey.server.internal.scanning.PackageNamesScanner@23b9b99d]
2015-02-12 14:42:15,170 | INFO  |  pool-1-thread-1 | ResourceConfig                   | 269 - org.glassfish.jersey.core.jersey-server - 2.16.0.SNAPSHOT | Not loading resource /asd/www/ from finder class java.util.HashSet -> [org.glassfish.jersey.server.internal.scanning.PackageNamesScanner@23b9b99d]
2015-02-12 14:42:15,171 | INFO  |  pool-1-thread-1 | ResourceConfig                   | 269 - org.glassfish.jersey.core.jersey-server - 2.16.0.SNAPSHOT | Not loading resource /asd/www/ from finder class java.util.HashSet -> [org.glassfish.jersey.server.internal.scanning.PackageNamesScanner@23b9b99d]

And on it goes.. forever, until JVM is killed. So, for some reason the ResourceFinder keeps giving me that directory over and over.

If i remove the www directory from my package, everything starts up perfectly fine.

As a side note, to anyone else trying to get OSGI/Jersey working: I kept getting the following exception:

java.lang.IllegalStateException: No generator was provided and there is no default generator registered
	at org.glassfish.hk2.internal.ServiceLocatorFactoryImpl.internalCreate(ServiceLocatorFactoryImpl.java:266)
	at org.glassfish.hk2.internal.ServiceLocatorFactoryImpl.create(ServiceLocatorFactoryImpl.java:230)
	at org.glassfish.jersey.internal.inject.Injections._createLocator(Injections.java:138)
	at org.glassfish.jersey.internal.inject.Injections.createLocator(Injections.java:123)
	at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:308)
	at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:289)
	at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.<init>(GrizzlyHttpContainer.java:331)
	at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory.createHttpServer(GrizzlyHttpServerFactory.java:119)

until I ensured that org.glassfish.hk2.locator was installed. In my maven-bundle-plugin instructions I added "<_include>src/main/resources/bundle.osgi</_include>", which contains "Require-Bundle: org.glassfish.hk2.locator".
Is there any better way to do this? Require-bundle seems non-recommended..



 Comments   
Comment by jstrom [ 12/Feb/15 ]

Oops, log output above says "Not loading resource /asd/www/"... I missed to rewrite that part in the issue text (in the rest of the text I changed "asd" to "testproject", to avoid confusion about "asd". that fired back!)

Comment by jstrom [ 12/Feb/15 ]

After some additional testing, it seems that it fails if the scanned prefix contains any HTML files.
Some tested scenarios:

Fails:
new ResourceConfig().packages("testproject")
/testproject/Main.class
/testproject/index.html

Fails:
new ResourceConfig().packages("testproject")
/testproject/Main.class
/testproject/index.html

Fails:
new ResourceConfig().packages("testproject")
/testproject/Main.class
/testproject/www/index.html

Works:
new ResourceConfig().packages("testproject.src")
/testproject/src/Main.class
/testproject/www/index.html

Works:
new ResourceConfig().packages("testproject")
/testproject/Main.class
/www/index.html

So.. Basically it seems I can not have any .html files in the path which is scanned?
It's easy to avoid though, just keep code in "com.example.project" and HTML resources in "www" (in a particular JAR). Keeping resources under com.example.project.www would fail though (but not sure if that is common practice or not).

For the record, this did not occur when running in standalone mode (with static main() as from the tutorials).

Comment by jstrom [ 18/Feb/15 ]

I've done some more debugging, and verified this is also a problem on 2.16 (and 2.17-SNAPSHOT @ b2424a3). I've noticed that it may hang on plain directories as well, even if they have class files in them.
The actual hang boils down to this:

  1. scanClasses calls hasNext() on the ResourceFinder, in this case a BundleSchemeResourceFinder.
  2. BundleSchemeResourceFinder.hasNext will return true if an internal boolean "accessed" is false.
  3. If the AnnotationAcceptingListener does accept the resource, it calls open() on the resourceFinder, else it continues with another round of hasNext().
  4. in BundleSchemeResourceFinder, if open() is called, accessed is set to true.
  5. Since open() is never called, accessed will always be false and we are stuck in a loop.

In my case, there are a bunch of BundleSchemeResourceFinder instances added to the resource stack. These are added from ResourceConfig.init(), which eventually delegates to osgiRegistry.getPackageResources to find any resources in my bundle.
In OsgiRegistry.getPackageResources (with some extra logging added), the call to findEntries (with recurse=false) results in this:

Looking for package asd in asd [154]
  found entry /asd/BasicApiResource.class => asd.BasicApiResource at bundle://154.0:0/asd/BasicApiResource.class
  found entry /asd/Main.class => asd.Main at bundle://154.0:0/asd/Main.class
.. some more classes...
  found entry /asd/TestExceptionMapper.class => asd.TestExceptionMapper at bundle://154.0:0/asd/TestExceptionMapper.class
  found entry /asd/x/ => asd. at bundle://154.0:0/asd/x/

The /asd/x directory has a few other resources, but since findEntries is non-recursive, it only returns the directory.

A working workaround is to make sure that any directory which is scanned, does not have any subdirectories. For example, ensure all resources are located in asd.resources and have nothing but .class files there.

Comment by jstrom [ 18/Feb/15 ]

(Oh, and a side note to any future google references to "No generator was provided and there is no default generator registered", it seems to be very important that the org.glassfish.hk2.osgi-resource-locator bundle is loaded before anything else (more likely, before org.glassfish.hk2.locator). Ensure this happens by setting the start-level of this bundle to a lower value than the rest. In Karaf/Felix, it can be done with bundle:start-level org.glassfish.hk2.osgi-resource-locator 70.)

Comment by jstrom [ 18/Feb/15 ]

Another gotcha with regards to OSGI scanning: On container startup, it will not always find my resources (getPackageResources's call to bundleContext.getBundles() returns no bundles).
Workaround: ensures start-level for the application is higher jersey bundles.

Comment by Michal Gajdos [ 18/Feb/15 ]

Thank you for a very detailed description and analysis, moving to backlog for now (we should be able to look into this soon).





[JERSEY-2798] Document performance penality introduced by DataSource Provider Created: 18/Feb/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: docs, performance
Affects Version/s: 2.16
Fix Version/s: None

Type: Task Priority: Major
Reporter: Michael Osipov Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Document that the DataSource implementation used by Jersey is backed by a byte array. That might introduce a huge performance/memory penality when huge data is processed.

In my case, a client can upstream large files (hundreds of megabytes), I requested Jersey to provide a DataSource. Memory exploded. I resorted to an inputStream with a custom InputStreamDataSource in the backend. That sovled the issue.






[JERSEY-2804] Deadlock in Apache HTTP client for basic non-preemptive authentication Created: 25/Feb/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: connectors, core
Affects Version/s: 2.16
Fix Version/s: None

Type: Bug Priority: Major
Reporter: mario.casola Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Linux ubuntu 13.10, tomcat 7.0.57, jdk 1.7.0_71 64 bit


Attachments: Zip Archive jersey-non-preemptive-auth.zip    

 Description   

I wanna share my experience about an issue that I encountered. The scenario is the following:

1. jersey client
2. http client connection manager
3. apache connection provider
4. basic non-preemptive authentication

the problem was that in some cases the connection was not released like expected, like the log below shows

2015-02-25 19:26:06.488 DEBUG 13230 --- [nio-8181-exec-9] h.i.c.PoolingHttpClientConnectionManager : Connection released: [id: 0][route: {}->http://localhost:8080][total kept alive: 1; route allocated: 1 of 10; total allocated: 1 of 10]
  • Example that works in both cases, successful http code or not
rootTarget.queryParam("sort", sort + "," + dir)
	.queryParam("size" + Integer.MAX_VALUE)
	.request(MediaType.APPLICATION_JSON_TYPE).get(String.class);
  • Example that works only if the request is unsuccessful
return rootTarget
	.request(MediaType.WILDCARD_TYPE)
	.post(Entity.entity(myobject, MediaType.APPLICATION_JSON_TYPE),
			MyCustomClass.class);
  • Example that doesn't work at all
Response r = null;
try {
	r = idTarget.request(MediaType.WILDCARD_TYPE)
			.put(Entity.entity(myobject, MediaType.APPLICATION_JSON_TYPE));
	if (r.getStatusInfo().getStatusCode() != Status.NO_CONTENT
			.getStatusCode()) {
		throw new InternalServerErrorException(r.getStatusInfo()
				.getReasonPhrase());
	}
} finally {
	if (r != null) {
		try {
			r.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

This last example works only if I consume the response body like string. Response.close() doesn't work.

Instead If I change the authentication to preemptive mode everything works fine.

Best regards
Mario Casola



 Comments   
Comment by Adam Lindenthal [ 11/Mar/15 ]

Hi Mario,

could you please share the code where you configure the client? Or, ideally provide a minimal reproducer testcase, e.g. buildable and runnable by maven?

Thanks a lot,
Adam

Comment by mario.casola [ 11/Mar/15 ]

Hi Adam,

at the following link you can download a maven project to test the issue

https://www.dropbox.com/s/dhgr4t5tt0j4g6q/jersey-non-preemptive-auth.zip?dl=0

Max connection per route 5

[WORKING]

$ mvn -DnonPreemptive=false -DconsumeString=true -Dexception=true test
$ mvn -DnonPreemptive=false -DconsumeString=false -Dexception=true test

2015-03-12 00:02:06.890 DEBUG 8504 --- [           main] h.i.c.PoolingHttpClientConnectionManager : Connection released: [id: 5][route: {}->http://localhost:8080][total kept alive: 0; route allocated: 0 of 5; total allocated: 0 of 10]

$ mvn -DnonPreemptive=false -DconsumeString=false -Dexception=false test
$ mvn -DnonPreemptive=false -DconsumeString=true -Dexception=false test

2015-03-12 00:03:05.015 DEBUG 8582 --- [           main] o.a.http.impl.execchain.MainClientExec   : Connection can be kept alive indefinitely
2015-03-12 00:03:05.016 DEBUG 8582 --- [           main] h.i.c.PoolingHttpClientConnectionManager : Connection [id: 0][route: {}->http://localhost:8080] can be kept alive indefinitely
2015-03-12 00:03:05.017 DEBUG 8582 --- [           main] h.i.c.PoolingHttpClientConnectionManager : Connection released: [id: 0][route: {}->http://localhost:8080][total kept alive: 1; route allocated: 1 of 5; total allocated: 1 of 10]

[NOT WORKING]

$ mvn -DnonPreemptive=true -DconsumeString=true -Dexception=true test
$ mvn -DnonPreemptive=true -DconsumeString=false -Dexception=true test
$ mvn -DnonPreemptive=true -DconsumeString=true -Dexception=false test
$ mvn -DnonPreemptive=true -DconsumeString=false -Dexception=false test

blocked

2015-03-11 23:42:39.717 DEBUG 7710 --- [           main] h.i.c.PoolingHttpClientConnectionManager : Connection request: [route: {}->http://localhost:8080][total kept alive: 0; route allocated: 5 of 5; total allocated: 5 of 10]

At the end doesn't seems to be a question between consuming String or a custom Object. Another aspect is if you remove the response body on http return code that is not SUCCESSFUL. In that case even with non preemptive authentication it works.

I hope this helps

regards
Mario

Comment by Adam Lindenthal [ 11/Mar/15 ]

Thanks, Mario.
I've attached your example to the issue. We will look at it and decide if someone knows what's wrong or if we plan some work on for future sprints.

Adam

Comment by Jakub Podlesak [ 23/Mar/15 ]

There does not seem to be an issue with client.close(). Try to place the following to the beginning of your test method:

            Executors.newFixedThreadPool(1).submit(new Runnable(){

                @Override
                public void run() {
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    restClient.close();
                }
            })

In the original test case, the restClient.close() was never invoked!

Comment by Jakub Podlesak [ 23/Mar/15 ]
	at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
	at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
	at org.apache.http.pool.PoolEntryFuture.await(PoolEntryFuture.java:133)
	at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:282)
	at org.apache.http.pool.AbstractConnPool.access$000(AbstractConnPool.java:64)
	at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:177)
	at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:170)
	at org.apache.http.pool.PoolEntryFuture.get(PoolEntryFuture.java:102)
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:244)
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:231)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:173)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:72)
	at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:455)
	at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:246)
	at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:667)
	at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:664)
	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.process(Errors.java:228)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
	at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:664)
	at org.glassfish.jersey.client.authentication.HttpAuthenticationFilter.repeatRequest(HttpAuthenticationFilter.java:334)
	at org.glassfish.jersey.client.authentication.BasicAuthenticator.filterResponseAndAuthenticate(BasicAuthenticator.java:125)
	at org.glassfish.jersey.client.authentication.HttpAuthenticationFilter.filter(HttpAuthenticationFilter.java:250)
	at org.glassfish.jersey.client.ClientFilteringStages$ResponseFilterStage.apply(ClientFilteringStages.java:134)
	at org.glassfish.jersey.client.ClientFilteringStages$ResponseFilterStage.apply(ClientFilteringStages.java:123)
	at org.glassfish.jersey.process.internal.Stages.process(Stages.java:171)
	at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:251)
	at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:683)
	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.process(Errors.java:228)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444)
	at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:679)
	at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:408)
	at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:308)
	at jersey.test.JerseyClientTest.test(JerseyClientTest.java:96)
Comment by Jakub Podlesak [ 23/Mar/15 ]

Updated bug title to describe the real issue.
Added stack trace that captures where the deadlock happens.

Moved to backlog.

Comment by mario.casola [ 23/Mar/15 ]

Hi Jakub,

good to know that you found the real issue. I didn't call the close method on restClient (javax.ws.rs.client.Client) object because in a real webapp I never call that method. On webapp shutdown spring call the close() method for me.
The method consumeTarget.request(MediaType.APPLICATION_JSON_TYPE).get(cls) should read the entity and call the method close on Response object.

thanks
Mario

Comment by Jakub Podlesak [ 24/Mar/15 ]

Understood, it was not the client but the response which you wanted to close. Anyway, the deadlock prevents any close attempt,
even if it is placed in a finally block. We need to address the deadlock first.





[JERSEY-2815] Add support for Optional from Java 8 into Jersey Created: 04/Mar/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: extensions
Affects Version/s: 2.16
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Michal Gajdos Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

We're currently able to support some of the types from Java 8 in Jersey (extension module). Create infrastructure for this extension module and add support for Optional (entity, param).






[JERSEY-2825] MOXyJsonProvider cannot unmarshall JSON arrays into custom collection types Created: 16/Mar/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: media
Affects Version/s: 2.18
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Michal Gajdos Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Sprint: Triaged

 Description   

Note: This is a problem in MOXy 2.6. It's filed against Jersey just to track the progress and the issue should be closed when new MOXy is integrated into Jersey.

Consider you have this JSON:

[{"jaxbBean":{"value":"one"}},{"jaxbBean":{"value":"two"}},{"jaxbBean":{"value":"three"}}]

Resource Method like:

@POST
@Path("custom")
public MyArrayList<JaxbBean> postCustom(final MyArrayList<JaxbBean> l) {
    return l;
}

Where MyArrayList looks like:

public class MyArrayList<T> extends ArrayList<T> {

    public MyArrayList() {
    }

    public MyArrayList(final Collection<T> a) {
        super(a);
    }

}

The JSON is unmarshalled as list of lists (MyArrayList of MyArrayLists) but JaxbBeans are not in unmarshalled object.



 Comments   
Comment by Libor Kramolis [ 04/Jan/16 ]

It seems it is already fixed in MOXy 2.6.1 (https://bugs.eclipse.org/bugs/show_bug.cgi?id=462321).

Jersey should use the latest MOXy release.





[JERSEY-2828] "Jersey bean validation" does not validate @PathParam on sub resource location Created: 20/Mar/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: extensions
Affects Version/s: 2.14
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Maxonchik Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Thare is no validation on sub resource location.

For example:

@Path("{resourceId}/action")
public ActionResource actionController(@PathParam("resourceId") @PathId @Pattern(regexp = "\\d{1,10}") String resourceId) {
        ....
}

parameter "resourceId" will not be validated



 Comments   
Comment by Libor Kramolis [ 04/Jan/16 ]

Please provide reproducible test case and try it with the latest Jersey release. There where big improvement with Jersey and Validation support.





[JERSEY-2835] Add new ApacheClientProperties.DISABLE_AUTOMATIC_RETRIES flag Created: 07/Apr/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: connectors
Affects Version/s: 2.17
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: khaing211 Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to JERSEY-2139 The org.glassfish.jersey.apache.conne... Open

 Description   

Add new ApacheClientProperties.DISABLE_AUTOMATIC_RETRIES flag
Calling HttpClientBuilder#disableAutomaticRetries



 Comments   
Comment by Adam Lindenthal [ 05/Aug/15 ]

Hi, thanks for reporting the issue/improvement suggestion.
I will put it to backlog, so that we can take a look at it later on.

Thanks,
Adam

Comment by Adam Lindenthal [ 27/Nov/15 ]

https://github.com/jersey/jersey/pull/161





[JERSEY-2842] Improve error when http response is written Created: 17/Apr/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: containers
Affects Version/s: 2.16
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: sebadiaz Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: incomplete, pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

all



 Description   

need to return the response in sending the actual response.

java.lang.IllegalArgumentException: setContentLength(0) when already written 159
at org.eclipse.jetty.server.Response.setContentLength(Response.java:990)
at org.glassfish.jersey.servlet.internal.ResponseWriter.writeResponseStatusAndHeaders(ResponseWriter.java:142)
at org.glassfish.jersey.server.ServerRuntime$Responder$1.getOutputStream(ServerRuntime.java:611)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:200)
at org.glassfish.jersey.message.internal.CommittingOutputStream.flushBuffer(CommittingOutputStream.java:305)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commit(CommittingOutputStream.java:261)
at org.glassfish.jersey.message.internal.CommittingOutputStream.close(CommittingOutputStream.java:276)
at org.glassfish.jersey.message.internal.OutboundMessageContext.close(OutboundMessageContext.java:834)
at org.glassfish.jersey.server.ContainerResponse.close(ContainerResponse.java:411)
at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:691)



 Comments   
Comment by Adam Lindenthal [ 15/May/15 ]

Hi sebediaz,

could you please provide something more than an exception? A reproducer test case with certain behaviour and describing what you would improve on the behaviour would be nice.

Thanks,
Adam

Comment by Adam Lindenthal [ 03/Jul/15 ]

Hi sebediaz,

just a kindly reminder. Could you please elaborate on the description a bit more?

Thanks,
Adam

Comment by sebadiaz [ 13/Jul/15 ]

Hi

Sometime, we can use a context for response. as @Context HttpServletResponse in the method or object attribute. The issue arrive in this case. In giving the access of the response , we can 't manage undesirable issues as data writing or different return on response status. We cannot on a server as jersey or tomcat, obtain a non mutable response class for reading. In this case just jersey can manage in preventing writing on bufffer when the buffer is sent or writted and giving a clear message

regards

sebastien diaz

Comment by Adam Lindenthal [ 07/Aug/15 ]

https://github.com/jersey/jersey/pull/158

Comment by Adam Lindenthal [ 13/Aug/15 ]

As this issue has ongoing pull request, moving to backlog until it is processed.





[JERSEY-2849] @BeanParam injection behavior changed with 2.17 Created: 30/Apr/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.17
Fix Version/s: None

Type: Bug Priority: Major
Reporter: vguna Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Jersey 2.17, JDK 1.7.0_55-b13 64 bit, Tomcat 7.0.21, Windows 7


Attachments: Zip Archive test.zip    
Issue Links:
Related
is related to JERSEY-2890 CLONE - Tomcat memory leak on undeploy Resolved
Sprint: Triaged

 Description   

Hi.

We're using Jersey 2.16 with JDK 1.7.0_55-b13 64 bit and Tomcat 7.0.21 under Windows 7 to build a REST api.
Now, we're facing a problem with memory usage during load. We've created a TestNG testcase method, that
performs CRUD operations 10 times in a loop. That method is invoked 1000 times by 50 concurrent threads.

After approx. 30 minutes, the server gets slower and slower until it gets an OutOfMemoryException. We
created a ThreadDump with jvisualvm and used Eclipse Memory Analyzer to get to the root problem.

It seems that hk2's SystemDescriptor is eating memory like a boss . Here's the output of the analyzer:

170.088 instances of "org.jvnet.hk2.internal.SystemDescriptor",
loaded by "org.apache.catalina.loader.WebappClassLoader @ 0xc026bd80"
occupy 625.581.408 (92,47%) bytes.
These instances are referenced from one instance of "org.jvnet.hk2.internal.ServiceLocatorImpl",
loaded by "org.apache.catalina.loader.WebappClassLoader @ 0xc026bd80"

We already found an old JIRA ticket regarding a SystemDescriptor memory leak:

https://java.net/jira/browse/HK2-205[https://java.net/jira/browse/HK2-205]

that was fixed in 2.3.0.

So we switched to the latest hk2 version, 2.4.0-b16. But without any effect.

---------

Meanwhile we came to the same results as reported here:

https://java.net/jira/browse/JERSEY-2800

It also got filled up with @BeanParams classes.

Then we switched to 2.17 and found out, that the @BeanParam class (PathContext) is missing some functionality.
It looks like that:

public class PathContext {

@PathParam(TenantResource.TENANT_ID_PATH_PARAM)
private String tenantId;
@PathParam(AccountResource.ACCOUNT_ID_PATH_PARAM)
private String accountId;
@PathParam(RepositoryResource.REPOSITORY_ID_PATH_PARAM)
private String repositoryId;
@PathParam(RepositoryEntryResource.REPOSITORY_ENTRY_ID_PATH_PARAM)
private String repositoryEntryId;
....

With 2.16 and prior, Calling a URL like this:

http://localhost:8080/something/api/1/tenants/b38c7e6b-f17f-45bf-a746-65b40f95d845/repositories/1ee83a90-6e2f-435c-ac6a-ece0f5106671/entries

Resulted into filled tenantId and repositoryId.

Now, only tenantId is filled - although repositoryId should also be accessible.
I can also confirm, that now only one instance of PathContext is created (using @PostConstruct).
With 2.16 it were 3: 1st with only tenantId set, the other 2 instances had repositoryId correctly set.

PathContext is injected into different resources as field member. Resources are accessed via Subresourcelocators.
So I'm wondering if the fix from JERSEY-2800 maybe broke some other stuff?

I would expect, if I inject the PathContext anywhere, it should parse the complete URL for the specified @PathParams.
This didn't seem to happen anymore.


Please find attached a small testcase that shows the problem.
It's quite ugly (I reused it from an Apache CXF testcase), but should be enough for demonstration.

It's a maven project that includes a war. If you execute "mvn clean install", it will automatically
start a tomcat container via cargo, deploys the war, and execute the JerseyIT test.

The test itself simply invokes an endpoint (RepositoryEntryResourceImpl)
and sends an entryId to it (url: http://localhost:8080/test/api/repositories/0815/entries/0816).

The endpoint reads from the injected PathContext the entryId and returns it to the testcase. It expects that
0816 is returned.

It should work with 2.16. If you change the version to 2.17 in the pom, it should fail with a null
returned from the endpoint.

If you take a look at the server log, the following is shown:

2.16:

Apr 29, 2015 5:54:55 PM test.PathContext postConstruct
INFO: hashCode: 556592017, repositoryId: 0815, entryId: null

Apr 29, 2015 5:54:55 PM test.PathContext postConstruct
INFO: hashCode: 29437898, repositoryId: 0815, entryId: 0816

Apr 29, 2015 5:54:55 PM test.RepositoryEntryResourceImpl getEntry
INFO: injected pathContext: hashCode: 29437898, repositoryId: 0815, entryId: 0816

Actually PathContext is created twice. Once for every endpoint. The 2nd instance
(for RepositoryEntryResourceImpl) now contains the correct entryId.

2.17:

Apr 29, 2015 5:58:28 PM test.PathContext postConstruct
INFO: hashCode: 1730327498, repositoryId: 0815, entryId: null

Apr 29, 2015 5:58:28 PM test.RepositoryEntryResourceImpl getEntry
INFO: injected pathContext: hashCode: 1730327498, repositoryId: 0815, entryId: null

Here, PathContext is only created once. Same instance is injected only once
into the different endpoints. Also entryId is null.

I hope that helps tracking down the problem.



 Comments   
Comment by vguna [ 30/Apr/15 ]

Marek told me to create an issue. But after I created it, the title doesn't reflect the real problem. Sadly, I can't edit the title nor the text anymore . I also can't attach the promised test project.

To be clear: the memory leak is fixed with 2.17. But @BeanParam doesn't work as before. So simply skip the first "chapter" .

Comment by Marek Potociar [ 06/May/15 ]

Attaching the test provided by the filer.

Comment by vguna [ 22/Jun/15 ]

Any news on this? Is any additional information needed?

Comment by Adam Lindenthal [ 10/Aug/15 ]

Hi vguna, not yet, but there have been some changes made on the hk2 side that we are going to test before upgrade. Those changes might actually resolve the linked issue as well as this one.
In the mean time, I will move the issue to backlog.

Regards,
Adam

Comment by vguna [ 16/Nov/15 ]

Hi.

I've re-tried this with 2.22.1 but with the same result .
Any news on this?





[JERSEY-2853] OAuth1 client does not include non-POST 'application/x-www-form-urlencoded' form entity-body parameters in OAuth1 signature base string Created: 05/May/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: security
Affects Version/s: 2.17
Fix Version/s: None

Type: Bug Priority: Major
Reporter: unserializable Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: oauth, oauth1, oauth1-client

 Description   

Pull request with a fix and detailed comments @: https://github.com/jersey/jersey/pull/160

Gist of the Jersey oauth1-client implementation is usage of very old oauth-core convention which effectively request entity body signatures and their validation for non-POST requests with 'application/x-www-form-urlencoded' request entity bodies (only query parameters included in the signature thing).



 Comments   
Comment by unserializable [ 05/May/15 ]

^^ /convention which effectively request entity body signatures/ ^^
upwards in bug description should have read:
/convention which effectively DISABLES request entity body signatures/

Comment by Adam Lindenthal [ 15/May/15 ]

Hi unserializable,

thanks for reporting and for the pull request. I will move the issue to backlog, as we are waiting for the OCA to be sent and processed and the patch to be reviewed and merged.

Thanks,
Adam





[JERSEY-2859] NullPointerException when SecurityEntityFilteringFeature enabled Created: 12/May/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: extensions, security
Affects Version/s: 2.17
Fix Version/s: None

Type: Bug Priority: Major
Reporter: raphael_c Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: incomplete
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hi,

I enabled SecurityEntityFilteringFeature. When I test a 406 due to a not supported media-type I get a NullPointerException thrown by ServerScopeProvider.getFilteringScopes because the getMatchedMethods() returns a null

for (final ResourceMethod method : ServerScopeProvider.getMatchedMethods(uriInfo)) {
                final Invocable invocable = method.getInvocable();

                mergeFilteringScopes(filteringScope,
                        getFilteringScopes(invocable.getHandlingMethod(), invocable.getHandler().getHandlerClass()));

                if (!filteringScope.isEmpty()) {
                    uriToContexts.putIfAbsent(path, filteringScope);
                    return filteringScope;
                }
            }

How can I tell Jersey to execute this feature only if I return a 200



 Comments   
Comment by Adam Lindenthal [ 10/Aug/15 ]

Thanks for reporting. This indeed looks like a bug. Putting it to backlog.

Regards,
Adam

Comment by Libor Kramolis [ 04/Jan/16 ]

Please provide reproducible test case.

Comment by raphael_c [ 05/Jan/16 ]

Hi,

To reproduce this you need a jersey application with the module declared in your ResourceConfig, then write a simple GET resource consuming only text/plain.

Once your app is running, invoke the simple resource with a different media-type. The app detects the wrong media-type then return a 406 which is intercepted by the plugin and causes the following error.

Tell me if you want more details.

Regards,

Comment by Libor Kramolis [ 05/Jan/16 ]

Could you provide running JerseyTest simple app?





[JERSEY-2864] HttpAuthenticationFeature should have a callback mechanism to get credentials Created: 14/May/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: security
Affects Version/s: 2.17
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: Scott Palmer Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

all



 Description   

Instead of configuring the credentials directly on the HttpAuthenticationFeature you should be able to provide a callback. That way, in pre-emptive mode, the credentials can be obtained by asking the user for them on-demand. The HttpAuthenticationFeature should then cache them for the given authentication realm.

I currently implement this with my own ClientRequestFilter that adds the authorization header from a cache of credentials, and a reflection-based proxy in my client that intercepts the 401 status, populates the credentials cache via a callback (where I can present a GUI), then retries the call. It works, but it is the sort of thing that should be built-in if you ask me.



 Comments   
Comment by Adam Lindenthal [ 11/Aug/15 ]

Hi Scott, thanks for the suggestion, we agree that the feature would be useful. I am moving the ticket to backlog, so that we can eventually work on it in one of the future sprints.

Regards,
Adam





[JERSEY-2868] MoxyObjectProvider does not handle classes with instance variables of same type correctly Created: 20/May/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: media
Affects Version/s: 2.17
Fix Version/s: None

Type: Bug Priority: Major
Reporter: jdn Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Using Jersey 2.17, running on Grizzly, using the Moxy to marshal to and from JSON. Running a resource with @Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)



 Description   

There seems to be a bug in how the MoxyObjectProvider breaks cycles in the object graph.

I think the bug is related to this code in the createSubgraphs(String, Subgraph, Class<?>, Map<String, ObjectGraph>, Set<String> processed) method (line 123):

  final String processedSubgraph = getProcessedSubgraph(entityClass, fieldName, subEntityClass);

            if (!subgraphs.isEmpty() && !processed.contains(processedSubgraph)) {
                processed.add(processedSubgraph);
                createSubgraphs(path, subgraph, subEntityClass, subgraphs, processed);
            } 

I have a class looking like this:

public class Foo {

	private Bar a;
	private Bar b;
	private Bar c;
}

All classes are with the appropriate getters, setters, and zero args constructor.

Bar looks like this:

public class Bar {

	private Baz k1;
}

Baz looks like this:

public class Baz {

	private Boz boz;
	private String s;
 }

Boz:

public class Boz {
	private int a;
}

In this case the Bar instances are only serialised properly for the first encountered instance, the two other does not serialise properly as the string "Bar_k1_Baz" is now appearing in the processed set, and thus resulting in the other subgraphs getting ignored. This will later result in Moxy not generating the subgraphs. The result is below.

{
   "a" : {
      "k1" : {
         "s" : "string A"
      }
   },
   "b" : {
      "k1" : {
         "s" : "string B"
      }
   },
   "c" : {
      "k1" : {
         "boz" : {
            "a" : 24
         },
         "s" : "string C"
      }
   }
} 


 Comments   
Comment by Iaroslav Savytskyi [ 26/May/15 ]

Can you please provide part of java code where you instantiate and fill Foo with other objects?

Comment by jdn [ 26/May/15 ]
@Path("bug/")
public class BugResource {

	@POST
	@PermitAll
	@Consumes(MediaType.APPLICATION_JSON)
	@Produces(MediaType.APPLICATION_JSON)
	public Foo createOrganization() {

		Foo foo = new Foo();

		Bar b = new Bar();
		Baz bazB = this.createBaz("String B");
		b.setK1(bazB);
		foo.setB(b);

		Bar c = new Bar();
		Baz bazC = this.createBaz("String C");
		c.setK1(bazC);
		foo.setC(c);

		Bar a = new Bar();
		Baz bazA = this.createBaz("String A");
		a.setK1(bazA);
		foo.setA(a);

		return foo;
	}

	private Baz createBaz(String s) {
		Boz boz = new Boz();
		Baz baz = new Baz();
		baz.setBoz(boz);
		baz.setS(s);
		return baz;
	}
}

What is the preferred way to share/format code?

Comment by jdn [ 03/Jun/15 ]

Any comments...

Comment by Adam Lindenthal [ 11/Aug/15 ]

Hi jdn, thanks for reporting this. I will move the issue to backlog, so that we can take a look at it in one of the future sprints.

Regards,
Adam





[JERSEY-2872] ConnectionCallback does not fire when client dropped a connection Created: 28/May/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: containers
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: weichengpan Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Comments   
Comment by weichengpan [ 28/May/15 ]

Hi, I have a use case to execute expensive computations,
and I would like to check if connection is drop or not before executing expensive computation.

It'll be great if the callback fired when client dropped, not at the time when writing something to ChunkedOutput.

AsyncResource.java
@Path("/async/Expensive")
@Singleton
public class AsyncResource {
    @Context ExecutorService executorService;
    @Context BusinessLogic businessLogic;
    static Logger logger = LoggerFactory.getLogger(AsyncResource.class);

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @ManagedAsync
    public void getExpensive (
        @PathParam("value") Integer value,
        @Suspended final AsyncResponse res) {
        final Future<?> submit;

        submit = executorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    res.resume(businessLogic.getExpensive(value));
                } catch (InterruptedException e) {
                }
            }
        });

        res.register(new ConnectionCallback() {
            @Override
            public void onDisconnect(AsyncResponse disconnected) {
                submit.cancel(false);
            }
        });
    }
Comment by Adam Lindenthal [ 07/Aug/15 ]

Hi, thanks for submitting the improvement idea.
I am not sure if we can detect the disconnect earlier, but it would be nice. I will move it to backlog, so that we can take a look at it later on.

Regards,
Adam





[JERSEY-2882] Jersey-client: No way to put non-retryable with digest auth Created: 10/Jun/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: connectors
Affects Version/s: 2.17
Fix Version/s: None

Type: Bug Priority: Major
Reporter: sammefford Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

java 1.8, Win8.1



 Description   

I see no way to put a stream or other non-retryable payload while using DIGEST auth. This is something we could do with Jersey 1.17 client.

Since digest requires a challenge-response, we have two choices for non-retryable payloads:
1) buffer the stream and send it with both the first and second request
2) make a separate auth-only request first to get the Authorization token then use it to put the non-retryable payload

I see no way to do either using Jersey/Jax-RS 2.17, even when using httpclient as the connector. httpclient offers AuthCache but I see no way to access that via Jersey/JAX-RS.

Am I right to consider it a MUST requirement for Jersey/JAX-RS to support digest auth and non-retryable payloads (such as InputStream)?

Here's the code that fails with "IOException: Stream closed". I'm testing it against MarkLogic server but any web service which supports digest would have the same problem.

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.RequestEntityProcessing;

import java.io.StringReader;

public class Jersey217Test {
    public static void main(String[] args) {
        String user = "admin";
        String pass = "admin";
        ClientConfig clientConfig = new ClientConfig();
        clientConfig.property(ClientProperties.REQUEST_ENTITY_PROCESSING,  RequestEntityProcessing.BUFFERED);
        Client client = ClientBuilder.newClient(clientConfig);
        client.register(HttpAuthenticationFeature.digest(user, pass));
        StringReader reader = new StringReader("test");
        WebTarget connection = client.target("http://localhost:8000/v1/documents");
        connection
            .queryParam("uri", "test.txt")
            .request((String) null)
            .put(Entity.entity(reader, "text/plain"));
        Response response = connection
            .queryParam("uri", "test.txt")
            .request("text/plain").get();
        String body = response.readEntity(String.class);
        System.out.println("Body=[" + body + "]");
    }
}


 Comments   
Comment by sammefford [ 15/Jun/15 ]

Here's a follow-up. I found a work-around but it's not what I need. If I use the same WebTarget it looks like follow-up requests are authenticated:

public class Jersey217Test {
    public static void main(String[] args) {
        String user = "admin";
        String pass = "admin";
        String baseUri = "http://localhost:8000/v1/";

        ClientConfig clientConfig = new ClientConfig();

        Client client = ClientBuilder.newClient(clientConfig);
        client.register(HttpAuthenticationFeature.digest(user, pass));
        StringReader reader = new StringReader("test");
        WebTarget base = client.target(baseUri).path("documents")
            .queryParam("uri", "test.txt");
        Response response = base
            .request(MediaType.MEDIA_TYPE_WILDCARD)
            .head();
        response.close();
        response = base
            .request(MediaType.MEDIA_TYPE_WILDCARD)
            .put(Entity.entity(reader, "text/plain"));
        response.close();
        response = base
            .request("text/plain").get();
        String body = response.readEntity(String.class);
        System.out.println("Body=[" + body + "]");
    }
}

The problem is that any method that generates a new WebTarget (such as queryParam) loses the authentication. So I'm seeing no viable way to authenticate once then make multiple requests with the same authentication. More specifically, I see no way to make an auth-only request prior to a non-retryable put method request unless the auth-only request can match exactly the url of the non-retryable request which is not always going to work in my scenario.

Comment by sammefford [ 11/Aug/15 ]

Ping. Is there anyone that can look at this? This bug is a blocker for us. It is preventing us from upgrading to Jersey 2.

Comment by Adam Lindenthal [ 13/Aug/15 ]

Hi, thanks for reporting the issue.
I am moving it to backlog, so that we can take a look at it in one of the future sprints.

Regards,
Adam

Comment by sammefford [ 14/Sep/15 ]

I wanted to check in and see if any progress can be made on this issue. We have users that want us to upgrade to Jersey 2, but I can't see how without resolving this issue.





[JERSEY-2883] Refactor Jersey Proxy Client Created: 10/Jun/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core, extensions
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: walec51 Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently its implementation is somewhat big blob like method which dosen't even follow good practices of structural code.

We should divide its functionality in a more OOP like manner befor expanding it.

I'll prepare a pull request suggesting the direction I would like to take.



 Comments   
Comment by Adam Lindenthal [ 06/Aug/15 ]

Hi, thanks for creating the jira ticket and for your readiness to create a pull request, it will be welcome.
If you didn't contributed to Jersey yet, you might find this reading useful: https://jersey.java.net/scm.html

Thanks,
Adam

Comment by Adam Lindenthal [ 06/Aug/15 ]

In the meantime, I will put the issue to backlog.





[JERSEY-2887] Add the support of the @Resource annotation to the Spring3 extension Created: 12/Jun/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: extensions
Affects Version/s: 2.18
Fix Version/s: None

Type: New Feature Priority: Major
Reporter: olivier.billiard Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: spring
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: spring3

 Description   

At the moment only the Autowire annotation is supported by the Spring3 extension. In most of the cases this is enough but when the generics are involved it is better to look for the beans by their name and not their type.
To solve this we need to add the support of the Resource annotation.



 Comments   
Comment by olivier.billiard [ 12/Jun/15 ]

I already prepared the fix and modified an example to show how to use it.
How can I give that to you or push it to the git? At the moment I have a permission denied.

Thanks

Comment by Michael Osipov [ 13/Jun/15 ]

Fork on GitHub, provide a pull request.

Comment by olivier.billiard [ 15/Jun/15 ]

Thanks Michael, I created the pull request.

Comment by Adam Lindenthal [ 07/Aug/15 ]

https://github.com/jersey/jersey/pull/174

Comment by Adam Lindenthal [ 07/Aug/15 ]

Moving to backlog, until the pull request is processed.





[JERSEY-2892] If the same class appears in the object graph more than once, EntityFiltering incorrectly filters its properties Created: 23/Jun/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: media
Affects Version/s: 2.18
Fix Version/s: None

Type: Bug Priority: Major
Reporter: bedag-moo Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: entity-filtering
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

If objects of the same class appear more than once in the serialization graph, JacksonObjectProvider causes their properties to be filtered even if there are no filtering annotations present.

*test case*
The resource

@Path("test")
@Produces(MediaType.APPLICATION_JSON)
public class TestResource {

    @GET
    public Issue issue() {
        return new Issue();
    }

    public static class Issue {
        public Person reporter = new Person();
        public Person assignee = new Person();
    }

    public static class Person {
        public Address address = new Address();
    }

    public static class Address {
        public Name name = new Name();
        public String town = "Town";
    }

    public static class Name {
        public String first = "John";
        public String last = "Doe";
    }
}

returns the following JSON document

{
  "reporter":{
    "address":{
      "name":{
        "first":"John",
        "last":"Doe"
      },
      "town":"Town"
     }
  },
  "assignee":{
    "address":{
      "town":"Town"
    }
  }
}

As you can see, even though assignee and reporter refer to equal objects, their "name" property is only serialized the first time.



 Comments   
Comment by bedag-moo [ 23/Jun/15 ]

In rather painstaking labor, I have tracked this down to JacksonObjectProvider.createSubfilters, which reads:

            final String fieldName = entry.getKey();
            final ObjectGraph graph = entry.getValue();

            final String path = parent + "." + fieldName;

            // Subgraph Fields.
            final Map<String, ObjectGraph> subgraphs = graph.getSubgraphs(path);

            final Class<?> subEntityClass = graph.getEntityClass();
            final String processedSubgraph = getProcessedSubgraph(entityClass, fieldName, subEntityClass);

            Map<String, FilteringPropertyFilter> subSubfilters = new HashMap<>();
            if (!subgraphs.isEmpty() && !processed.contains(processedSubgraph)) {
                processed.add(processedSubgraph);
                subSubfilters = createSubfilters(path, subEntityClass, subgraphs, processed);
            }

            subfilters.put(fieldName, new FilteringPropertyFilter(graph.getEntityClass(), graph.getFields(path), subSubfilters));

The last line creates a new FilteringPropertyFilter for the field, passing it `subSubfilters`, which is only added to if `!processed.contains(processedSubgraph)`. However, processedSubgraph only depends on the subfield being checked. Therefore, if the same class is encountered more than once, this condition is false for all but the first occurence, causing subfilters to remain empty, which in turn causes all properties of complex type to be filtered out for all but the first occurence of that class in the object graph.

Comment by Adam Lindenthal [ 07/Aug/15 ]

Hi, thanks for opening the issue and for your time spent with the analysis.
I will move it to backlog, so that we can plan the work on it in one of the future sprints.

Regards,
Adam





[JERSEY-2896] Port to simpleframework 6.0.1 Created: 27/Jun/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: containers
Affects Version/s: 2.18
Fix Version/s: None

Type: Task Priority: Major
Reporter: puntogil Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Comments   
Comment by puntogil [ 27/Jun/15 ]

diff -Nru jersey-2.18/containers/simple-http/pom.xml jersey-2.18.simple/containers/simple-http/pom.xml
— jersey-2.18/containers/simple-http/pom.xml 2015-06-27 19:55:52.092656409 +0200
+++ jersey-2.18.simple/containers/simple-http/pom.xml 2015-06-27 20:03:12.623837317 +0200
@@ -61,7 +61,18 @@
</dependency>
<dependency>
<groupId>org.simpleframework</groupId>

  • <artifactId>simple</artifactId>
    + <artifactId>simple-common</artifactId>
    + <version>$ {simple.version}</version>
    + </dependency>
    + <dependency>
    + <groupId>org.simpleframework</groupId>
    + <artifactId>simple-http</artifactId>
    + <version>${simple.version}

    </version>
    + </dependency>
    + <dependency>
    + <groupId>org.simpleframework</groupId>
    + <artifactId>simple-transport</artifactId>
    + <version>$

    {simple.version}</version>
    </dependency>
    </dependencies>

    diff -Nru jersey-2.18/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java jersey-2.18.simple/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java
    — jersey-2.18/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java 2015-06-03 19:07:50.000000000 +0200
    +++ jersey-2.18.simple/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java 2015-06-27 19:10:22.696774254 +0200
    @@ -57,8 +57,7 @@
    import org.glassfish.hk2.api.ServiceLocator;

    import org.simpleframework.http.core.Container;
    -import org.simpleframework.http.core.ContainerServer;
    -import org.simpleframework.transport.Server;
    +import org.simpleframework.http.core.ContainerSocketProcessor;
    import org.simpleframework.transport.connect.Connection;
    import org.simpleframework.transport.connect.SocketConnection;

    @@ -180,10 +179,11 @@
    public static SimpleServer create(final URI address,
    final SSLContext context,
    final SimpleContainer container) {
    - return _create(address, context, container, new UnsafeValue<Server, IOException>() {
    + return _create(address, context, container, new UnsafeValue<ContainerSocketProcessor, IOException>() {
    @Override
    - public Server get() throws IOException {
    - return new ContainerServer(container);
    + public ContainerSocketProcessor get() throws IOException { + ContainerSocketProcessor csp = new ContainerSocketProcessor(container); + return csp; }
    });
    }
    @@ -241,10 +241,11 @@
    final int count,
    final int select) throws ProcessingException {

    - return _create(address, context, container, new UnsafeValue<Server, IOException>() {
    + return _create(address, context, container, new UnsafeValue<ContainerSocketProcessor, IOException>() {
    @Override
    - public Server get() throws IOException {
    - return new ContainerServer(container, count, select);
    + public ContainerSocketProcessor get() throws IOException { + ContainerSocketProcessor csp = new ContainerSocketProcessor(container, count, select); + return csp; }
    });
    }
    @@ -252,7 +253,7 @@
    private static SimpleServer _create(final URI address,
    final SSLContext context,
    final SimpleContainer container,
    - final UnsafeValue<Server, IOException> serverProvider) throws ProcessingException {
    + final UnsafeValue<ContainerSocketProcessor, IOException> serverProvider) throws ProcessingException {
    if (address == null) { throw new IllegalArgumentException(LocalizationMessages.URI_CANNOT_BE_NULL()); }
    @@ -277,7 +278,7 @@
    final InetSocketAddress listen = new InetSocketAddress(port);
    final Connection connection;
    try {
    - final Server server = serverProvider.get();
    + final ContainerSocketProcessor server = serverProvider.get();
    connection = new SocketConnection(server);

    final SocketAddress socketAddr = connection.connect(listen, context);
    diff -Nru jersey-2.18/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java jersey-2.18.simple/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java
    — jersey-2.18/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java 2015-06-03 19:07:50.000000000 +0200
    +++ jersey-2.18.simple/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java 2015-06-27 19:58:50.104243748 +0200
    @@ -280,7 +280,8 @@

    @Override
    public Principal getUserPrincipal() { - return request.getSecuritySession().getLocalPrincipal(); + Principal rqst = (Principal) request.getClientCertificate(); + return rqst; }

    @Override
    diff -Nru jersey-2.18/pom.xml jersey-2.18.simple/pom.xml
    — jersey-2.18/pom.xml 2015-06-27 19:55:52.100656031 +0200
    +++ jersey-2.18.simple/pom.xml 2015-06-27 20:04:00.236587182 +0200
    @@ -1229,7 +1229,17 @@

    <dependency>
    <groupId>org.simpleframework</groupId>
    - <artifactId>simple</artifactId>
    + <artifactId>simple-common</artifactId>
    + <version>${simple.version}

    </version>
    + </dependency>
    + <dependency>
    + <groupId>org.simpleframework</groupId>
    + <artifactId>simple-http</artifactId>
    + <version>$

    {simple.version}</version>
    + </dependency>
    + <dependency>
    + <groupId>org.simpleframework</groupId>
    + <artifactId>simple-transport</artifactId>
    <version>${simple.version}

    </version>
    </dependency>

@@ -1637,7 +1647,7 @@
<rxjava.version>1.0.4</rxjava.version>
<servlet2.version>2.4</servlet2.version>
<servlet3.version>3.0.1</servlet3.version>

  • <simple.version>5.1.4</simple.version>
    + <simple.version>6.0.1</simple.version>
    <spring3.version>3.2.3.RELEASE</spring3.version>
    <validation.api.version>1.1.0.Final</validation.api.version>
    <weld.version>2.2.8.Final</weld.version>
Comment by Adam Lindenthal [ 06/Aug/15 ]

Hi puntogil. Thanks for opening the ticket and for providing the diff.
We cannot accept contributions in this way. Would you rather consider creating a pull request on github?
Here's some overview on how to do it: https://jersey.java.net/scm.html

Anyway, I'll put the issue to backlog. If you will create a pull-request, just paste a link to github to the issue (and vice versa).
If you won't, someone will do this eventually via internal commit.

Regards,
Adam





[JERSEY-2901] Return CompletableFuture from ApplicationHandler.apply() instead of Future Created: 01/Jul/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.18, 2.19
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: cppexpert Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

It would be great if ApplicationHandler.apply(x, y) could return CompletableFuture instead of Future.

The problem with Future is that there is no way for client asynchronously getting result without blocking the thread. It's highly ineffective in high-load server.

CompletableFuture was instroduced in JDK 1.8. If dependency on 1.8 is blocker we could use vanilla interface such as

public interface CompletionCallback {
    public void onComplete(ContainerResponse response);
}

and add ApplicationHandler.setCompletionHandler(CompletionCallback callback).

Currently I have to use ugly hack as follows

    class OutputStreamCompletion<T> extends OutputStream {

        final private OutputStream stream;
        final private Promise<Future<T>> promise;

        private Future<T> javaFuture;

        public OutputStreamCompletion(@NotNull OutputStream stream, @NotNull Promise<Future<T>> promise) {
            this.stream = stream;
            this.promise = promise;
        }

        @Override
        public void write(int b) throws IOException {
            stream.write(b);
        }

        @Override
        public void write(@NotNull byte b[]) throws IOException {
            stream.write(b);
        }

        @Override
        public void write(@NotNull byte b[], int off, int len) throws IOException {
            stream.write(b, off, len);
        }

        @Override
        public void flush() throws IOException {
            stream.flush();
        }

        @Override
        public void close() throws IOException {
            stream.close();
            promise.success(javaFuture);
        }

        public void setJavaFuture(@NotNull Future<T> future) {
            this.javaFuture = future;
        }
    }


 Comments   
Comment by Michal Gajdos [ 01/Jul/15 ]

This won't happen in Jersey 2.x, which implements JAX-RS 2.0, because the spec says that the implementation has to run on Java 7. However JAX-RS 2.1 (currently in progress) will require Java 8 and that's the moment when this topic can be discussed. Work on the next version of Jersey (based on JAX-RS 2.1) should start soon so stay tuned Moving to backlog for now.

Comment by cppexpert [ 01/Jul/15 ]

How about using custom `CompletionCallback` ? It will work on 1.7 and won't violate the standard I assume.





[JERSEY-2915] Support Rx.Observable with Jersey Proxy Client Created: 15/Jul/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: extensions
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: saacharya Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Would it be possible to enhance the Jersey Proxy client project (https://jersey.java.net/apidocs/2.19/jersey/org/glassfish/jersey/client/proxy/package-summary.html) to provide support for Rx Observable. The Core Jersey Client project supports Rx Observable , it would be great if we could do the following:

 @Path("myresource")
 public interface MyResourceIfc {
     @GET
     @Produces("text/plain")
     Observable<String> get();
}


 Comments   
Comment by Adam Lindenthal [ 06/Aug/15 ]

Hi, thanks for you suggestion.
I will put the ticket to backlog, cannot however promise anything...

Have a nice day,
Adam





[JERSEY-2927] Allow to disable lookup of o.g.j.s.spi.ComponentProvider Created: 31/Jul/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.17, 2.19
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: modaxas Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Glassfish 4.0 on Linux



 Description   

Hello,

I have been trying to get the latest Jersey embedded in my application which will run on vanilla Glassfish 4.0. In order to succeed, I need to disable any runtime look ups of the classes in the classpath (since then older Jersey version integrated into Glassfish will conflict with newer one I'm trying to embed). I'm almost done except that I cannot prevent Jersey from ServiceFinder'ing o.g.j.s.spi.ComponentProvider at o.g.j.server.ApplicationHandler. Could you make this lookup optional (which would be configuration with either METAINF_SERVICES_LOOKUP_DISBALE or a new property)?



 Comments   
Comment by Adam Lindenthal [ 10/Aug/15 ]

Hi, wouldn't it be easier to download latest glassfish sources (we are integrating latest jersey into glassfish during each release) and build it? Or do you really need for some reason not to use jersey provided by glassfish (regardless the version)?

Regards,
Adam

Comment by Adam Lindenthal [ 10/Aug/15 ]

https://java.net/projects/glassfish/sources/svn/show/trunk/main

Comment by modaxas [ 15/Aug/15 ]

Hello,

no, because I have no control over production environment (nor I want the app to be strictly tied to it) but I obviously want to use the latest Jersey for practical reasons (+ a couple of features and bug fixes). Unfortunately, Glassfish, which I need as a mere app container in my case, is getting in my way where it should not to.

I would not ask If it didn't work and didn't help my case. Currently I have to resort to shipping a modified version of ApplicationHandler in my app which skips the scanning. But obviously this is neither nice nor very maintainable.

Comment by Adam Lindenthal [ 17/Aug/15 ]

Well, I understand your motivation, it's just that I would be afraid of running into some weird issues in the future if something remains on classpath.
I will put this issue to backlog, so that we can take a look at it in one of the future sprints.





[JERSEY-2940] Support Jetty 9.3 Created: 16/Aug/15  Updated: 11/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.21
Fix Version/s: None

Type: Improvement Priority: Major
Reporter: azell Assignee: Unassigned
Resolution: Unresolved Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Relates
relates to JERSEY-2949 Jetty async write ordering leads to d... Resolved
relates to JERSEY-2951 Supplied Jetty version (9.1.1.v201401... Open
Tags: jetty, pull-request

 Description   

Jetty is now at 9.3.2.v20150730. Running with this version results in run-time errors:

java.lang.NoSuchMethodError: org.eclipse.jetty.server.Response.getResponse(Ljavax/servlet/http/HttpServletResponse;)Lorg/eclipse/jetty/server/Response;
at org.glassfish.jersey.jetty.JettyHttpContainer.handle(JettyHttpContainer.java:166)

I am guessing there is a similar fix at http://osdir.com/ml/scm-fedora-commits/2015-06/msg33723.html which converts "Response.getResponse(httpServletResponse);" to "request.getResponse();"



 Comments   
Comment by azell [ 16/Aug/15 ]

Jetty 9.3 requires Java 8, so this may not be appropriate for the current Jersey which targets 1.7. Changing jetty.version to 9.2.13.v20150730 causes a number of async POST and PUT tests to hang.

Comment by azell [ 30/Aug/15 ]

There is a bug in the Jetty connector for all releases >= 9.1.4.v20140401. I will create a new issue and pull request.

Comment by emszpak [ 02/Sep/15 ]

@azell Could you put a link to the issue/PR here to make it easier to track?

Comment by azell [ 03/Sep/15 ]

Link to Jetty connector issue: https://java.net/jira/browse/JERSEY-2949

Comment by Adam Lindenthal [ 04/Sep/15 ]

Link to the pull request: https://github.com/jersey/jersey/pull/188

Comment by Adam Lindenthal [ 04/Sep/15 ]

Hi Azell, thanks for creating the issue and the pull request.
As already stated in the pull request, we cannot merge it right now as it is because of the jdk8 dependency.

I am moving the issue to backlog, where it stays at least until we decide not to support Java < 8.
You mentioned that you are planning to create a pull request for JERSEY-2949. I asked you a question in the current PR #188, but with regard to your plans to create a PR for the other issue, I guess I can close #188, at least for now, correct?

Regards,
Adam

Comment by azell [ 04/Sep/15 ]

Yes, #188 can be closed until the minimum Java version for Jersey is 1.8.

Comment by Adam Lindenthal [ 04/Sep/15 ]

Thanks, just closed the PR.

Comment by emszpak [ 04/Sep/15 ]

Guys, I haven't dug into the code (and don't know what exactly is the problem), but maybe it would be possible to add support for Jetty 9.3 (for people using Java 8 in runtime) without dropping Java 7 support (for people with Java 7 and earlier Jetty versions)?

Comment by azell [ 04/Sep/15 ]

From https://webtide.com/jetty-9-3-features/ :

Jetty-9.3 is built and targeted for Java 8. This change was prompted by the SNI extension reliance on a Java 8 API and the HTTP2 specification need for TLS ciphers that are only available in Java 8. It is possible to build Jetty-9.3 for Java 7 and we were considering releasing it as such with a few configuration tricks to enable the few classes that require java 8, however we decided that since java 7 is end-of-life is was not worth the complication to support it directly in the release. If you really need java 7, then please speak to Webtide about a build of 9.3 for 7.





[JERSEY-2950] Jersey ignores @ApplicationPath in embedded jetty Created: 30/Aug/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: containers, core
Affects Version/s: 2.21
Fix Version/s: None

Type: Bug Priority: Major
Reporter: aalquaiti Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Java SE 8, jetty-sever 9.3.2,



 Description   

In embedded jetty, jersey container ignores @ApplicationPath annotation. Here is the code used:

package me.aymen.rest.server;

import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletContainer;

public class EmbeddedJetty
{
    public static void main(String[] args)
    {
       Server server = new Server(9034);
       ServletContextHandler context = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
       server.setHandler(context);
       context.setContextPath("/*");
       ServletContainer jersey = new ServletContainer(ResourceConfig.forApplicationClass(MyApplication.class));
       ServletHolder holder = new ServletHolder(jersey);
       
        try
        {
            server.start();
        }
        catch (Exception ex)
        {
            Logger.getLogger(EmbeddedJetty.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        context.addServlet(holder, "/*");
    }
}

As for the Application:

package me.aymen.rest.server;

import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/test")
public class MyApplication extends Application
{
    Set<Class<?>> clss;
    
    public MyApplication()
    {
        clss = new HashSet<>();        
        clss.add(MyService.class);
    }
    
    @Override
    public Set<Class<?>> getClasses()
    {
        return  clss;
    }
}

And the service resource:

package me.aymen.rest.server;

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

@Path("/serv")
public class MyService {

   @GET   
   @Produces(MediaType.TEXT_HTML)
   public String available() {
      return "<HTML><Head><title>My Service</title><Body><H3>Hello, World!</H3><Body></Head></HTML>";
   }
}


 Comments   
Comment by Adam Lindenthal [ 04/Sep/15 ]

Hi, thanks for reporting the issue.

I am moving it to backlog, so that we can take a look at it in one of the future sprints.

Regards,
Adam





[JERSEY-2951] Supplied Jetty version (9.1.1.v20140108) doesn't set Date header. Created: 02/Sep/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: containers
Affects Version/s: 2.21
Fix Version/s: None

Type: Bug Priority: Major
Reporter: fholmqvist Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Dependency
depends on JERSEY-2949 Jetty async write ordering leads to d... Resolved
Relates
relates to JERSEY-2940 Support Jetty 9.3 Open
Sprint: Triaged

 Description   

Using the supplied jetty (9.1.1.v20140108) no Date header are returned in responses. Solution is to update Jetty version. This override makes Date header work again:

        <jetty.version>9.2.13.v20150730</jetty.version>

And

        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-jetty-servlet</artifactId>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-jetty-http</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.eclipse.jetty</groupId>
                    <artifactId>jetty-server</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.eclipse.jetty</groupId>
                    <artifactId>jetty-webapp</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.eclipse.jetty</groupId>
                    <artifactId>jetty-util</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.eclipse.jetty</groupId>
                    <artifactId>jetty-continuation</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>${jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-webapp</artifactId>
            <version>${jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-util</artifactId>
            <version>${jetty.version}</version>
        </dependency>


 Comments   
Comment by Adam Lindenthal [ 04/Sep/15 ]

Hi and thanks for opening this.
As there are reported issues with async processing with Jetty versions 9.1.4 and above, I've linked the issues together and will move this one to backlog at least unless the async problems are resolved.

After this happens, I assume, we will upgrade to more recent version (probably 9.2.13 - the latest one with jdk7 support), so I hope this issue will be resolved while fixing the other.

Regards,
Adam





[JERSEY-2955] Classloading issue in case of custom classloader usage Created: 04/Sep/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.19
Fix Version/s: None

Type: Bug Priority: Major
Reporter: yakimovich Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Weblogic 12.1.3, Java7



 Description   

When Jersey is loaded via custom classloader it's failing with ClassNotFoundException:

**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /              Caused by :java.lang.ClassNotFoundException: org.glassfish.jersey.internal.spi.AutoDiscoverable
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at weblogic.utils.classloaders.GenericClassLoader.findLocalClass(GenericClassLoader.java:335)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at weblogic.utils.classloaders.GenericClassLoader.findClass(GenericClassLoader.java:302)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at weblogic.utils.classloaders.GenericClassLoader.loadClass(GenericClassLoader.java:180)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at java.lang.ClassLoader.defineClass1(Native Method)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at weblogic.utils.classloaders.GenericClassLoader.defineClass(GenericClassLoader.java:385)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at weblogic.utils.classloaders.GenericClassLoader.findLocalClass(GenericClassLoader.java:344)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at weblogic.utils.classloaders.GenericClassLoader.findClass(GenericClassLoader.java:302)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at weblogic.utils.classloaders.GenericClassLoader.loadClass(GenericClassLoader.java:180)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at weblogic.utils.classloaders.FilteringClassLoader.findClass(FilteringClassLoader.java:106)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at weblogic.utils.classloaders.FilteringClassLoader.loadClass(FilteringClassLoader.java:91)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at java.lang.ClassLoader.loadClass(ClassLoader.java:412)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at weblogic.utils.classloaders.GenericClassLoader.loadClass(GenericClassLoader.java:180)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at weblogic.utils.classloaders.ChangeAwareClassLoader.loadClass(ChangeAwareClassLoader.java:43)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at java.lang.Class.forName0(Native Method)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at java.lang.Class.forName(Class.java:270)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.jersey.internal.util.ReflectionHelper$7.run(ReflectionHelper.java:403)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.jersey.internal.util.ReflectionHelper$7.run(ReflectionHelper.java:398)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at java.security.AccessController.doPrivileged(Native Method)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.jersey.internal.ServiceFinder$AbstractLazyIterator.hasNext(ServiceFinder.java:577)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.jersey.internal.ServiceFinder.toClassArray(ServiceFinder.java:418)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.jersey.internal.ServiceFinderBinder.configure(ServiceFinderBinder.java:90)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.hk2.utilities.binding.AbstractBinder.bind(AbstractBinder.java:171)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.hk2.utilities.binding.AbstractBinder.install(AbstractBinder.java:329)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.jersey.server.ServerBinder.configure(ServerBinder.java:94)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.hk2.utilities.binding.AbstractBinder.bind(AbstractBinder.java:171)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.jersey.internal.inject.Injections.bind(Injections.java:154)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.jersey.internal.inject.Injections._createLocator(Injections.java:144)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.jersey.internal.inject.Injections.createLocator(Injections.java:123)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:329)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:339)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:170)
**** Error          Fri Aug 28 12:39:56 EDT 2015        1440779996519  /                              at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:362)

The reason of such exception is that ServiceFinder(loaded by current custom classloader) is using current thread's context classloader for loading services and as a result such classes are not found. All those service classes are coming with current custom classloader and not available for thread's context classloader. What I'm asking for is to change such logic and do fallback to current classloader. Something like Validation library are doing - http://grepcode.com/file/repo1.maven.org/maven2/javax.validation/validation-api/1.1.0.Final/javax/validation/Validation.java?av=f
I already had email conversation with Marek Potociar regarding this clasloading issue and he agreed to look into fallback with own classloader usage.
Note, that javax.ws.rs.client.FactoryFinder is having the same problem.



 Comments   
Comment by Adam Lindenthal [ 14/Sep/15 ]

Hi, thanks for opening the issue.
If you already discussed with Marek, I guess I can but the issue to backlog.
In case you want to help us, feel free to create a small runnable reproducer test case and share it.

Regards,
Adam





[JERSEY-2956] File Upload issue. multipart/form-data issue Created: 07/Sep/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: examples, media
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: shermax Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: 2.21
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Using jersey 2.21, mimepull 1.9.6, jackson 2.5.4, spring 4.1.6.RELEASE (for DI only) & spring security 4.0.2.RELEASE for security. Using JDK 1.8.0_25 and Tomcat 8.0.26.


Attachments: Zip Archive jersey-file-upload-master.zip    
Sprint: Triaged

 Description   

Detailed explanation can be found at following link:

http://stackoverflow.com/questions/32426291/jersey-2-multipart-form-data-issue-inputstream-is-empty-available-0



 Comments   
Comment by Marek Potociar [ 10/Sep/15 ]

Reclassifying as bug.

Comment by Adam Lindenthal [ 14/Sep/15 ]

Hi, thanks for reporting the issue.
I am moving it to backlog, so that we can take a look at it in one of the future sprints.
In the meantime, if you would be willing to create a minimal runnable reproducer test case/demo app and share it (e.g. via github), including the client code (or reproducing steps - such as the curl command you are using, etc.), it would be appreciated.
I see you already posted sources from your app on stackoverflow, so hopefully extracting minimalistic case focused on the issue would not be to much work.

Thanks,
Adam

Comment by shermax [ 18/Sep/15 ]

Hi Adam!

Thanks for your response!

I am sharing sample code which is not working on me:
https://github.com/shermax/jersey-file-upload

Info: Using Java 1.8.0_25(x64) & Tomcat 8.0.26 on Windows 8.1 machine.

Comment by Adam Lindenthal [ 18/Sep/15 ]

Thanks, I downloaded it and re-attached here.

Adam

Comment by shermax [ 20/Oct/15 ]

Hi Adam!
Is there any progress with this issue?
Thanks!

Sherzod

Comment by Fire_For_Effect [ 27/Nov/15 ]

Just wanted to share this... posted to the original Stack Overflow question.

http://stackoverflow.com/questions/32426291/jersey-2-multipart-form-data-issue-inputstream-is-empty-available-0/33962167#33962167

In short, i found the bug and a possible solution.





[JERSEY-2958] InMemoryTestContainer does not call "onStartup" and "onShutdown" Created: 11/Sep/15  Updated: 25/Jan/16

Status: In Progress
Project: jersey
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major
Reporter: rzanner Assignee: petrjanouch
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

In the "start" and "stop" methods of the TestContainer, the internal ApplicationHandler's "onStartup" and onShutdown" methods need to be called to make sure that registered ContainerLifecycleListeners are executed.

        @Override
        public void start() {
            if (started.compareAndSet(false, true)) {
                LOGGER.log(Level.FINE, "Starting InMemoryContainer...");
                // this line needs to be added:
                appHandler.onStartup(null);
            } else {
                LOGGER.log(Level.WARNING, "Ignoring start request - InMemoryTestContainer is already started.");
            }
        }

        @Override
        public void stop() {
            if (started.compareAndSet(true, false)) {
                LOGGER.log(Level.FINE, "Stopping InMemoryContainer...");
                // this line needs to be added:
                appHandler.onShutdown(null);
            } else {
                LOGGER.log(Level.WARNING, "Ignoring stop request - InMemoryTestContainer is already stopped.");
            }
        }






[JERSEY-2961] Missing support for OAuth2 client bearer type basic in access token request Created: 15/Sep/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: security
Affects Version/s: 2.9.1
Fix Version/s: None

Type: Bug Priority: Major
Reporter: rgunn Assignee: Ondrej Kosatka
Resolution: Unresolved Votes: 0
Labels: evaluation-needed
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: oauth2, secuirty

 Description   

Some OAuth2 providers as per RFC 6749 4.1.3 require the header

Authorization: Basic [clientId:secret]

to be included as per RFC 6749 Section 4.1.1:

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

Can this be added to to the OAuth2ClientSupport.authorizationCodeGrantFlowBuilder ?



 Comments   
Comment by rgunn [ 15/Sep/15 ]

In the meantime I have passed my own Client instance to the OAuth2CodeGrantFlow.Builder and registered a ClientRequestFilter so this header can be added





[JERSEY-2963] MessageBodyWriter not found for media type application/json when using MOXy Created: 16/Sep/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: media
Affects Version/s: 2.21
Fix Version/s: None

Type: Bug Priority: Major
Reporter: Miko95 Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I'm getting the following error in my logs:

org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor aroundWriteTo
Grave: MessageBodyWriter not found for media type=application/json, type=class com.sample.MyDTO, genericType=class com.sample.MyDTO.

In general, it is caused by the lack of registered MessageBodyWriter but in my case, I do have the jersey-media-proxy JAR on the classpath (with all its dependencies). If that helps debugging, I confirm that the configure method of the MoxyJsonFeature is called when my web application is deployed.

I precise I'm using Jersey v2.21. My web application is deployed on Tomcat 8.0.26.

Also, I tried switching to Jackson and it works fine so I assume something is going wrong with MOXy.



 Comments   
Comment by Marek Potociar [ 21/Sep/15 ]

Looks like MOXy entity providers should be registered with lower priority to not interfere with application-specific custom providers.





[JERSEY-2964] ContextResolver<ObjectMapper> don't work when register a MessageBodyReader<Object> Created: 16/Sep/15  Updated: 25/Jan/16

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.19
Fix Version/s: None

Type: Bug Priority: Major
Reporter: amgohan Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: evaluation-needed
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I had this configuration working fine :