[JERSEY-2908] RolesAllowedDynamicFeature returns incorrect 401 challenge Created: 12/Jul/15  Updated: 31/Aug/15  Resolved: 31/Aug/15

Status: Resolved
Project: jersey
Component/s: core
Affects Version/s: 2.18, 2.19
Fix Version/s: 2.22

Type: Bug Priority: Major
Reporter: AdamZegelin Assignee: Petr Bouda
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Modifications were made to RolesAllowedDynamicFeature to support return HTTP status 401 when there is no active user principal in the SecurityContext — see JERSEY-2818.

RolesAllowedDynamicFeature now throws a NotAuthorizedException, but incorrectly provides a human-readable localised error message as the exception parameter, which ends up as the 401 WWW-Authenticate challenge.

WWW-Authenticate should be a valid challenge (or challenges), which is application specific — i.e., it should not be hard-coded to "Basic".
An example is WWW-Authenticate: Basic realm="My Application Realm"

$ curl -I http://localhost:9000/api/restricted
HTTP/1.1 401 Unauthorized
www-authenticate: User not authorized.
content-length: 0
date: Sun, 12 Jul 2015 08:27:03 GMT
connection: close
RolesAllowedDynamicFeature.java:401
throw new NotAuthorizedException(LocalizationMessages.USER_NOT_AUTHORIZED());
⋮
NotAuthorizedException.java:85
public NotAuthorizedException(Object challenge, Object... moreChallenges) …
⋮


 Comments   
Comment by Adam Lindenthal [ 06/Aug/15 ]

Hi, thanks for reporting the problem.
I will put the issue in backlog, so that we can plan the work on it in one of the future sprints.

Regards,
Adam

Comment by Petr Bouda [ 31/Aug/15 ]

Throws ForbiddenException instead of NotAuthorizedException





[JERSEY-2950] Jersey ignores @ApplicationPath in embedded jetty Created: 30/Aug/15  Updated: 30/Aug/15

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>"; }

}






[JERSEY-2949] Jetty async write ordering leads to deadlock Created: 30/Aug/15  Updated: 30/Aug/15

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

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

Any Jetty version >= 9.1.4.v20140401


Tags: connectors, jetty

 Description   

According to http://www.eclipse.org/jetty/documentation/current/http-client-api.html#http-client-content the client should not attempt to write the request body until the async send() method has been invoked.

Writing the request body first leads to a deadlock with all recent versions of Jetty. Jetty 9.1.1.v20140108 allows this behavior.

Given the documentation referenced above the correct behavior is to:

1. Associate the content provider with the Jetty request
2. Call the async send method on the Jetty request and pass it a callback
3. Write the request content
4. Close the content provider's output stream

I will send a pull request. After the above changes are made, all the unit tests under jetty-connector pass using Jetty 9.2.13.v20150730.






[JERSEY-2940] Support Jetty 9.3 Created: 16/Aug/15  Updated: 30/Aug/15

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: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

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.





[JERSEY-2948] Cannot perform OAuth1 auth flow with Flickr Created: 29/Aug/15  Updated: 29/Aug/15

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

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

OS X 10.10.5

java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)

org.glassfish.jersey.security:oauth1-client:2.21



 Description   

Trying to follow example on OAuth1 auth flow
https://jersey.java.net/documentation/latest/security.html
with Flickr:

try

{ ConsumerCredentials consumerCredentials = new ConsumerCredentials( "does not matter", "does not matter"); OAuth1AuthorizationFlow authFlow = OAuth1ClientSupport.builder(consumerCredentials) .authorizationFlow( "https://www.flickr.com/services/oauth/request_token", "https://www.flickr.com/services/oauth/access_token", "https://www.flickr.com/services/oauth/authorize") .build(); String authorizationUri = authFlow.start(); return authorizationUri; }

catch (Exception ex)

{ ex.printStackTrace(); return null; }

gives an exception (api keys may be valid or not, does not matter):

java.lang.RuntimeException: Error occurred in the oauth client support. Error requesting Request Token. Response status 411 returned.
at org.glassfish.jersey.client.oauth1.OAuth1AuthorizationFlowImpl.start(OAuth1AuthorizationFlowImpl.java:199)

The reason seems to be that Flickr server is picky about Content-Length header presence even if it's POST with empty body.






[JERSEY-2890] CLONE - Tomcat memory leak on undeploy Created: 16/Jun/15  Updated: 28/Aug/15

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

Type: Bug Priority: Major
Reporter: sampatn Assignee: Adam Lindenthal
Resolution: Unresolved Votes: 3
Labels: hk2, memory-leak
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Tomcat 8.0.18


Issue Links:
Cloners
clones JERSEY-2772 Tomcat memory leak on undeploy Resolved
Dependency
depends on HK2-264 tomcat memory leak Closed
Duplicate
duplicates HK2-247 Tomcat memory leak on undeploy Closed
Related
is related to JERSEY-2849 @BeanParam injection behavior changed... Open

 Description   

On undeploy, I get the following errors. Any idea?

03-Feb-2015 08:48:14.362 SEVERE [http-nio-8080-exec-62] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [v1] created a ThreadLocal with key of type [org.jboss.netty.util.CharsetUtil$2] (value [org.jboss.netty.util.CharsetUtil$2@ecfacab]) and a value of type [java.util.IdentityHashMap] (value [{UTF-8=sun.nio.cs.UTF_8$Decoder@3b8a17a9}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
03-Feb-2015 08:48:14.362 SEVERE [http-nio-8080-exec-62] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [v1] created a ThreadLocal with key of type [org.jboss.netty.util.CharsetUtil$2] (value [org.jboss.netty.util.CharsetUtil$2@ecfacab]) and a value of type [java.util.IdentityHashMap] (value [{UTF-8=sun.nio.cs.UTF_8$Decoder@515aa672}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
03-Feb-2015 08:48:14.362 SEVERE [http-nio-8080-exec-62] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [v1] created a ThreadLocal with key of type [org.jboss.netty.util.CharsetUtil$2] (value [org.jboss.netty.util.CharsetUtil$2@ecfacab]) and a value of type [java.util.IdentityHashMap] (value [{UTF-8=sun.nio.cs.UTF_8$Decoder@26d65908}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
03-Feb-2015 08:48:14.362 SEVERE [http-nio-8080-exec-62] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [v1] created a ThreadLocal with key of type [com.codahale.metrics.ThreadLocalRandom$1] (value [com.codahale.metrics.ThreadLocalRandom$1@558f138d]) and a value of type [com.codahale.metrics.ThreadLocalRandom] (value [com.codahale.metrics.ThreadLocalRandom@3ed371ca]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
03-Feb-2015 08:48:14.362 SEVERE [http-nio-8080-exec-62] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [v1] created a ThreadLocal with key of type [org.jboss.netty.util.CharsetUtil$2] (value [org.jboss.netty.util.CharsetUtil$2@ecfacab]) and a value of type [java.util.IdentityHashMap] (value [{UTF-8=sun.nio.cs.UTF_8$Decoder@3abe2954}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
03-Feb-2015 08:48:14.882 INFO [http-nio-8080-exec-62] org.apache.catalina.startup.HostConfig.undeploy Undeploying context [/v1]


 Comments   
Comment by sampatn [ 16/Jun/15 ]

I am still getting this with version 2.17 as well as with 2.18

SEVERE: The web application [/hello_world_v1.0] created a ThreadLocal with key of type [org.jvnet.hk2.internal.PerLocatorUtilities$1] (value [o
rg.jvnet.hk2.internal.PerLocatorUtilities$1@2ea83c11]) and a value of type [java.util.WeakHashMap] (value [{}]) but failed to remove it when the web a
pplication was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
Jun 16, 2015 10:03:55 AM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks

Comment by lazlev [ 19/Jun/15 ]

I can confirm that this still occurs in version 2.18!

Comment by lazlev [ 19/Jun/15 ]

I tested it with the latest hk2-locator-2.4.0-b25 and still got the following memory leaks:

Jun 19, 2015 9:42:03 AM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/Webapp] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@1e3094b]) and a value of type [java.lang.Class] (value [class oracle.sql.AnyDataFactory]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
Jun 19, 2015 9:42:03 AM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/Webapp] created a ThreadLocal with key of type [org.jvnet.hk2.internal.PerLocatorUtilities$1] (value [org.jvnet.hk2.internal.PerLocatorUtilities$1@6d22ae]) and a value of type [java.util.WeakHashMap] (value [{}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
Jun 19, 2015 9:42:03 AM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/Webapp] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@ffe030]) and a value of type [java.lang.Class] (value [class oracle.sql.TypeDescriptorFactory]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
Jun 19, 2015 9:42:03 AM org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
SEVERE: The web application [/Webapp] created a ThreadLocal with key of type [org.jvnet.hk2.internal.PerLocatorUtilities$2] (value [org.jvnet.hk2.internal.PerLocatorUtilities$2@d7ad5f]) and a value of type [java.util.WeakHashMap] (value [

{protected javax.servlet.http.HttpServletRequest com.zf.webservices.services.BaseService.request=org.jvnet.hk2.internal.SoftAnnotatedElementAnnotationInfo@1b76cb8, public org.glassfish.jersey.servlet.WebComponent$HttpServletRequestReferencingFactory(javax.inject.Provider)=org.jvnet.hk2.internal.SoftAnnotatedElementAnnotationInfo@142d20c, protected org.glassfish.jersey.server.internal.process.ServerProcessingBinder$ContainerRequestFactory(javax.inject.Provider)=org.jvnet.hk2.internal.SoftAnnotatedElementAnnotationInfo@1ec1ec8, protected javax.servlet.http.HttpServletResponse com.zf.webservices.services.BaseService.response=org.jvnet.hk2.internal.SoftAnnotatedElementAnnotationInfo@d916e6}

]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

Comment by _elena_ [ 01/Jul/15 ]

Any news for this bug?

Comment by TechnicalGuru [ 06/Jul/15 ]

I can confirm for Jersey 2.19 - still there.

06-Jul-2015 12:04:23.602 SEVERE [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.loader.WebappClassLoader.checkThreadLocalMapForLeaks The web application [/oventa] created a ThreadLocal with key of type [org.jvnet.hk2.internal.PerLocatorUtilities$1] (value [org.jvnet.hk2.internal.PerLocatorUtilities$1@11fccd70]) and a value of type [java.util.WeakHashMap] (value [{}]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
Comment by Stepan Vavra [ 07/Jul/15 ]

Hi,

we're already investigating this problem (again). And we know that there is a memory leak in Jersey. We were able to reproduce this memory leak only and only with Tomcat and it's CURL REST deployment API with disabled memory leak ThreadLocals prevention ( <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />). (It's enough to not disable this memory leak prevention, and you're just fine.)

By the way, note that this SEVERE log record does not always imply a problem (see this post https://neilmadden.wordpress.com/2014/07/21/threadlocal-variables-and-permgen-memory-leaks-not-always-a-leak/).

Thanks,
Stepan

Comment by scarbo [ 31/Jul/15 ]

I have the same problem using apache-tomcat-8.0.24, is there any work around to solve this? any update on this bug?

Comment by Stepan Vavra [ 10/Aug/15 ]

What kind of problem do you have on your mind? You should not get OutOfMemoryError exception as long as the thread local leak prevention is enabled. In such case everything should be ok. Of course, except for the log record and implied overhead with thread pool management.
If you're concerned with Tomcat's thread pool management; in particular, re-creation of threads from a thread pool, you need to wait for a fix.

Comment by Adam Lindenthal [ 10/Aug/15 ]

Hi, there are some changes on hk2 side, that need to be tested against Jersey if it solves this problem. In the meantime moving to backlog.

Comment by phil-lift [ 28/Aug/15 ]

I have jersey 2.19, with it's dependency : HK2 2.4.0b25

I copied the the updated version of PerLocatorUtilities and the new Hk2ThreadLocal.java in my workspace.

https://github.com/hk2-project/hk2/blob/master/hk2-utils/src/main/java/org/glassfish/hk2/utilities/general/Hk2ThreadLocal.java
https://github.com/hk2-project/hk2/blob/d2631ce0dc6fd9b57635caf8e44f1bd50c7cdf5f/hk2-locator/src/main/java/org/jvnet/hk2/internal/PerLocatorUtilities.java

My Tomcat (7.57 java 7uXX) shutdown logs are now clean.

The only thing that changed in PerLocatorUtilities is the used of the new brand new Hk2ThreadLocal which has not dependency outside of javax.

I feel confident this is an acceptable workaround, until the new release

Phil





[JERSEY-2947] beanFactory.resolveDependency not called within resource Created: 28/Aug/15  Updated: 28/Aug/15

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

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

Tags: UnsatisfiedDependencyException, beanFactory, resolveDependency

 Description   

The problem occurs in a Jersey-Resource.

Context: We add a custom bean factory to the application context, that returns a class-specific SLF4J Logger instance (@see LoggerInjector).
The below described setup works properly for all Spring managed dependencies, but it can’t resolve the Logger instance which is instantiated by the LoggerInjector-beanFactory even if it is part of the application context.

I couldn’t found any limitations on that…
https://hk2.java.net/spring-bridge/

Versions used:
spring: 4.2.0.RELEASE
jersey-spring3 2.21
jersey 2.21

//Our Bean Factory:
public class LoggerInjector extends DefaultListableBeanFactory {

public LoggerInjector() {
}

@Override
public Object resolveDependency(DependencyDescriptor descriptor,
String beanName, Set<String> autowiredBeanNames,
TypeConverter typeConverter) throws BeansException {

if (Logger.class == descriptor.getDependencyType())

{ return LoggerFactory.getLogger(getDeclaringClass(descriptor)); }

else

{ return super.resolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter); }

}

private Class<?> getDeclaringClass(DependencyDescriptor descriptor)

{ return null; //the name of the class declaring the Logger instance" }

}

//Attach BeanFactory to Application Context:
LoggerInjector customBeanFactory = new LoggerInjector();
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(customBeanFactory);

//Our Resource Configuration where we set the application context
ResourceConfig config = new ResourceConfig(MyResource.class);
config.property("contextConfig", context);

//Our Jersey-Resource:

@Component
@Path("api/hello"
public class MyResource {
@Inject
Logger logger; //<- can’t be resolved

@GET
public String getSingle()

{ logger.info("hello"); return "hello"; }

}

//Console output when running the request
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=Logger,parent=MyResource,qualifiers={},position=-1,optional=false,self=false,unqualified=null,1484552)






[JERSEY-2945] Setting host name verifier in Jersey client not honored in AHC connector. Created: 26/Aug/15  Updated: 28/Aug/15

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

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


 Description   

When we set a HostNameVerifier through ClientBuilder, it is not honored by
the ApacheConnector:

clientBuilder.hostnameVerifier(NoopHostnameVerifier.INSTANCE)



 Comments   
Comment by lukho [ 26/Aug/15 ]

Here is a reproducer. Please replace s_sslProviderClient.getDependencies().getSSLContext() with the appropriate SSLContext configured on your system and "https://127.0.0.1:30000/dist-test1/1" with the URL of your resource.

    @Test
    public void sampleTest()
        {
        ClientConfig clientConfig = new ClientConfig();
        clientConfig.connectorProvider(new ApacheConnectorProvider());
        Client client = ClientBuilder.newBuilder()
                .withConfig(clientConfig)
                .register(JacksonMapperProvider.class)
                .register(JacksonFeature.class)
                .hostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .sslContext(s_sslProviderClient.getDependencies().getSSLContext()).build();
        WebTarget target = client.target("https://127.0.0.1:30000/dist-test1/1");
        Response response = target.request().get();
        int status = response.getStatus();
        assertEquals(200 /* OK */, status);
        }
Comment by Marek Potociar [ 28/Aug/15 ]

There is also a partial fix focused on the AHC Connector in this closed pull request:
https://github.com/jersey/jersey/pull/190
Note that there may be a same issue with other connectors too, so ideally, when fixing this issue, we need to go through and fix all the connectors, if needed.





[JERSEY-1450] PartialRequestBuilder.cookie() handles multiple cookies incorrectly Created: 06/Oct/12  Updated: 28/Aug/15

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 1.14, 2.0-m09
Fix Version/s: backlog

Type: Bug Priority: Major
Reporter: BGraversen Assignee: Michal Gajdos
Resolution: Unresolved Votes: 3
Labels: None
Remaining Estimate: 18 hours
Time Spent: 3 hours
Original Estimate: 12 hours
Environment:

Not relevant



 Description   

When building a request, using WebResource.Builder, there is a convenience method for adding cookies to the request, namely cookie(Cookie cookie), which eventually calls PartialRequestBuilder.cookie(Cookie cookie).

The cookie() method simply adds a specific header to the request, looking at the code in PartialRequestBuilder we see that it sets a specific header field.

public T cookie(Cookie cookie)

{ getMetadata().add("Cookie", cookie); return (T)this; }

public T header(String name, Object value)

{ getMetadata().add(name, value); return (T)this; }

The metadata field is a map of lists, and each time a new header with the same name is added, it is added to the list. Eventually the list is serialized into an actual header, and here the toString method on the cookie object messes things up.

It adds a $Version=1 field to the cookie-field for each cookie set, so if more than 1 cookie is added, some servers ignores the cookies, as they cannot parse them correctly (at least the PHP server that I called against did not like the cookie header). Inspecting the cookie header, it also appears to be invalid, here is an example of a call through jersey-client, that has had 2 cookies added

$Version=1;SimpleSAMLAuthToken=_16a3633f6dff1ee29b2c8aab0e8ba98e22f12ac725,$Version=1;PHPSESSID=f9f526f78675c84d337d56dcdefcefff

It puts comma's as separators, and adds the $Version=1 field twice, both of which I'd assume is incorrect with regards to the Cookie header.

I'm currently using a workaround, where I create the Cookie field by hand, and then call header("Cookie", myCookieValue) directly.



 Comments   
Comment by Michal Gajdos [ 22/Oct/12 ]

Cookies in Jersey 1.x are implemented according to RFC 2965 (RFC 2109) which is obsolete. New specification of Cookie processing, defined in RFC 6265 will be implemented (and this problem fixed, see CookieProvider) in Jersey 2 (maybe in Jersey 1.16 or later).

Comment by Michal Gajdos [ 07/Nov/13 ]

Support for new RFC 6265 targeting only for 2.x release of Jersey for now.

Comment by shashwatag [ 13/Sep/14 ]

Using jersey-client version: 1.18, there are 2 issues:
a) In com.sun.jersey.core.impl.provider.header.CookieProvider class, toString() is adding unnecessary fields ($Version, Domain etc) and that too with wrong format. Please refer to the following RFC: http://tools.ietf.org/html/rfc6265#section-5.4 for correct format. ';' is used to separate multiple cookie KV pairs rather than KV fields.
b) In com.sun.jersey.client.urlconnection.URLConnectionClientHandler.java, cookie is serialized as just any other multi-valued header in "writeOutBoundHeaders()". This method separates multiple values with "," which is a wrong separator for Cookies.

I think the cookie flow at the client is completely broken.

Comment by paul_galbraith [ 04/Jun/15 ]

Still not working in 2.17

Comment by bbrooks [ 28/Aug/15 ]

Still broke in 2.18 as well.





[JERSEY-2714] Location header forcibly expanded to absolute path Created: 25/Nov/14  Updated: 27/Aug/15

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

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


 Description   

Unless I'm horribly mistaken:

Current version of Jersey (as of November 2014) seems to have decided that a "Location" header that is set on a response will be forcibly pre-pended with the base path of the application.

Presumably, this is an attempt to comply with the HTTP specification, which does indeed call for an absolute URL in this header.

However, common practice is to use a relative URI instead, and earlier versions (sorry I can't be more specific) used to allow this using the ResponseBuilder . header mechanism, although the Response.created(URI) mechanism has, so far as I'm aware, always expanded the location to absolute (which is why my code uses the header mechanism).

The reason that an absolute URL is a disaster is that it will be wrong in a clustered environment. Normal practice, for this reason, is to use a relative URI, and the W3C notes that a change to the specification to "permit" relative URIs is likely to be made.



 Comments   
Comment by Adam Lindenthal [ 02/Dec/14 ]

Hi Simon, this behaviour was introduced in Jersey 2.3 in September 2013 and yes, it was in order to comply with the HTTP specification.
I guess we should discuss this and maybe introduce a property to make both behaviours possible.
I will move the issue to backlog, so that we can plan the work on it in the future.

Comment by pgilchrist [ 27/Aug/15 ]

The HTTP spec was amended as of June 2014 with RFC 7231 and no longer requires the Location field to be absolute. When absolute Locations are required this causes tremendous headaches in environments where load balancers and especially proxies are present. Can this be bumped in priority?

Comment by SimonHGR [ 27/Aug/15 ]

Indeed... It requires horrible workarounds using filters (unless I missed something) and is seriously troublesome in larger corporate systems (which invariably are subject to URL rewriting outside the service implementation).





[JERSEY-2946] StackOverFlow in org.glassfish.jersey.server.model.Resourse$Builder.toString() Created: 27/Aug/15  Updated: 27/Aug/15

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

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


 Description   

Just updated from 2.14 to 2.21 to get fix on JERSEY-2772

on july 19 : https://github.com/jersey/jersey/commit/3fc485f06b1293cf268631824250933b1172e572

Line 674 to 689

appending parentResource (line 686) causes a StackOverFlow error (when setting up the InMemoryTestContainer in my case)

I guess the parent links to the child that link to the parent thats links the child and so on...



 Comments   
Comment by phil-lift [ 27/Aug/15 ]

Reverting to 2.19 resolves the problem for now.





[JERSEY-2886] RolesAllowedDynamicResource factory sets inappropriate WWW-Authenticate header Created: 11/Jun/15  Updated: 27/Aug/15  Resolved: 27/Aug/15

Status: Resolved
Project: jersey
Component/s: core, security
Affects Version/s: 2.18
Fix Version/s: None

Type: Bug Priority: Major
Reporter: justin.emery Assignee: Petr Bouda
Resolution: Duplicate Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

For Jersey 2.18, RolesAllowedDynamicResource has been changed to return 401 rather than 403 if the user is not authenticated - see JERSEY-2818.

This is fine in principle (I previously used an ExceptionMapper to provide similar functionality), however a 401 error must provide an prompt using the `WWW-Authenticate`. This will typically include a Basic, Digest, or Bearer prompt, but possible others. RolesAllowedDymamicResource will use "User not authorized" which is not helpful - it is a none-standard value, not recognised by browsers or other clients.

Since RolesAllowedDynamicResource has `@Priority(Priorities.AUTHORIZATION)` it will occur after authentication filters where 401 errors (and WWW-Authenticate headers) are usually sent.

I was able to work around this by adding an ExceptionMapper for NotAuthorizedException to return a proper response. However this is not ideal, and I believe everyone using RolesAllowedDynamicResource will need to do this in order to return useful 401 responses.

I believe RolesAllowedDynamicResource needs to provide a way of specifying the WWW-Authenticate if a 401 error is to be returned. An easy solution would be to construct RolesAllowedDynamicResource with a String to be returned as the value for the WWW-Authenticate header.



 Comments   
Comment by justin.emery [ 26/Jun/15 ]

Sorry, this should be referring to RolesAllowedDynamicFeature

Comment by Adam Lindenthal [ 07/Aug/15 ]

Hi, thanks for submiting the issue.
I will move it to backlog and we will plan the work on it in one of the future sprints.

Regards,
Adam

Comment by Petr Bouda [ 27/Aug/15 ]

Duplicate: https://java.net/jira/browse/JERSEY-2908





[JERSEY-2917] @HeaderParam Corrupts Empty String Value Created: 20/Jul/15  Updated: 27/Aug/15  Resolved: 20/Aug/15

Status: Resolved
Project: jersey
Component/s: connectors, core
Affects Version/s: 2.17
Fix Version/s: 2.22

Type: Bug Priority: Minor
Reporter: wulcan Assignee: Petr Bouda
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

If I send a request header with empty string "" as value, Jersey transforms that to a header with value "[null]". If I get it with @HeaderParam



 Comments   
Comment by wulcan [ 20/Jul/15 ]

This seems to depend on the container, I am using Jetty.

Comment by wulcan [ 20/Jul/15 ]

Here's an example that reproduces the bug.

<project
        xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>examples</groupId>
    <artifactId>a</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>a</name>

    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
            <artifactId>jersey-test-framework-provider-jetty</artifactId>
            <version>2.19</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>
Test.java
package examples;

import static org.junit.Assert.assertEquals;

import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;

public class Test extends JerseyTest {
    @Path("a")
    public static class AResource {
        @GET
        public String get(@HeaderParam("a") String value) {
            return value;
        }
    }

    @Override
    protected Application configure() {
        return new ResourceConfig(AResource.class);
    }

    @org.junit.Test
    public void testName() throws Exception {
        assertEquals("", target("a").request().header("a", "").get(String.class));
    }
}
Comment by wulcan [ 20/Jul/15 ]

Suspicious code: org.glassfish.jersey.message.internal.HeaderUtils:165

Comment by wulcan [ 20/Jul/15 ]

Also affects 2.19

Comment by wulcan [ 20/Jul/15 ]

Using @Context HttpHeaders has the same problem.

Comment by Adam Lindenthal [ 06/Aug/15 ]

Hi wulcan. Thanks for reporting.

I will move the issue to backlog, xo that we can take a look at it later on.

Regards,
Adam

Comment by Petr Bouda [ 20/Aug/15 ]

If a header is present in the request and it's null, then a value of this header will be set as empty string.

Comment by wulcan [ 27/Aug/15 ]

Thank you very much!





[JERSEY-2916] UriComponent.decodeQuery does not respect decodeNames flag for name-only params Created: 15/Jul/15  Updated: 26/Aug/15  Resolved: 26/Aug/15

Status: Resolved
Project: jersey
Component/s: core
Affects Version/s: 1.19, 2.19
Fix Version/s: 2.22

Type: Bug Priority: Major
Reporter: matt_f Assignee: Petr Bouda
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The private UriComponent.decodeQueryParam method uses the decodeNames and decodeValues flags when handling query parameters with both a name and value:
https://github.com/jersey/jersey/blob/master/core-common/src/main/java/org/glassfish/jersey/uri/UriComponent.java#L577

params.add((decodeNames) ? URLDecoder.decode(param.substring(0, equals), "UTF-8") : param.substring(0, equals),
           (decodeValues) ? URLDecoder.decode(param.substring(equals + 1), "UTF-8") : param.substring(equals + 1));

However, the decodeNames flag is not used if the query parameter has no value:

https://github.com/jersey/jersey/blob/master/core-common/src/main/java/org/glassfish/jersey/uri/UriComponent.java#L582

  params.add(URLDecoder.decode(param, "UTF-8"), "");


 Comments   
Comment by Adam Lindenthal [ 06/Aug/15 ]

Hi, thanks for reporting. Seems to make sense and should be an easy one-liner fix + test.
In the backlog it goes....

Regards,
Adam

Comment by Petr Bouda [ 26/Aug/15 ]

UriComponent query decoding is driven by a flag.

Comment by matt_f [ 26/Aug/15 ]

Petr, any chance you could also apply this to the Jersey 1.x repo as well? It would be helpful if this was part of a 1.20 release.

Thanks!





[JERSEY-2899] Jersey Doesn't Use HttpUrlConnectorProvider with custom SSLSocketFactory Created: 01/Jul/15  Updated: 26/Aug/15  Resolved: 26/Aug/15

Status: Resolved
Project: jersey
Component/s: None
Affects Version/s: 2.19
Fix Version/s: 2.22

Type: Bug Priority: Major
Reporter: brcolow Assignee: Petr Bouda
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Windows/Mac OS X, JDK 8u60



 Description   

I am trying to use Jersey + JDK's Http(s)UrlConnection to be able to be notified when SSL handshakes occur via an HttpsUrlConnection through a Jersey client. The request goes through (using SSL), and the response comes back (using SSL) but Jersey is not using the SSLSocketFactory that I provide via a connectorProvider that opens an HttpsUrlConnection and calls setSSLSocketFactory() on that connection. The code should make this more clear.

Invocation + Instantiation:

    this.httpClient = getHttpsClient(new DefaultSSLContextProvider());
    Invocation.Builder invBuilder = httpClient.target(API_URL_PRIVATE + API_VERSION_2 + "markets").request(MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN, MediaType.TEXT_HTML);
	invBuilder.header("Content-Type", "application/x-www-form-urlencoded");
	invBuilder.header("User-Agent", USER_AGENT);

	Response response = invBuilder.get();
	logger.debug("response: " + response);

httpClient:

    public Client getHttpsClient(SSLContextProvider sslContextProvider) throws KeyStoreException
    {
        ClientConfig config = new ClientConfig().connectorProvider(new HttpUrlConnectorProvider().connectionFactory(
                url ->
                {
                    HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
                    connection.setSSLSocketFactory(sslContextProvider.getSSLSocketFactory());
                    return connection;
                }));

        return ClientBuilder.newBuilder()
                .withConfig(config)
                .build();
    }

DefaultSSLContextProvider:

	public class DefaultSSLContextProvider implements SSLContextProvider
	{
		private SSLContext sslContext;
		private ObservableSSLSocketFactory observableSSLSocketFactory;

		private static final Logger logger = LoggerFactory.getLogger(DefaultSSLContextProvider.class);

		public DefaultSSLContextProvider()
		{
			try
			{
				TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("X509");
				sslContext = SSLContext.getInstance("SSL");
				KeyStore keyStore = getKeyStore();
				trustManagerFactory.init(keyStore);
				sslContext.init(null, trustManagerFactory.getTrustManagers(), new SecureRandom());
				observableSSLSocketFactory = new ObservableSSLSocketFactory(sslContext);
				HttpsURLConnection.setDefaultSSLSocketFactory(observableSSLSocketFactory);
				SSLContext.setDefault(sslContext);
			}
			catch (NoSuchAlgorithmException e)
			{
				throw new RuntimeException(e);
			}
			catch (KeyManagementException | KeyStoreException e)
			{
				logger.error("could not create DefaultSSLContextProvider", e);
				throw new IllegalStateException(e);
			}
		}

		@Override
		public SSLContext getSSLContext()
		{
			return sslContext;
		}

		@Override
		public SSLSocketFactory getSSLSocketFactory()
		{
			return observableSSLSocketFactory;
		}
		
		@Override
		public KeyStore getKeyStore()
		{
			// snip
		}
	}

ObservableSSLSocketFactory:

	/**
	 * Based heavily on:
	 * http://stackoverflow.com/a/23365536/3634630
	 */
	public class ObservableSSLSocketFactory extends SSLSocketFactory
	{
		private final SSLContext sslContext;
		private final String[] preferredCipherSuites;
		private final String[] preferredProtocols;

		private static final Logger logger = LoggerFactory.getLogger(ObservableSSLSocketFactory.class);

		protected ObservableSSLSocketFactory(SSLContext sslContext)
		{
			logger.debug("CREATING OBSERVABLE SOCKET FACTORY!");
			this.sslContext = sslContext;
			preferredCipherSuites = getCiphers();
			preferredProtocols = getProtocols();
			logger.debug("Observable socket factory created");
			logger.debug("preferredCipherSuites: " + preferredCipherSuites);
			logger.debug("preferredProcotols: " + preferredProtocols);
		}

		@Override
		public String[] getDefaultCipherSuites()
		{
			return preferredCipherSuites;
		}

		@Override
		public String[] getSupportedCipherSuites()
		{
			return preferredCipherSuites;
		}

		public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException
		{
			logger.debug("creating ssl socket");
			SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
			SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(s, host, port, autoClose);

			sslSocket.addHandshakeCompletedListener(new HandshakeListener());
			sslSocket.setEnabledProtocols(preferredProtocols);
			sslSocket.setEnabledCipherSuites(preferredCipherSuites);

			return sslSocket;
		}

		public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException
		{
			logger.debug("creating ssl socket");
			SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
			SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(address, port, localAddress, localPort);

			sslSocket.addHandshakeCompletedListener(new HandshakeListener());
			sslSocket.setEnabledProtocols(preferredProtocols);
			sslSocket.setEnabledCipherSuites(preferredCipherSuites);

			return sslSocket;
		}

		public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException
		{
			logger.debug("creating ssl socket");
			SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
			SSLSocket sslSocket = (SSLSocket)sslSocketFactory.createSocket(host, port, localHost, localPort);

			sslSocket.addHandshakeCompletedListener(new HandshakeListener());
			sslSocket.setEnabledProtocols(preferredProtocols);
			sslSocket.setEnabledCipherSuites(preferredCipherSuites);

			return sslSocket;
		}

		public Socket createSocket(InetAddress host, int port) throws IOException
		{
			logger.debug("creating ssl socket");
			SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
			SSLSocket sslSocket = (SSLSocket)sslSocketFactory.createSocket(host, port);

			sslSocket.addHandshakeCompletedListener(new HandshakeListener());
			sslSocket.setEnabledProtocols(preferredProtocols);
			sslSocket.setEnabledCipherSuites(preferredCipherSuites);

			return sslSocket;
		}

		public Socket createSocket(String host, int port) throws IOException
		{
			logger.debug("creating ssl socket");
			SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
			SSLSocket sslSocket = (SSLSocket)sslSocketFactory.createSocket(host, port);

			sslSocket.addHandshakeCompletedListener(new HandshakeListener());
			sslSocket.setEnabledProtocols(preferredProtocols);
			sslSocket.setEnabledCipherSuites(preferredCipherSuites);

			return sslSocket;
		}

		private String[] getProtocols()
		{
			// snip
		}

		private String[] getCiphers()
		{
			// snip
		}

		class HandshakeListener implements HandshakeCompletedListener
		{
			public HandshakeListener()
			{
				logger.debug("Created new HandshakeListener");
			}

			public void handshakeCompleted(HandshakeCompletedEvent e)
			{
				logger.debug("Handshake successful!");
				logger.debug("using cipher suite: " + e.getCipherSuite());
			}
		}
	}

As I said, no exceptions or errors occur (and indeed the original request goes through with no problem (HTTP 200), however the only things that are logged are:

00:01:37.867CREATING OBSERVABLE SOCKET FACTORY!
00:01:38.072Observable socket factory created
00:01:38.073 preferredCipherSuites: [TLS_ECDHE_ECDSA_WITH256...(snip)]
00:01:38.073 preferredProcotols: [TLSv1, TLSv1.1, TLSv1.2]
00:01:39.435 response: InboundJaxrsResponse{context=ClientResponse{method=GET, uri=https://www.bitstamp.net/api/order_book/, status=200, reason=OK}}

Nothing from `createSocket()`'s or the HandshakeCompletedListener.

I would expect that the log would contain the entries:

creating ssl socket
Handshake successful!
using cipher suite: (blah)

But in fact they don't show up because the code is not executed.



 Comments   
Comment by Adam Lindenthal [ 06/Aug/15 ]

Hi, thanks for reporting the issue and for sharing the test case.
I will move the issue to backlog, so that we can plan the work on it.

Regards,
Adam

Comment by Petr Bouda [ 24/Aug/15 ]

Hi,

I tried to reproduce your bug, but unsuccessfully. Could you provide an entire test using JerseyTest class, which should be easily runnable? I came across several problems when I was trying to compose some test from your provided examples.

Thank you,

Petr

Comment by Petr Bouda [ 26/Aug/15 ]

HttpUrlConnection is able to register a custom socket factory





[JERSEY-2898] Do not set Content Length to -1 for chunked transfer encoding Created: 29/Jun/15  Updated: 25/Aug/15  Resolved: 25/Aug/15

Status: Resolved
Project: jersey
Component/s: core
Affects Version/s: 2.17
Fix Version/s: backlog

Type: Bug Priority: Minor
Reporter: ralphwen Assignee: Libor Kramolis
Resolution: Cannot Reproduce Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The content-length header is set along with "chunked" transfer-encoding header. This causes issues for the receiving entity that is not able to handle this properly such as node/request



 Comments   
Comment by Adam Lindenthal [ 06/Aug/15 ]

Hi, thanks for reporting this.
You probably rather mean not to send the Content-Length header at all, correct?

Moving the issue to backlog, so that we can take a look at it later on.

Regards,
Adam

Comment by Libor Kramolis [ 25/Aug/15 ]

@ralphwen I can not reproduce the issue in Jersey 2.22-SNAPSHOT. Please try to reproduce it with latest Jersey release 2.21. And if you still has a problem, please, prepare reproducible test case. Thanks.





[JERSEY-2914] HK2 based proxies injected into CDI app scoped JAX-RS components break for multiple Jersey apps Created: 15/Jul/15  Updated: 24/Aug/15

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

Type: Bug Priority: Major
Reporter: Jakub Podlesak Assignee: Jakub Podlesak
Resolution: Unresolved Votes: 1
Labels: unplanned
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Blocks
is blocked by HK2-276 Dynamic proxies break in "multiple se... Open
Tags: cdi

 Description   

When multiple Jersey applications are running within a single CDI container,
and they share CDI managed app scoped components, that are getting JAX-RS injected with request scope proxies, the following error occurs:

java.lang.IllegalStateException: Not inside a request scope.
	at jersey.repackaged.com.google.common.base.Preconditions.checkState(Preconditions.java:173)
	at org.glassfish.jersey.process.internal.RequestScope.current(RequestScope.java:233)
	at org.glassfish.jersey.process.internal.RequestScope.findOrCreate(RequestScope.java:158)
	at org.jvnet.hk2.internal.MethodInterceptorImpl.invoke(MethodInterceptorImpl.java:74)
	at org.jvnet.hk2.internal.MethodInterceptorInvocationHandler.invoke(MethodInterceptorInvocationHandler.java:62)

The above exception happens because the HK2 generated proxy invocation handler retains reference
for the first HK2 locator that injects the app scoped component. If any further HTTP requests comes
via a different Jersey app/HK2 locator, then the proxy method invocation handler sticks with the first
locator, and an error occurs.



 Comments   
Comment by Jakub Podlesak [ 24/Aug/15 ]

Reproducer test: https://github.com/jersey/jersey/blob/master/tests/integration/cdi-multimodule/war2/src/test/java/org/glassfish/jersey/tests/integration/multimodule/cdi/web2/JaxRsCdiIntegrationTest.java





[JERSEY-2938] JAX-RS resource marked as @Stateless EJB causes lookup failure Created: 12/Aug/15  Updated: 24/Aug/15  Resolved: 24/Aug/15

Status: Resolved
Project: jersey
Component/s: None
Affects Version/s: None
Fix Version/s: 2.22

Type: Bug Priority: Major
Reporter: payara_steve Assignee: Libor Kramolis
Resolution: Fixed Votes: 0
Labels: pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

A JAX-RS resource in a war file also marked as an @Stateless EJB when mixed with other EJBs in an EJB module causes a javax.naming.NamingException and failure it initialise EJB injection.

See testcase at https://github.com/payara/Payara/issues/394

Jersey tries to look up the JAX-RS EJB with an incorrect module name. Specifically the module name of other EJBs. For example in the test case above;

Resource EJB is deployed as;
Portable JNDI names for EJB Resource: [java:global/test-ear-0.0.1-SNAPSHOT/test-war-0.0.1-SNAPSHOT/Resource!net.trajano.test.Resource, java:global/test-ear-0.0.1-SNAPSHOT/test-war-0.0.1-SNAPSHOT/Resource]]]

Jersey attempts to lookup;

[2015-08-12T20:42:56.671+0100] [Payara 4.1] [WARNING] [] [org.glassfish.jersey.gf.ejb.internal.EjbComponentProvider] [tid: _ThreadID=30 _ThreadName=http-listener-1(3)] [timeMillis: 1439408576671] [levelValue: 900] [[

An instance of EJB class, net.trajano.test.Resource, 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/test-ejb2-0.0.1-SNAPSHOT/Resource' 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/test-ejb2-0.0.1-SNAPSHOT/Resource]

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:417)

at javax.naming.InitialContext.lookup(InitialContext.java:417)

Another EJB is deployed at;
[2015-08-12T20:42:41.554+0100] [Payara 4.1] [INFO] [AS-EJB-00054] [javax.enterprise.ejb.container] [tid: _ThreadID=43 _ThreadName=admin-listener(2)] [timeMillis: 1439408561554] [levelValue: 800] [[

Portable JNDI names for EJB HelloEjb2: [java:global/test-ear-0.0.1-SNAPSHOT/test-ejb2-0.0.1-SNAPSHOT/HelloEjb2, java:global/test-ear-0.0.1-SNAPSHOT/test-ejb2-0.0.1-SNAPSHOT/HelloEjb2!net.trajano.test.api.Hello2]]]



 Comments   
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 payara_steve [ 15/Aug/15 ]

This patches the issue

diff --git a/containers/glassfish/jersey-gf-ejb/src/main/java/org/glassfish/jersey/gf/ejb/internal/EjbComponentProvider.java b/containers/glassfish/jersey-gf-ejb/src/main/java/org/glassfish/jersey/gf/ejb/internal/EjbComponentProvider.java
index 3568274..2bc9991 100644
--- a/containers/glassfish/jersey-gf-ejb/src/main/java/org/glassfish/jersey/gf/ejb/internal/EjbComponentProvider.java
+++ b/containers/glassfish/jersey-gf-ejb/src/main/java/org/glassfish/jersey/gf/ejb/internal/EjbComponentProvider.java
@@ -197,7 +197,7 @@
             final List<String> tempLibNames = new LinkedList<>();
             for (ModuleInfo moduleInfo : appInfo.getModuleInfos()) {
                 final String jarName = moduleInfo.getName();
-                if (jarName.endsWith(".jar")) {
+                if (jarName.endsWith(".jar") || jarName.endsWith(".war")) {
                     final String moduleName = jarName.substring(0, jarName.length() - 4);
                     tempLibNames.add(moduleName);
                     final Object bundleDescriptor = moduleInfo.getMetaData(EjbBundleDescriptorImpl.class.getName());
Comment by payara_steve [ 20/Aug/15 ]

Created Pull request https://github.com/jersey/jersey/pull/189

Comment by Libor Kramolis [ 24/Aug/15 ]

Integration test will be submitted separately.





[JERSEY-2239] Unable to parse "If-None-Match" header value Created: 21/Nov/13  Updated: 24/Aug/15

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

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-2840] jersey-apache-connector.jar missing OSGI properties Created: 10/Apr/15  Updated: 24/Aug/15

Status: Open
Project: jersey
Component/s: connectors, osgi
Affects Version/s: None
Fix Version/s: backlog

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


 Description   

Please add OSGI bundle properties to jersey-apache-connector.jar.



 Comments   
Comment by Adam Lindenthal [ 10/Aug/15 ]

Hi, thanks for reporting. I will put the issue to backlog, so that we can look at it later.

Regards,
Adam

Comment by konstantina___ [ 17/Aug/15 ]

Hi,
I've made a patch for the apache connector OSGi manifest properties.
I've added the maven-bundle-plugin execution to the pom file of the artifact following the adopted plugin execution in the other jersey artifacts.

The patch is uploaded here https://gist.github.com/tinchooU/8c7aecc073cb9026cc3d

If you could please review the change.

Thank you in advance.

BR,
Tina

Comment by Adam Lindenthal [ 21/Aug/15 ]

Hi Konstantina,

thank you for your patch. Technically, we cannot review and accept your change, as you are not a registered Jersey contributor (= you have not signed and sent the Oracle Contributor Agreement - OCA). You can, of course become one, if you'd like to.

However, with such a small patch, our change will most likely not differ much from yours

Regards,
Adam

Comment by konstantina___ [ 24/Aug/15 ]

Hi Adam,

since the fix is relatively small, I've added it to gist and didn't go through the whole contributing procedure for it.
Since your change will most likely not differ from the patch, could you add the OSGi properties soon?

My idea was to provide a quick help about the fix.

Regards,
Tina





[JERSEY-2924] Allow kryo serialization of objects without no-args constructor Created: 29/Jul/15  Updated: 24/Aug/15

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

Type: Improvement Priority: Minor
Reporter: stefanobortoli Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: incomplete
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Playing around with the new Kryo serialization media type, we hit the problem of not being able to deserialize javax.xml.namespace.QName which does not have a 'no-args' constructor.

This is possible using for example the kryo instantiation strategy of objenesis (http://objenesis.org/)

<dependency>
<groupId>org.objenesis</groupId>
<artifactId>objenesis</artifactId>
<version>2.1</version>
</dependency>

This is very important to allow serialization of legacy objects, or objects not under the control of the developer.



 Comments   
Comment by Adam Lindenthal [ 05/Aug/15 ]

Hi Stefano,

thanks for reporting the issue. Please note, that the Kryo feature is in the incubator module, which marks it as being not really finished or not really production ready - and not really our current priority to focus on. Hence, I have to significantly lower the priority, as this field has to be taken "globally" - not how critical th bug is for the Kryo feature, but for Jersey as a whole.

I will put the issue to backlog, but personally I don't expect it to be fixed very quickly, as there are many issues with higher real importance.
However, there is still a possibility of creating a pull request - for more information, please see: https://jersey.java.net/scm.html

Regards,
Adam

Comment by Adam Lindenthal [ 05/Aug/15 ]

One more thing - if you decide not to improve the module yourself by providing a pull request, at least sharing your testcase (or creating one) or some minimalistic app, that shows the problem in real context would be appreciated.

Thanks.

Comment by stefanobortoli [ 05/Aug/15 ]

Hi Adam, I understand the low priority. However, the fix is very simple and included in the open ticket. I fixed it for my purposes, but I am far from being able to tell that we can go for a pull request. About your request of an example, I had the issue of serializing an object that was containing a javax QName. If you serialize user defined POJOs, one can work around these issues, but if you are working with legacy services (in my case, we are porting SOAP WS to REST) where data structures cannot be easily changed, then you start having problems. Fast serialization when you have high number of calls improves considerably performances, specially in SaaS architectures.

Comment by Libor Kramolis [ 10/Aug/15 ]

Hi. It is strange, because Kryo itself HAS dependency on Objenesis.

Whenever I execute mvn dependency:tree in incubator/kryo module I get:

[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ jersey-media-kryo ---
[INFO] org.glassfish.jersey.media:jersey-media-kryo:jar:2.20-SNAPSHOT
[INFO] +- javax.ws.rs:javax.ws.rs-api:jar:2.0.1:provided
[INFO] +- org.glassfish.jersey.core:jersey-common:jar:2.20-SNAPSHOT:compile
[INFO] |  +- javax.annotation:javax.annotation-api:jar:1.2:compile
[INFO] |  +- org.glassfish.jersey.bundles.repackaged:jersey-guava:jar:2.20-SNAPSHOT:compile
[INFO] |  +- org.glassfish.hk2:hk2-api:jar:2.4.0-b27:compile
[INFO] |  |  +- org.glassfish.hk2:hk2-utils:jar:2.4.0-b27:compile
[INFO] |  |  \- org.glassfish.hk2.external:aopalliance-repackaged:jar:2.4.0-b27:compile
[INFO] |  +- org.glassfish.hk2.external:javax.inject:jar:2.4.0-b27:compile
[INFO] |  +- org.glassfish.hk2:hk2-locator:jar:2.4.0-b27:compile
[INFO] |  |  \- org.javassist:javassist:jar:3.18.1-GA:compile
[INFO] |  \- org.glassfish.hk2:osgi-resource-locator:jar:1.0.1:compile
[INFO] +- com.esotericsoftware:kryo:jar:3.0.2:compile
[INFO] |  +- com.esotericsoftware:reflectasm:jar:1.10.1:compile
[INFO] |  |  \- org.ow2.asm:asm:jar:5.0.3:compile
[INFO] |  +- com.esotericsoftware:minlog:jar:1.3.0:compile
[INFO] |  \- org.objenesis:objenesis:jar:2.1:compile
[INFO] \- org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-grizzly2:jar:2.20-SNAPSHOT:test
[INFO]    +- org.glassfish.jersey.test-framework:jersey-test-framework-core:jar:2.20-SNAPSHOT:test
[INFO]    |  +- org.glassfish.jersey.core:jersey-server:jar:2.20-SNAPSHOT:test
[INFO]    |  |  +- org.glassfish.jersey.core:jersey-client:jar:2.20-SNAPSHOT:test
[INFO]    |  |  +- org.glassfish.jersey.media:jersey-media-jaxb:jar:2.20-SNAPSHOT:test
[INFO]    |  |  \- javax.validation:validation-api:jar:1.1.0.Final:test
[INFO]    |  +- org.glassfish.jersey.containers:jersey-container-servlet-core:jar:2.20-SNAPSHOT:test
[INFO]    |  \- javax.servlet:javax.servlet-api:jar:3.0.1:test
[INFO]    +- org.glassfish.jersey.containers:jersey-container-grizzly2-http:jar:2.20-SNAPSHOT:test
[INFO]    |  \- org.glassfish.grizzly:grizzly-http-server:jar:2.3.19:test
[INFO]    |     \- org.glassfish.grizzly:grizzly-http:jar:2.3.19:test
[INFO]    |        \- org.glassfish.grizzly:grizzly-framework:jar:2.3.19:test
[INFO]    +- org.glassfish.jersey.containers:jersey-container-grizzly2-servlet:jar:2.20-SNAPSHOT:test
[INFO]    |  +- org.glassfish.jersey.containers:jersey-container-servlet:jar:2.20-SNAPSHOT:test
[INFO]    |  \- org.glassfish.grizzly:grizzly-http-servlet:jar:2.3.19:test
[INFO]    +- junit:junit:jar:4.12:test
[INFO]    |  \- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO]    \- org.ow2.asm:asm-debug-all:jar:5.0.4:test

And you can see Kryo transitive dependency on org.objenesis:objenesis:jar:2.1:compile.

Comment by Libor Kramolis [ 10/Aug/15 ]

@stefanobortoli Could you try mvn dependency:tree on your project if you see the objenesis there?

Comment by stefanobortoli [ 24/Aug/15 ]

Yes, Kryo 3.0.2 has objenesis has a dependency. Then the only thing missing is to override the default instantiation strategy with the standard objenesis standard factory in the kryo message body provider.

public KryoMessageBodyProvider() {
final KryoFactory kryoFactory = new KryoFactory() {
public Kryo create()

{ final Kryo kryo = new Kryo(); //TODO: configure kryo instance, customize settings //TODO: e.g. looking for Kryo via ContextResolver (like Jackson) kryo.setInstantiatorStrategy(new DefaultInstantiatorStrategy(new StdInstantiatorStrategy())); return kryo; }

};
kryoPool = new KryoPool.Builder(kryoFactory).softReferences().build();
}

This solved the issue for me. However, it would be interesting to have a kryofactory passed as a parameter somewhere. So, if I need to register classes I can do it in my custom kryo factory. MY2C.





[JERSEY-2934] ChunkedInput.FixedBoundaryParser fails if last byte of data is the same as first byte of boundary delimiter Created: 05/Aug/15  Updated: 24/Aug/15  Resolved: 24/Aug/15

Status: Resolved
Project: jersey
Component/s: core
Affects Version/s: 2.19
Fix Version/s: 2.22

Type: Bug Priority: Minor
Reporter: vladimir.eatwell Assignee: Petr Bouda
Resolution: Fixed Votes: 0
Labels: client
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

org.glassfish.jersey.client.ChunkedInput contains a class FixedBoundaryParser for parsing objects from chunked http responses.

The algorithm in #readChunk(InputStream in) which tries to match the bytes being read to the boundary delimiter bytes puts sequences of bytes that match the beginning of the boundary delimiter into a separate buffer, if it finds a mismatch it assumes the sequence matched so far is all data and pushes it to the data buffer, resetting the delimiter match buffer, e.g.:

boundary bytes = 123456
input = 123457
12345 is pushed to the delimiter matching buffer, when '7' is read, the matching buffer is pushed to the data buffer and the '7' is pushed to the data buffer also.

This method fails to correctly identify the boundary delimiter in the following cases:

boundary bytes = 123456
input = 1123456

'1' is written to the matching buffer - but when the next '1' is read, the '1' from the matching buffer is written to the data buffer, followed by the '1' just read. Because the second '1' is not written to the matching buffer, the algorithm fails to match the '123456' sequence.

It also fails if any sequence of bytes matching a prefix of the delimiter bytes precedes the delimiter, e.g.:

boundary bytes = 123456
input = 12345123456

failing test:

import org.glassfish.jersey.client.ChunkParser;
import org.glassfish.jersey.client.ChunkedInput;
import org.junit.Test;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public class ChunkParserTest {

	@Test
	public void delimiterParsingFails() throws IOException {
		ChunkParser parser = ChunkedInput.createParser("123456");
		InputStream input = new ByteArrayInputStream("11234567".getBytes());
		byte[] chunk = parser.readChunk(input);
		assertThat(new String(chunk), is("1"));
	}
}


 Comments   
Comment by vladimir.eatwell [ 05/Aug/15 ]

We have worked around the issue by using the following custom boundary parser:

import org.glassfish.jersey.client.ChunkParser;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;

public class CustomChunkParser implements ChunkParser {

	private final byte[] delimiter;

        public CustomChunkParser(byte[] delimiter) {
            this.delimiter = delimiter;
        }

	@Override
	public byte[] readChunk(InputStream inputStream) throws IOException {

		// Data buffer. Bytes are first pushed into the delimiter buffer and then evicted into the main buffer.
		ByteArrayOutputStream buffer = new ByteArrayOutputStream();

		// A circular buffer used to hold bytes as they are read.
		CircularBuffer delimiterBuffer = new CircularBuffer(delimiter.length);

		int data;
		do {
			do {
				data = inputStream.read();

				if (data == -1) {
					// Dump the contents of the delimiter buffer into the output buffer.
					delimiterBuffer.dump(buffer);
					break;
				}

				int popped = delimiterBuffer.push(data);
				if (popped != -1) {
					buffer.write((byte) popped);
				}

				if (delimiterBuffer.equals(delimiter)) {
					delimiterBuffer.reset();
					break;
				}
			} while (true);
		} while (data != -1 && buffer.size() == 0);

		if (buffer.size() > 0) {
			return buffer.toByteArray();
		} else {
			return null;
		}
	}

	private static class CircularBuffer {
		private final int[] buffer;
		private int cursor;

		CircularBuffer(int size) {
			buffer = new int[size];
			reset();
		}

		/**
		 * Add a byte to the buffer
		 * @param datum byte to push (as an int due to signage issues)
		 * @return the byte popped from the buffer to make room for the new one, may be -1 indicating no byte was popped.
		 */
		int push(int datum) {
			int retVal = buffer[cursor];
			buffer[cursor] = datum;
			cursor = (cursor + 1) % buffer.length;
			return retVal;
		}

		boolean equals(byte[] match) {
			for (int ii = 0; ii < match.length; ii++) {
				int offset = (cursor + ii) % buffer.length;

				if (buffer[offset] == -1) {
					return false;
				} else if (match[ii] != (byte)(buffer[offset])) {
					return false;
				}
			}
			return true;
		}

		/**
		 * Dump the contents of the buffer
		 * @param outputStream stream to dump to
		 */
		void dump(OutputStream outputStream) throws IOException {
			for (int ii = 0; ii < buffer.length; ii++) {
				int offset = (cursor + ii) % buffer.length;
				if (buffer[offset] != -1) {
					outputStream.write(buffer[offset]);
				}
			}
		}

		void reset() {
			cursor = 0;
			Arrays.fill(buffer, -1);
		}
	}
}
Comment by Adam Lindenthal [ 06/Aug/15 ]

Hi Vladimir,

thanks for reporting the issue. I will put it to backlog, so that we can plan the work on it in one of the next sprints.

Regards,
Adam

Comment by Petr Bouda [ 24/Aug/15 ]

FixedBoudaryParser fixed for multiple-chars delimiters.





[JERSEY-2832] Inconsistent behavior using @BeanParam, a ParamConverter, and an ExceptionMapper Created: 30/Mar/15  Updated: 21/Aug/15  Resolved: 21/Aug/15

Status: Resolved
Project: jersey
Component/s: None
Affects Version/s: 2.17
Fix Version/s: 2.22

Type: Bug Priority: Major
Reporter: atomala Assignee: Petr Bouda
Resolution: Fixed Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: Zip Archive jerseyDemo-master.zip    

 Description   

This bug only seems to be happening when using a custom ParamConverter, a @BeanParam wrapper object, and a custom ExceptionMapper.

I am using a custom ParamConverter for some of my @QueryParam and @PathParam objects. When the ParamConverter throws a custom exception because it couldn't be converted correctly (i.e. bad parameters passed in), Jersey will catch my custom exception and wrap it in a ParamException.QueryParamException or a ParamException.PathParamException. I can write my exception handling logic to unwrap the Jersey exception and get my custom exception and then I am able to return a useful error message to the user using the ExceptionMapper.

When I use a @BeanParam object with the exact same @QueryParam and @PathParam objects contained within, the behavior is not the same. If an error is thrown in the ParamConverter, Jersey catches the exception and throws a NotFoundException instead of a ParamException.QueryParamException or a ParamException.PathParamException. It is not possible to create a custom error message since there is no context in the NotFoundException, which is also thrown when an endpoint is not found. It seems like Jersey should still throw a ParamException.QueryParamException or a ParamException.PathParamException instead of a NotFoundException when using the @BeanParam wrapper object.

I have switched my code to use the @QueryParam and @PathParam objects and manually mapped them to my bean object. It would be much nicer to use the @BeanParam object instead to keep my code clean.



 Comments   
Comment by Libor Kramolis [ 01/Apr/15 ]

Hello @atomala and thanks for issue report. May you provide us reproducible test case? E.g. simple JerseyTest app to reproduce the problem. Thanks.

Comment by atomala [ 07/Apr/15 ]

@Libor I have created a test application. How can I upload it to this ticket? I don't have the ability to attach anything.

Comment by Libor Kramolis [ 08/Apr/15 ]

@atomala Thanks. May you store it in https://gist.github.com/?

Comment by atomala [ 09/Apr/15 ]

@Libor

I just put the project on github since it's a complete project. It's built using maven and spring-boot. If you clone it and run the following command, it will start the jersey application on port 8080.

mvn clean verify spring-boot:run

There is documentation in the DemoController class that contains the curl messages that produce the error.

If you have any questions about the project, please let me know.

https://github.com/atomala1/jerseyDemo

Comment by atomala [ 04/May/15 ]

Any update on this issue?

Comment by cdeszaq [ 02/Jun/15 ]

This looks like it was also reported in 2013: http://stackoverflow.com/q/19825795/20770

Comment by Adam Lindenthal [ 05/Aug/15 ]

Uploading the reproducer app from atomala.

Comment by Adam Lindenthal [ 05/Aug/15 ]

Moving the issue to backlog, so that it can be worked on in one of the future sprints.

Cheers,
Adam

Comment by Petr Bouda [ 21/Aug/15 ]

Propagation of an exception from BeanParam converter through HK2 framework and throw the proper exception in ParamValueHelper.





[JERSEY-2860] When setting a new baseUri in a prematching filter, Reponse.created() still uses old baseUri Created: 12/May/15  Updated: 21/Aug/15

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

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

Issue Links:
Related
is related to JERSEY-2838 Response.created(URI) does not conver... Open

 Description   

Given the following filter:

@PreMatching
@Priority(10)
public class BaseUriFromProxyValuesFilter implements ContainerRequestFilter {
    baseUri = URI.create("https://www.google.com");
    requestContext.setRequestUri(baseUri, requestUri);
}

And the following resource:

  @Path('/')
  public static class TestResource {

    @GET
    @Path("/here")
    static Response redirectToRelativePath(@Context ContainerRequestContext requestContext) {
      Response.created(URI.create("/somewhere")).build()
    }

  }

When:
the container is running at http://localhost:8080

I expect:
The location header to contain: https://www.google.com/somewhere

But I see:
The location header containing http://localhost:8080/somewhere

The reason for this is that

OutboundJaxrsResponse.Builder.setBaseUri(baseUri);

In the ServerRuntime is called before the prematching phase of the request and is not updated when a prematching filter changes the base uri.

I can't get master (or tag 1.17) to build so sadly I can't create a pull request for this bug. Hopefully this is enough info to fix the runtime.

What probably will do the trick is change ContainerRequest#setRequestUri(Uri, Uri) to:

    @Override
    public void setRequestUri(URI baseUri, URI requestUri) throws IllegalStateException {
        if (!uriRoutingContext.getMatchedURIs().isEmpty()) {
            throw new IllegalStateException("Method could be called only in pre-matching request filter.");
        }

        this.encodedRelativePath = null;
        this.decodedRelativePath = null;
        this.absolutePathUri = null;
        this.uriRoutingContext.invalidateUriComponentViews();
        OutboundJaxrsResponse.Builder.setBaseUri(baseUri);

        this.baseUri = baseUri;
        this.requestUri = requestUri;
    }


 Comments   
Comment by Adam Lindenthal [ 15/May/15 ]

Hi wouterdanes,

thanks for creating the issue. I will move the issue to backlog, so that we can work on it later on.

Regards,
Adam

Comment by Adam Lindenthal [ 15/May/15 ]

I linked JERSEY-2838, as those might be loosely related. Might make sense to solve those two together.

Comment by wouterdanes [ 15/May/15 ]

I can help out if you want, just need to get the build going. Is there any specifics I need to know?

Comment by Adam Lindenthal [ 18/May/15 ]

You mean contributing via pull request? Sure, that's appreciated.

General information can be found at: https://jersey.java.net/scm.html#/Submitting_Patches_and_Contribute_Code

I noticed, that you reported, that the version 2.16 is affected, so as a first step, you need to test it against latest snapshot.
Once you have the git repository cloned (you don't need the entire history, so you can limit the depth), you should be able to build the sources with mvn clean install. You only need the Java 7 SE JDK and having the internet connection set up correctly (proxies, etc.) from your shell, as the build downloads artifacts from maven central. You can skip the tests for the first time (-Dmaven.test.skip=true), so that you don't have to wait for the entire full build.

Does that answer your question or did you mean something else?

Regards,
Adam

Comment by Adam Lindenthal [ 21/Aug/15 ]

Oh, now I read it again, you mean specifics regarding the build? I don't know about any. What problems are you experiencing? In what environment (JDK, maven version, OS)?

Comment by Adam Lindenthal [ 21/Aug/15 ]

Anyway, I am already doing some changes in that area, so you don't need to provide a pull request. I rather mean it generally, if you'd like to build Jersey and maybe start contributing in some other manner.





[JERSEY-2906] Jersey-gf-cdi contanins dependency to javax.transaction-api Created: 09/Jul/15  Updated: 21/Aug/15  Resolved: 06/Aug/15

Status: Resolved
Project: jersey
Component/s: infrastructure
Affects Version/s: 2.14
Fix Version/s: 2.15

Type: Bug Priority: Minor
Reporter: gdemecki Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I've included jersey-gf-cdi-2.14.jar to make my Jersey + Weld + Jetty app work.

  <!-- Jersey -->
  <dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>${jersey.version}</version>
  </dependency>
  <dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-client</artifactId>
    <version>${jersey.version}</version>
  </dependency>

  <!-- Jersey with Weld -->
  <dependency>
    <groupId>org.glassfish.jersey.containers.glassfish</groupId>
    <artifactId>jersey-gf-cdi</artifactId>
    <version>${jersey-gf-cdi.version}</version>
  </dependency>
  <dependency>
    <groupId>org.glassfish.jersey.containers.glassfish</groupId>
    <artifactId>jersey-gf-cdi-ban-custom-hk2-binding</artifactId>
    <version>${jersey-gf-cdi.version}</version>
  </dependency>

But unfortunately I've got exception:

org.jboss.weld.resources.spi.ResourceLoadingException: Error while loading class org.glassfish.jersey.gf.cdi.internal.TransactionalExceptionMapper
	at org.jboss.weld.resources.ClassTransformer.getBackedAnnotatedType(ClassTransformer.java:186)
	at org.jboss.weld.resources.ClassTransformer.getBackedAnnotatedType(ClassTransformer.java:194)
	at org.jboss.weld.manager.BeanManagerImpl.createAnnotatedType(BeanManagerImpl.java:1178)
	at org.jboss.weld.util.ForwardingBeanManager.createAnnotatedType(ForwardingBeanManager.java:196)
	at org.glassfish.jersey.gf.cdi.internal.CdiComponentProvider.beforeBeanDiscovery(CdiComponentProvider.java:656)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:497)
	at org.jboss.weld.injection.MethodInjectionPoint.invokeOnInstanceWithSpecialValue(MethodInjectionPoint.java:90)
	at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:271)
	at org.jboss.weld.event.ExtensionObserverMethodImpl.sendEvent(ExtensionObserverMethodImpl.java:121)
	at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:258)
	at org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:237)
	at org.jboss.weld.event.ObserverNotifier.notifyObserver(ObserverNotifier.java:174)
	at org.jboss.weld.event.ObserverNotifier.notifyObservers(ObserverNotifier.java:133)
	at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:107)
	at org.jboss.weld.bootstrap.events.AbstractContainerEvent.fire(AbstractContainerEvent.java:54)
	at org.jboss.weld.bootstrap.events.AbstractDefinitionContainerEvent.fire(AbstractDefinitionContainerEvent.java:42)
	at org.jboss.weld.bootstrap.events.BeforeBeanDiscoveryImpl.fire(BeforeBeanDiscoveryImpl.java:45)
	at org.jboss.weld.bootstrap.WeldStartup.startInitialization(WeldStartup.java:344)
	at org.jboss.weld.bootstrap.WeldBootstrap.startInitialization(WeldBootstrap.java:76)
	at org.jboss.weld.environment.servlet.WeldServletLifecycle.initialize(WeldServletLifecycle.java:105)
	at org.jboss.weld.environment.servlet.Listener.contextInitialized(Listener.java:63)
	at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:794)
	at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:522)
	at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:785)
	at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:341)
	at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1357)
	at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1350)
	at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:734)
	at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:258)
	at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:512)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
	at org.eclipse.jetty.server.Server.start(Server.java:405)
	at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
	at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
	at org.eclipse.jetty.server.Server.doStart(Server.java:372)
	at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
	at com.xyz.AppRunner.startJettyJersey_AndWeld(AppRunner.java:47)
	at com.xyz.AppRunner.main(AppRunner.java:19)
Caused by: java.lang.NoClassDefFoundError: javax/transaction/TransactionalException
	at java.lang.Class.getDeclaredConstructors0(Native Method)
	at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
	at java.lang.Class.getDeclaredConstructors(Class.java:2020)
	at org.jboss.weld.security.GetDeclaredConstructorsAction.run(GetDeclaredConstructorsAction.java:30)
	at org.jboss.weld.security.GetDeclaredConstructorsAction.run(GetDeclaredConstructorsAction.java:22)
	at java.security.AccessController.doPrivileged(Native Method)
	at org.jboss.weld.annotated.slim.backed.BackedAnnotatedType$BackedAnnotatedConstructors.computeValue(BackedAnnotatedType.java:161)
	at org.jboss.weld.annotated.slim.backed.BackedAnnotatedType$BackedAnnotatedConstructors.computeValue(BackedAnnotatedType.java:158)
	at org.jboss.weld.util.LazyValueHolder.get(LazyValueHolder.java:35)
	at org.jboss.weld.annotated.slim.backed.BackedAnnotatedType$EagerlyInitializedLazyValueHolder.<init>(BackedAnnotatedType.java:154)
	at org.jboss.weld.annotated.slim.backed.BackedAnnotatedType$BackedAnnotatedConstructors.<init>(BackedAnnotatedType.java:158)
	at org.jboss.weld.annotated.slim.backed.BackedAnnotatedType$BackedAnnotatedConstructors.<init>(BackedAnnotatedType.java:158)
	at org.jboss.weld.annotated.slim.backed.BackedAnnotatedType.<init>(BackedAnnotatedType.java:64)
	at org.jboss.weld.annotated.slim.backed.BackedAnnotatedType.of(BackedAnnotatedType.java:47)
	at org.jboss.weld.resources.ClassTransformer$TransformClassToBackedAnnotatedType.load(ClassTransformer.java:83)
	at org.jboss.weld.resources.ClassTransformer$TransformClassToBackedAnnotatedType.load(ClassTransformer.java:80)
	at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3589)
	at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2374)
	at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2337)
	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2252)
	at com.google.common.cache.LocalCache.get(LocalCache.java:3990)
	at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:3994)
	at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:4878)
	at org.jboss.weld.util.cache.LoadingCacheUtils.getCacheValue(LoadingCacheUtils.java:52)
	at org.jboss.weld.util.cache.LoadingCacheUtils.getCastCacheValue(LoadingCacheUtils.java:80)
	at org.jboss.weld.resources.ClassTransformer.getBackedAnnotatedType(ClassTransformer.java:175)
	... 41 more
Caused by: java.lang.ClassNotFoundException: javax.transaction.TransactionalException
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	... 67 more

The reason is obvious: TransactionalExceptionMapper shipped with library, has a reference to javax.transaction.TransactionalException from javax.transaction-api.

So it seems that I cannot use Jersey inside Jetty or Tomcat without Java Transaction API on the classpath. Weird.

Workaround is obvious, I have to add dependency to transaction-api:

    <dependency>
      <groupId>javax.transaction</groupId>
      <artifactId>javax.transaction-api</artifactId>
      <version>1.2</version>
    </dependency>

Can somebody fix this idiosyncrasy?



 Comments   
Comment by Adam Lindenthal [ 06/Aug/15 ]

Hi, thanks for reporting the issue.
The structure of the cdi integration modules has changed heavily since 2.14, which renders this issue no more valid.
See: https://github.com/jersey/jersey/tree/master/ext/cdi as a starting point.

I will close this now, feel free to contact us if you disagree.

Regards,
Adam

Comment by gdemecki [ 19/Aug/15 ]

But jersey-gf-cdi doesn't have a released version above 2.14.
So along with Weld 2.x am I supposed to use jersey-cdi1x-servlet or jersey-cdi1x (or both)?

Thanks in advance for clarification.

Comment by Adam Lindenthal [ 21/Aug/15 ]

Indeed, the structure has changed, jersey-gf-cdi has been replaced by multiple modules. You seem to be running in servlet container (jetty), so you will need jersey-cdi1x-servlet dependency. If you would like to run out of the servlet environment, you would need to use jersey-weld-se module. Both do have (transitive) dependencies on jersey-cdi1x, so you don't need to declare the dependency, but the jar will (among others) appear on your classpath.

More info about this change can be found in 2.14 to 2.15 migration guide.
You can also take a look at our cdi-web and helloworld-weld examples.

Hope this helps,
Adam





[JERSEY-2918] nonascii character in header causes ArrayIndexOutOfBoundsException in HttpHeaderReaderImpl Created: 22/Jul/15  Updated: 21/Aug/15  Resolved: 21/Aug/15

Status: Resolved
Project: jersey
Component/s: core
Affects Version/s: 1.9
Fix Version/s: 2.22

Type: Bug Priority: Major
Reporter: chibichii Assignee: Petr Bouda
Resolution: Cannot Reproduce Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Nonascii character in a header can cause an ArrayIndexOutOfBoundsException. The cause seems to be that the code in
HttpHeaderReaderImpl (or more specifically, in the TYPE_TABLE in GrammarUtil has only 127 elements, but if a two byte unicode character beginning with byte 127 or higher is present, then this AIOB occurs.

See stacktrace snippet below:

21-Jul-2015 08:01:59.230 SEVERE [http-nio-8081-exec-75] null.null Mapped exception to response: 500 (Internal Server Error)
 java.lang.ArrayIndexOutOfBoundsException: 194
        at com.sun.jersey.core.header.reader.HttpHeaderReaderImpl.hasNextSeparator(HttpHeaderReaderImpl.java:153)
        at com.sun.jersey.core.header.reader.HttpHeaderListAdapter.hasNext(HttpHeaderListAdapter.java:68)
        at com.sun.jersey.core.header.AcceptableLanguageTag.<init>(AcceptableLanguageTag.java:65)
        at com.sun.jersey.core.header.reader.HttpHeaderReader$8.create(HttpHeaderReader.java:418)
        at com.sun.jersey.core.header.reader.HttpHeaderReader$8.create(HttpHeaderReader.java:416)


 Comments   
Comment by Adam Lindenthal [ 06/Aug/15 ]

Hi chibichii, thanks for noticing this issue.

Well, we shall indeed fix the code, so that it does not throw AIOOBE during the test if the character is a token.
On the other hand, using unicode in headers does is not necessarily a good practice.

Anyway, the same code is also shared by Jersey 2.x, so I'll add 2.19 into affected versions.

Please note, that the release cycle for the 1.x version is not very frequent now, as the version is basically only maintained. It might take longer until the fix is propagated to a stable version with a release.

I am moving the issue to backlog, so that we can take a look at it later on.

Regards,
Adam

Comment by Petr Bouda [ 20/Aug/15 ]

Hi Chibichii,

could you please provide any example, because in current version I am not able to reproduce your problem. Header values represented by Unicode characters are successfully injected into the given resource method, but the value is badly decoded (strange characters) because in reality all you can put in an HTTP header is simply ASCII. You can use UTF8+BASE64 encoding extension presented in http://www.ietf.org/rfc/rfc2047.txt

Comment by Petr Bouda [ 21/Aug/15 ]

No ArrayIndexOutOfBoundsException thrown, headers with UNICODE chars can be gained from a container (tested on Grizzly and Jetty), but there are some inappropriate chars because of encoding in the case of non-ASCII.





[JERSEY-2944] Overflow in org.glassfish.jersey.server.model.Resource$Builder.toString(); Created: 20/Aug/15  Updated: 20/Aug/15

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

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


 Description   

From IntrospectionModeller.doCreateResourceBuilder() : 165


        if (LOGGER.isLoggable(Level.FINEST)) {
            LOGGER.finest(LocalizationMessages.NEW_AR_CREATED_BY_INTROSPECTION_MODELER(
                    resourceBuilder.toString()));
        }

Resource$Builder.toString() tries to output its internal state, but it is self referenced in those maps, leading to infinite loop on cascading toString() calls.






[JERSEY-2881] jdk1.7+ Profile Prevents Dependency Resolution Created: 09/Jun/15  Updated: 20/Aug/15

Status: Open
Project: jersey
Component/s: release
Affects Version/s: 2.18
Fix Version/s: backlog

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

Mac OS using ant with maven ant tasks. Ant version 1.9.4. Maven version 3.3.3. maven-ant-tasks 2.1.3.



 Description   

A failure occurs while resolving dependencies for Jersey:

build.xml:144: Unable to resolve artifact: Unable to get dependency information: Unable to read the metadata file for artifact 'org.glassfish.jersey.test-framework:jersey-test-framework-core:jar': Invalid JDK version in profile 'jdk1.7+': Unbounded range: [1.7, for project org.glassfish.jersey:project
org.glassfish.jersey.test-framework:jersey-test-framework-core:jar:2.18

Path to dependency:
1) org.apache.maven:super-pom:pom:2.0



 Comments   
Comment by duanem [ 09/Jun/15 ]

The offending line appears to be in project-2.16.pom:

<activation>
<jdk>[1.7,</jdk>
</activation>

should be

<activation>
<jdk>[1.7,)</jdk>
</activation>

At least this fixes the issue for my build environment.

http://maven.apache.org/enforcer/enforcer-rules/versionRanges.html seems to indicate that this syntax is not correct for maven version ranges.

Comment by rolandh [ 01/Jul/15 ]

have the same issue, but with versions 2.18 and brand-new 2.19
looks fixed in 'project-2.16.pom' (mentioned by duanem) and ''project-2.17.pom' but not in later versions 2.18 and 2.19

Comment by Adam Lindenthal [ 07/Jul/15 ]

pull request created at: https://github.com/jersey/jersey/pull/177

Comment by Adam Lindenthal [ 07/Jul/15 ]

Hi, I will put the issue to backlog, until OCA is signed, pull request is reviewed and eventually merged.

Regards,
Adam

Comment by v1ctor [ 02/Aug/15 ]

Hi! Could somebody please tell me a workaround for this issue?

Comment by Adam Lindenthal [ 07/Aug/15 ]

V1ctor, to my understanding, the workaround is in the duanem's first comment above. It's exactly the same thing as done in the linked pull request.

Adam

Comment by nhoj_p [ 20/Aug/15 ]

Just following the jersey getting started guide and project 2.21 also has the same issue.

Comment by nhoj_p [ 20/Aug/15 ]

Issue appears to be linked to maven silently ignoring validation issues with enforcer rule version ranges. http://maven.apache.org/enforcer/enforcer-rules/versionRanges.html





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

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

Type: Improvement Priority: Major
Reporter: jwells Assignee: Unassigned
Resolution: Unresolved Votes: 48
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... Resolved
is related to JERSEY-1957 Implement Spring integration for Jers... Resolved
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





[JERSEY-2943] Enabling by default property jersey.config.server.response.setStatusOverSendError. Created: 19/Aug/15  Updated: 19/Aug/15

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

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


 Description   

I would definitely vote for server-side property jersey.config.server.response.setStatusOverSendError to be enabled by default.

For me, without this feature, Jersey behaviour is not consistent.
But what do You think?






[JERSEY-2942] @Path with regular expression overrides other @Path's with the same URI Created: 19/Aug/15  Updated: 19/Aug/15

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

Type: Bug Priority: Major
Reporter: gdemecki Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:
  • jdk 1.8_40
  • Win 7
  • Jetty 9.2.x


 Description   

Following code works fine:

@Path("/users")
@Produces("application/json")
@Consumes("application/json")
public class UserEndpoint {

    @GET
    @Path("/{id}")
    public Response getUser(@PathParam("id") String id) {
        return Response.ok("\"{" + id + "}\"").build();
    }

}

But when I've added one more method for the same URI, but with different HTTP method:

@Path("/users")
@Produces("application/json")
@Consumes("application/json")
public class UserEndpoint {

    @GET
    @Path("/{id}")
    public Response getUser(@PathParam("id") String id) {
        return Response.ok("\"{" + id + "}\"").build();
    }

    @DELETE
    @Path("/{id:[0-9][0-9]*}") // THIS CAUSES FIRST METHOD TO RETURN 405
    public Response deleteUser(@PathParam("id") Long userId) {
        return Response.noContent().build();
    }
}

Then suddenly I've got 405 Method Not Allowed for

 GET /api/users/1  HTTP/1.1

I was able to reproduce this with Jersey 2.14, 2.16 and 2.19.






[JERSEY-2893] ResourceConfig packages() ResourceFinder registration gets lost Created: 23/Jun/15  Updated: 19/Aug/15  Resolved: 19/Aug/15

Status: Resolved
Project: jersey
Component/s: core
Affects Version/s: 2.5, 2.18
Fix Version/s: None

Type: Bug Priority: Major
Reporter: diar_ahmed Assignee: Stepan Vavra
Resolution: Incomplete Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

In WLS, upon moving from 2.17 to 2.18, we saw an issue where our classes that got registered with ResourceConfig.packages() were not read & used to generate our wadl, so our app started failing.

I was able to reproduce the same issue locally on my machine using Jersey 2.5 & by calling this.getClasses() inside my ResourceConfig subclass constructor after calling this.packages(true,"my.package1","my.package2");

The issue ( after I debugged in the Jersey 2.5 source ) seems to be that

  1. the packages api explicitly creates an instance of PackageNamesScanner and registers a the packages, which creates a ResourceFinderStack()
  2. The first time ResourceConfig.getClasses() is called, the resource finders in the ResourceFinderStack() are iterated over ( stack.next() ), where stack.next() removes the resource finder after processing, so the next time the PackageNamesScanner/ResourceFinderStack is called it will have no more ResourceFinders in the stack.
  3. ResourceConfig.getClasses() then caches the classes in the ResourceConfig instance.
  4. When runtime rest processing starts, a WrappingResourceConfig is created which copies the internal state of the ResourceConfig, but doesn't copy the class cache
  5. the next time ResourceConfig.getClasses() is called on the WrappingResourceConfig's ResourceConfig, it will need to use the PackageNameScanner to find the classes again, but because the ResourceFinderStack has already been iterated over, there are no resource finders left & no classes are returned.

If we explicitly register packages in web.xml, these always work because the implementation of ResourceConfig.scanClasses() always creates new PackageNamesScanner instances every time it is called. This does not happen for classes registered with ResourceConfig.packages(), but it may want to, so people do not run into this issue.



 Comments   
Comment by diar_ahmed [ 23/Jun/15 ]

Here is the basic structure of our ResourceConfig with names changed to protect the innocent ; )

  <servlet>
    <servlet-name>JerseyServlet</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>my.Application</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>JerseyServlet</servlet-name>
    <url-pattern>/api/*</url-pattern>
  </servlet-mapping>
@ApplicationPath("api") // doesn't matter if we have @ApplicationPath, since we already declare in web.xml. 
public class Application extends ResourceConfig {
    
    public Application() {
	super();
	packages(true, "my.package1", "my.package2");

        // I should be able to call this now & still have my Runtime REST service work, but it doesn't 	
        this.getClasses();

	log.info("ReST Application initialized");
    }
}
Comment by Stepan Vavra [ 19/Aug/15 ]

Hi Ahmed,

I'm sorry, but I cannot do anything else than to resolve this issue with an Incomplete status.

I can reproduce the behaviour of Jersey 2.5 as you're describing; however this problem does not occur in newer version of Jersey (2.21 for instance). As such, there's nothing I could change in the current Jersey codebase in order to help you with your problem.

If you can provide me with a reproducible example in Jersey 2.21, please feel free to reopen this ticket. In only that case I would be able to identify the lines of code where we do something wrong (or do nothing at all) and fix it.

Thanks,
Stepan





[JERSEY-2941] BasicAuthenticator#filterResponseAndAuthenticate: auth-scheme checks should be case insensitve Created: 18/Aug/15  Updated: 18/Aug/15

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

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


 Description   

RFC 2617 in section 1.2 states that the auth-scheme should be treated case insensitive:

1.2 Access Authentication Framework

HTTP provides a simple challenge-response authentication mechanism
that MAY be used by a server to challenge a client request and by a
client to provide authentication information. It uses an extensible,
case-insensitive token to identify the authentication scheme,
followed by a comma-separated list of attribute-value pairs which
carry the parameters necessary for achieving authentication via that
scheme.

In org.glassfish.jersey.client.authentication.BasicAuthenticator.filterResponseAndAuthenticate(ClientRequestContext, ClientResponseContext) there is a line that does not ignore the case:

if (authenticate != null && authenticate.trim().startsWith("Basic")) {

We've got into authentication issues due to that line while doing some request from a jersey client using
client.register(HttpAuthenticationFeature.universal(username, password));

Against a jetty 9.3.1.v20150714 that is returning header like
WWW-Authenticate: basic realm="foo"

Following the inner workings of HttpAuthenticationFilter, we could fix it like: https://gist.github.com/jcodagnone/1f3f736c672e3a3f8317






[JERSEY-2546] wadl OPTIONS request returns 500 Internal Server Error if resource has no "direct" resource method Created: 12/Jun/14  Updated: 18/Aug/15  Resolved: 18/Aug/15

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

Type: Bug Priority: Major
Reporter: Anthony Ve Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: 1221
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The following class returns 500 Internal Server Error when doing an OPTIONS request on ".../users" because it doesn't have a "direct" resource method (or in other words, it has nothing but sub-resource methods). I don't know what the correct response should be here, but a status code of 500 seems wrong & e.g. the NetBeans "Test RESTful Web Services" functionality crashes on this.

@Stateless
@Path("/users")
public class UserService {

@Path("/current")
@GET
@Produces(TEXT_PLAIN)
public String getCurrentUser()

{ return "current user"; }

}

The body of the 500 response contains:

javax.ws.rs.NotFoundException: HTTP 404 Not Found
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:266)
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:1025)
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.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
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:744)



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

Hi,

thanks for finding a bug. I am moving the issue to the backlog.

the problem is that we currently support OPTIONS methods only for URIs where any resource method is available. In your case there is no resource method for "/users" and therefore we do not provide the OPTIONS method. This is probably incorrect, we should provide OPTIONS method for the resource too. JAXRS spec 3.3.5 says:

On receipt of an OPTIONS request an implementation MUST either:
1. Call a method annotated with a request method designator for OPTIONS or, if none present,
2. Generate an automatic response using the metadata provided by the JAX-RS annotations on the matching
class and its methods.

In this point the class is matched, so we should also provide OPTIONS method.

Anyway, returning 500 instead of 404 is a bug.

thanks
Mira

Comment by Ondrej Kosatka [ 18/Aug/15 ]

The issue has been already fixed.





[JERSEY-2874] NPE in @FormDataParam value factory when handling requests without body Created: 02/Jun/15  Updated: 18/Aug/15  Resolved: 18/Aug/15

Status: Resolved
Project: jersey
Component/s: None
Affects Version/s: 2.14
Fix Version/s: 2.22

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


 Description   

When using @FormDataParam in conjunction with FormDataBodyPart an NPE is thrown in FormDataParamValueFactoryProvider (line 205) when receiving a request without a body. The expected behavior would be a 400 "Bad Request" response. I have only tested Jersey version 2.14.
I don't think this issue is related to JERSEY-1658.






[JERSEY-2723] grizzly parse uri error for URI path beginning with two consecutive slashes Created: 04/Dec/14  Updated: 18/Aug/15  Resolved: 18/Aug/15

Status: Resolved
Project: jersey
Component/s: containers
Affects Version/s: 2.13
Fix Version/s: 2.22

Type: Bug Priority: Major
Reporter: icode Assignee: Petr Bouda
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The exception happens whenever handling URI path beginning with two consecutive slashes (three slashes are fine from that perspective).

"stack message"
javax.ws.rs.core.UriBuilderException: java.net.URISyntaxException: Expected authority at index 2: //
	at org.glassfish.jersey.uri.internal.JerseyUriBuilder.createURI(JerseyUriBuilder.java:908) ~[jersey-common-2.13.jar:na]
	at org.glassfish.jersey.uri.internal.JerseyUriBuilder._build(JerseyUriBuilder.java:897) ~[jersey-common-2.13.jar:na]
	at org.glassfish.jersey.uri.internal.JerseyUriBuilder.build(JerseyUriBuilder.java:810) ~[jersey-common-2.13.jar:na]
	at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.getRequestUri(GrizzlyHttpContainer.java:451) ~[jersey-container-grizzly2-http-2.10.1.jar:na]
	at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:348) ~[jersey-container-grizzly2-http-2.10.1.jar:na]
	at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:219) ~[grizzly-http-server-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:745) [na:1.7.0_65]

please fix bug at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer private URI getRequestUri(URI baseUri, Request grizzlyRequest)

"GrizzlyHttpContainer"

private URI getRequestUri(URI baseUri, Request grizzlyRequest) {
        // TODO: this is terrible, there must be a way to obtain the original request URI!
      +//please use getRequestURIRef().getDecodedURI() or normalize 
        String originalUri = UriBuilder.fromPath(
                grizzlyRequest.getRequest().getRequestURIRef().getOriginalRequestURIBC().toString(Charsets.DEFAULT_CHARSET)
        ).build().toString();

        String queryString = grizzlyRequest.getQueryString();
        if (queryString != null) {
            originalUri = originalUri + "?" + ContainerUtils.encodeUnsafeCharacters(queryString);
        }

        return baseUri.resolve(originalUri);
    }

please use getRequestURIRef().getDecodedURI() or normalize

  
        String originalUri = UriBuilder.fromPath(
grizzlyRequest.getRequest().getRequestURIRef().getOriginalRequestURIBC().toString(Charsets.DEFAULT_CHARSET)
        ).build().toString();

please! thanks lot



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

Any chance you could submit a pull request containing a reproducible test covering your use case? Thanks in advance for any response!

Comment by icode [ 09/Dec/14 ]

please visit http://localhost:port// on grizzly container

Comment by Jakub Podlesak [ 10/Dec/14 ]

Things will not be that easy, we need to be able to retain multiple consecutive slashes in the URI. However we should try to address this issue somehow.

We should avoid any code leading to new URI("//") call which could be caused also by URI.resolve method invocation.

Comment by icode [ 10/Dec/14 ]

why move to backlog?this important!grizzly can't use basic

Comment by Jakub Podlesak [ 10/Dec/14 ]

While i agree this is important, the bug could still be worked around using e.g. an appropriately
configured Apache httpd server instance running in front of Grizzly.
Schedule for the current Jersey sprint is very tight, and i am not sure this would fit in, that is all the backlog assignment says.

Comment by Petr Bouda [ 18/Aug/15 ]

Fix for Grizzly using, but must be enabled by parameter ServerProperties.REDUCE_CONTEXT_PATH_SLASHES_ENABLED





[JERSEY-2728] SSLHandshakeException masked by useless IllegalStateException: Already connected Created: 10/Dec/14  Updated: 17/Aug/15

Status: Open
Project: jersey
Component/s: connectors
Affects Version/s: 2.13
Fix Version/s: backlog

Type: Bug Priority: Minor
Reporter: vksavochkin Assignee: Unassigned
Resolution: Unresolved Votes: 11
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by JERSEY-2729 Confusing and inadequate exception "j... Resolved

 Description   

When connecting to https endpoint, jersey throws this useless
IllegalStateException instead of original
javax.net.ssl.SSLHandshakeException:

javax.ws.rs.ProcessingException: Already connected
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:255)
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:424)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:664)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:424)
at org.glassfish.jersey.client.JerseyInvocation$Builder.post(JerseyInvocation.java:333)
at my.test.TestService.foo(TestService.java:65)
...
Caused by: java.lang.IllegalStateException: Already connected
at sun.net.www.protocol.http.HttpURLConnection.setRequestProperty(HttpURLConnection.java:3000)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.setRequestProperty(HttpsURLConnectionImpl.java:316)
at org.glassfish.jersey.client.HttpUrlConnector.setOutboundHeaders(HttpUrlConnector.java:348)
at org.glassfish.jersey.client.HttpUrlConnector.access$100(HttpUrlConnector.java:87)
at org.glassfish.jersey.client.HttpUrlConnector$3.getOutputStream(HttpUrlConnector.java:311)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:200)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:194)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commit(CommittingOutputStream.java:262)
at org.glassfish.jersey.message.internal.OutboundMessageContext.commitStream(OutboundMessageContext.java:811)
at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:546)
at org.glassfish.jersey.client.HttpUrlConnector._apply(HttpUrlConnector.java:315)
at org.glassfish.jersey.client.HttpUrlConnector.apply(HttpUrlConnector.java:227)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:246)
... 32 more

I think, org.glassfish.jersey.client.ClientRequest#writeEntity should
catch all exceptions not just IOException when logging close() errors
in "finally" block.

Also, SSLException should be treated like a ConnectException.



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

Agreed with Vladimir he would create a pull request for this.
Moving to backlog, as we have not agreed any time frame.

@Vladimir: feel free to submit the request whenever it is ready, thanks

Comment by brcolow [ 28/Jun/15 ]

This is really affecting my ability to properly create and test my jersey https client implementation. I need to be able to see what is going wrong - instead I just get the "IllegalStateException: Already connected" message which unfortunately masks the problem...hope this is not forgotten! Thanks.

Comment by fedotxxl [ 10/Jul/15 ]

Please fix this issue! It's *very hard* to detect problems with https - I spent the whole day. Finally I did following:

1 . Run debugger
2. Add breakpoint to org.glassfish.jersey.client.ClientRequest#writeEntity (line 502 in my case)
3. Evaluated workers.writeTo... (alt+f8 in intellij idea) -> got an exception -> fixed it

Comment by trumpetinc [ 17/Aug/15 ]

Please fix - having meaningful error messages makes troubleshooting much, much easier.





[JERSEY-2797] Jersey(2.10.4) Entity provider selection algorithm gives less priority to custom providers(MessageBodyWriter) making it not to be invoked Created: 18/Feb/15  Updated: 17/Aug/15  Resolved: 14/Aug/15

Status: Resolved
Project: jersey
Component/s: core, media
Affects Version/s: 2.10
Fix Version/s: 2.21

Type: Bug Priority: Major
Reporter: shaswat Assignee: Petr Bouda
Resolution: Works as designed Votes: 0
Labels: incomplete
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Glassfish 4.1


Attachments: Zip Archive simple-service.zip    

 Description   

We have a custom MessageBodyWriter in our application for serializing DTO objects to XML in output stream

We have a custom MessageBodyWriter in our application that produces data of Media type application/xml.As we know Jersey 2.x has an algorithm(https://jersey.java.net/documentation/latest/message-body-workers.html#mbw.writer.selection.algorithm) that chooses a suitable MBR from a list of internal and custom MessageBodyWriters to persist entity into output buffer.The algorithm sorts MBR is based upon Object type distance and media type distance.So our Custom MBR is not getting invoked as we saw in the Jersey common code (MessageBodyFactory.getMessageBodyWriter())that our Custom Writer is at the below in the list and some other provider whose isWriteable() method returns true getting invoked.Further based on media type sorting our writers gets priority as we have mentioned media type as "application/xml" ,but in terms of Object type distance the priority gets lower as the DTO objects to be persist has long distance from Object super class .Eventually our Custom writer sits below in the list of writer providers and other JAXB providers like (specifically XmlRootElementJaxbProvider) gets priority and as its isWriteable() returns true so this provider (XmlRootElementJaxbProvider) gets called

The question is how can we force Jersey to invoke custom MessageBodyWriters ??Should we try adding a custom media type(like application/vnd.xml) to force it to call our Custom MessageBodyWriters ??



 Comments   
Comment by Michal Gajdos [ 18/Feb/15 ]

How do you register the provider into your application?

Comment by shaswat [ 18/Feb/15 ]

We have decorated our custom MessageBodyWriter with @Provider annotation.
@Provider
@Produces("application/xml")
public class RestDataSourceMessageBodyWriter implements MessageBodyWriter<Object> {

Comment by Michal Gajdos [ 20/Feb/15 ]

Ok, so you're using package scanning to register your provider. In this case Jersey doesn't recognizes your provider as a custom provider and treats it like our providers. Try to add @Priority(1) annotation on top of your provider.

Comment by shaswat [ 23/Feb/15 ]

I added @Priority(1) annotation on top of my MBW .The issue still exist.

@Priority(1)
@Provider
@Produces("application/xml")
public class RestDataSourceMessageBodyWriter implements MessageBodyWriter<Object> {

Comment by shaswat [ 23/Feb/15 ]

I guess we can use Priorities annotation for Interceptors /filters not for MessageBodyWriters .

Comment by shaswat [ 23/Feb/15 ]

Well My custom MBR looks like below
@Provider
@Produces("application/xml")
public class RestDataSourceMessageBodyWriter implements MessageBodyWriter {

if I make my custom MBR more specific like

@Provider
@Produces("application/xml")
public class RestDataSourceMessageBodyWriter implements MessageBodyWriter<UserInfoDTO> {

(Here "UserInfoDTO" is the first DTO object which gets searlized to xml by entity provider) then it works .But we cannot write custom MBR for thousands of DTOs and it has to be any ways.What do you suggest here?

Comment by Adam Lindenthal [ 05/Mar/15 ]

Hi shaswat,

well, if you cannot make your DTOs to extend an abstract class or implement an interface, you might want to try to set the legacy ordering property.

Comment by shaswat [ 06/Mar/15 ]

Hi Adam,

I already did that .I added below method in my root application class(class that extends javax.ws.rs.core.Application ),but interestingly ,the issue remains

@Override
public Map<String,Object> getProperties()

{ Map<String,Object> resources = new java.util.HashMap<>(); resources.put(LEGACY_WORKERS_ORDERING, true); return resources; }
Comment by Adam Lindenthal [ 06/Mar/15 ]

Interesting,
would you mind providing a full (as minimalistic as possible) reproducer test case? Not necessarily a unit test per se, just a tiny app with one resource and the custom provider registered (ideally maven based) that shows the problem isolated from other influences. You can either put it on github and link it here or send a zip to me via email, I will attach it here (unfortunately you don't have the permission to attach files in JIRA directly). If it saves you some time, you can use one of our archetypes to generate the skeleton of the app.
We need to either confirm, that there is a bug in the provider (writer) selection algorithm (or some related code) or check if there is something wrong with the way you are using it and make it clear (e.g. update the docs).

BTW, does your problem still persist if you register all your resources and providers manually (not the entire package)?

Thanks,
Adam

Comment by shaswat [ 06/Mar/15 ]

Please share your mail id or I'll put the code on git hub and share the link here.Well I did analyze a lot ,debugged the Jersey core package's MessageBodyFactory getMessageBodyWriter () method .I believe there is an issue with sorting of MBRs(MessageBodyWriter) on Object type distance grounds.Just to confirm that I created a sample app and my DTOs didn't extend or implemented any class or interfaces .I was able to call the writeTo() method of my custom MBR.Then I made my DTOs to extend couple of classes and I was able to reproduce the issue .The distance from your DTO class from java.lang.Object matters I guess here if you write---
public class RestDataSourceMessageBodyWriter implements MessageBodyWriter<Object> { "angle brackets java.lang.Object" "

Comment by shaswat [ 06/Mar/15 ]

We decorated our MBR with @Provider .That's what we do to register our custom provider .How do I register them manually?

Comment by shaswat [ 06/Mar/15 ]

oops sorry to mentioned that I did try registering them manually like below and the issue remained.

@Override
public Set<Class<?>> getClasses()

{ Set<Class<?>> resources = new java.util.HashSet<>(); resources.add(com.jenzabar.ngp.smartgwt.jaxrs.RestDataSourceMessageBodyWriter.class); return resources; }
Comment by Adam Lindenthal [ 06/Mar/15 ]

Yes, that's what I was asking.
The email is my firstname.lastname at oracle.com.

Thanks, after I receive it, I'll attach it here, so that whoever will work on this issue has the access to the reproducer.

Regards,
Adam

Comment by Jakub Podlesak [ 17/Mar/15 ]

Any update on the use case? Anybody?

Comment by Adam Lindenthal [ 15/May/15 ]

I rather re-checked my inbox, but haven't found anything.
Shaswat, would you share your testcase?

Thanks,
Adam

Comment by MAYarbrough [ 09/Jun/15 ]

Not sure what happened to Shaswat, but i believe i'm running into the same issue.

Here's a use case.
https://www.dropbox.com/s/w2rfv7kdob09c9o/simple-service.zip?dl=0

If you change the writer to <String> it works, if it's set to <Object> it doesn't

Comment by shaswat [ 10/Jun/15 ]

Sorry guys ! I was little busy with some crazy deadlines so didn't respond.Please give me 2 days to reporoduce and share the issue in a sample app .It was happening with our application and I wasn't able to reproduce in a sample application with a resource and MBW class

Comment by Adam Lindenthal [ 03/Jul/15 ]

Sample app from MAYarbrough

Comment by Adam Lindenthal [ 05/Aug/15 ]

Hi, seems like there is no further discussion around that, so I am putting the issue to backlog, so that it can be scheduled for one of the future sprints.

Regards,
Adam

Comment by Petr Bouda [ 14/Aug/15 ]

Hi MAYarbrough,

how you wrote, in case you define the correct generic type, so everything works fine.

public class CustomMessageBodyWriter implements MessageBodyWriter<String>

This behaviour is described in point 4. of the selection algorithm (https://jersey.java.net/documentation/latest/message-body-workers.html#mbw.writer.selection.algorithm)

Regards,

Petr

Comment by MAYarbrough [ 14/Aug/15 ]

Hey Petr, the second part of that point 4 says that any custom, user registered providers have to be sorted ahead of default providers. This tells me that the my provider that implements MessageBodyWriter<Object> should take precedence over any default <Object> providers. Is that not the case?

Comment by Petr Bouda [ 17/Aug/15 ]

you are not completely right, custom x default rule is performed as last step in comparison algorithm (if all previous steps did not pick up the provider which should be applied). I recommend you to look at the inner class WorkerComparator in MessageBodyFactory. In your case, if default provider has something more concrete then Object class, then default provider should be applied instead of your custom implementation.

Comment by MAYarbrough [ 17/Aug/15 ]

Ah, so if I need to override Strings as well as all other Objects then I need to make a String writer and an Object writer?

Do you know if there's a list of all the other default writers that I would need to override?

Edit: writers not filters

Comment by Petr Bouda [ 17/Aug/15 ]

Likely you will need to implement both of them if I understand this problem correctly or create one class with two interfaces, one for String and another for Object. One tip for you, for testing purposes you can use CONFIG logging and you should see classes managed by Jersey;

logging.properties
handlers = java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=CONFIG
Comment by MAYarbrough [ 17/Aug/15 ]

Ah! great. That should definitely help

Thanks Petr





[JERSEY-2927] Allow to disable lookup of o.g.j.s.spi.ComponentProvider Created: 31/Jul/15  Updated: 17/Aug/15

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 2.17, 2.19
Fix Version/s: backlog

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-2656] Form parameters serialized without '=' (equal sign) are lost when decoding the entity as Form. Created: 22/Sep/14  Updated: 17/Aug/15  Resolved: 13/Aug/15

Status: Resolved
Project: jersey
Component/s: media
Affects Version/s: 2.12
Fix Version/s: 2.20

Type: Bug Priority: Minor
Reporter: cairomax Assignee: Petr Bouda
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The method AbstractFormProvider#readFrom decodes parts of a URL encoded form which do not include an equal sign '=' by assigning null as the parameter value (see AbstractFormProvider.java, line 80, from Jersey 2.12). However, the implementation of MultivaluedMap used when generating instances of Form ignores null values by default.

This means that all the occurrences of a parameter encoded without the '=' are lost, and, among the consequences, it is possible that an application receives an empty list as the value of an entry in the MultivaluedMap (while it should safely assume that it does not happen).

HTML5 specifies that the equal sign '=' must always be included when encoding forms as x-www-form-urlencoded. However, it also specifies that when the equal sign is missing during decoding, the parameter should be interpreted as having a blank value (an empty string).
See http://www.w3.org/TR/html5/forms.html#url-encoded-form-data.

The correct behavior should be either to adopt the HTML5 decoding conventions (i.e., not producing null values) or to allow null values in the implementation of MultivaluedMap used by default to represent forms.

Notice that, for example, curl encodes parameters without equal sign if it does not appear in the command line (as in curl http://example.com/ -d param)



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

Hi cairomax,

thanks for submitting the issue and for providing a detailed description.
I am moving it to backlog now and we will plan it for one of the future sprints.

Regards,
Adam

Comment by cairomax [ 17/Aug/15 ]

Hi.
Thank you for the fix.

As I see from the source code here, now null values are not discarded anymore.
I was wondering if giving null values for form parameters without '=' is at all a good idea. It's a border case that developers usually do not think about, and a special behavior in this case (i.e. giving null) may be dangerous. Is there any particular reason for this choice or a reference standard?
In any case, with this fix a developer aware of this case can handle it properly.

Regards,
Massimo





[JERSEY-2870] Incorrect Free Software Foundation address Created: 21/May/15  Updated: 15/Aug/15  Resolved: 15/Aug/15

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

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


 Description   

Hi
Seem the LICENSE.txt file report the old address of GNU Free Software Foundation
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
can you correct with
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
for Fedora is considered as a bug, see https://fedoraproject.org/wiki/Common_Rpmlint_issues#incorrect-fsf-address
Thanks in advance
Regards



 Comments   
Comment by puntogil [ 21/May/15 ]

This problem is present in the branch 1.x and 2.x

Comment by Adam Lindenthal [ 07/Aug/15 ]

Thanks for reporting, just merged the changes. Should be soon visible on github in both (1.x, 2.x) repositories.

Regards,
Adam





[JERSEY-2847] AcceptableMediaType overrides toString incorrectly. Created: 22/Apr/15  Updated: 14/Aug/15  Resolved: 13/Aug/15

Status: Resolved
Project: jersey
Component/s: core
Affects Version/s: 2.16
Fix Version/s: 2.21

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

Issue Links:
Relates
relates to JERSEY-2844 Content-Type header in response not s... Resolved

 Description   

AcceptableMediaType toString() override returns curly braces around the media type.

This can be reproduced by specifying @Produces("text/html") on a method.

If you then specify the accept-type in the request

e.g. curl -v -XGET -H"Accept:text/html" http://localhost:8080/book/

The headers will include the following:

Content-Type:

{text/html, q=1000}

;charset=UTF-8

This causes the browser to download the response rather than render it. This occurred in Chrome and Firefox.



 Comments   
Comment by Jonas Thedering [ 28/Apr/15 ]

This also leads to problems for methods returning RenderedImage, because ImageIO does not return an ImageWriter for the media type.
The exception is:

java.io.IOException: The image-based media type {image/png, q=1000} is not supported for writing
	at org.glassfish.jersey.message.internal.RenderedImageProvider.writeTo(RenderedImageProvider.java:125)
Comment by Adam Lindenthal [ 07/Aug/15 ]

Hi, thanks for reporting this.
I just tried to launch a build with the curly braces removed and it seems to pass. I don't see any specific reason why it is present, but I will consult it with the author of the code.

I guess both of your use cases should not mind the added quality factor - that's inline with the http specs.
In the meantime, I will put the issue to backlog.

Regards,
Adam

Comment by Adam Lindenthal [ 11/Aug/15 ]

Hi, I didn't check the validity of this issue properly. I saw the curly braces in the toString() method, so I thought it makes sense, but didn't check how the string propagates into the header value.
The toString() method return value should actually under normal circumstances never be propagated into the header, we use header delegates instead.
I tried to reproduce the issue (following your instructions) against latest version and also against 2.16 (as reported), but did not succeed.

Few minutes ago I closed the related bug and explained the mechanism what happened and why toString() was called and stored in the header.
Can you please check, if your case isn't similar?

If not, I would really appreciate a complete minimalistic test case / demo app, as I really do not see it happening on my workspace.

Thanks,
Adam

Comment by Jonas Thedering [ 12/Aug/15 ]

Hi,
for my problem (RenderedImageProvider) here is a simple test case:

@Path("/renderedImageTest")
public class RenderedImageTest
{
    @GET
    @Produces("text/html")
    public String get()
    {
        StringBuilder sb = new StringBuilder();
        sb.append("<!DOCTYPE html>\n");
        sb.append("<html>\n<body>\n");
        sb.append("<img src=\"renderedImageTest/image\">\n");
        sb.append("</body>\n</html>\n");
        return sb.toString();
    }

    @GET
    @Path("image")
    @Produces("image/png")
    public RenderedImage getImage()
    {
        BufferedImage image = new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics = image.createGraphics();
        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
        graphics.setColor(Color.LIGHT_GRAY);
        graphics.fillOval(1, 1, 297, 297);
        graphics.setColor(Color.BLACK);
        graphics.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 40));
        FontMetrics metrics = graphics.getFontMetrics();
        graphics.drawString("Test", 150 - metrics.stringWidth("Test") / 2,
                150 + metrics.getAscent() - metrics.getHeight() / 2);
        graphics.dispose();

        return image;
    }
}

Just open /renderedImageTest with a web browser. This code worked with Jersey 2.5.1, but no longer works with Jersey 2.17 and 2.19. In this case, the problem is not the response to the client but there is an internal server error (Response is 500 Request failed) in the RenderedImageProvider. You can see in RenderedImageProvider.getWriterFormatName(MediaType) that it uses the toString method of the MediaType to determine if the mime type is supported by ImageIO.

Regards,
Jonas

Comment by Adam Lindenthal [ 13/Aug/15 ]

Hi, the fix was merged and will be available with the next release or in the snapshot repository.

Thanks for reporting and providing the information!
Adam

Comment by Jonas Thedering [ 14/Aug/15 ]

Hi,
I just tried the newest snapshot and can confirm that the problem seems to be fixed.

Thanks
Jonas

Comment by Adam Lindenthal [ 14/Aug/15 ]

Glad to hear that, thanks for letting us know.

Enjoy
Adam





[JERSEY-2591] Inheritance of JAX-RS resources is not working. Created: 21/Jul/14  Updated: 14/Aug/15  Resolved: 14/Aug/15

Status: Resolved
Project: jersey
Component/s: core
Affects Version/s: 2.10.1
Fix Version/s: 2.21

Type: Bug Priority: Major
Reporter: abhirockzz Assignee: Petr Bouda
Resolution: Works as designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by JERSEY-2592 Inheritance of JAX-RS resources is no... Resolved
is duplicated by JERSEY-2593 Inheritance of JAX-RS resources is no... Resolved
is duplicated by JERSEY-2594 Inheritance of JAX-RS resources is no... Resolved

 Description   

Invocation of a class which inherits another annotated JAX-RS resource (java interface) fails with HTTP 500 error

Consider a simple Java interface decorated with basic JAX-RS annotations

@Path("/testrest")
public interface RESTIntf {
    
    @POST
    @Consumes(TEXT_PLAIN)
    @Produces(TEXT_PLAIN)     
    public String greet(String name);
}

Write an implementation class - no JAX-RS annotations required

public class RESTResImpl implements RESTIntf{
	public RESTResImpl(){
	
	}

     @Override
      public String greet(String name){
        String greeting = "Hello "+ name +" !";
         System.out.println("greeting --- "+ greeting);
        return greeting;
    }
}

Write the obligatory class extending the JAX-RS Application class, deploy and run the example

@ApplicationPath("/")
public class RESTConfig extends javax.ws.rs.core.Application{
    
}

Note: I get a different exception If I switch from an interface to an abstract class

Following is the error

java.lang.NoSuchMethodException: Could not find a suitable constructor in RESTIntf class.
at org.glassfish.jersey.internal.inject.JerseyClassAnalyzer.getConstructor(JerseyClassAnalyzer.java:189)
at org.jvnet.hk2.internal.Utilities.getConstructor(Utilities.java:184)
at org.jvnet.hk2.internal.Utilities.justCreate(Utilities.java:984)
at org.jvnet.hk2.internal.ServiceLocatorImpl.create(ServiceLocatorImpl.java:856)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:948)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:940)
at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:173)
at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:185)
at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:115)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:115)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:115)
at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:94)
at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:63)
at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:263)
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:254)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1028)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:372)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
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:744)

If I switch from an interface to an abstract class, this is what I get

java.lang.InstantiationException
at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at org.glassfish.hk2.utilities.reflection.ReflectionHelper.makeMe(ReflectionHelper.java:1104)
at org.jvnet.hk2.internal.Utilities.justCreate(Utilities.java:1001)
at org.jvnet.hk2.internal.ServiceLocatorImpl.create(ServiceLocatorImpl.java:856)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:948)
at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:940)
at org.glassfish.jersey.internal.inject.Injections.getOrCreate(Injections.java:173)
at org.glassfish.jersey.server.model.MethodHandler$ClassBasedMethodHandler.getInstance(MethodHandler.java:185)
at org.glassfish.jersey.server.internal.routing.PushMethodHandlerRouter.apply(PushMethodHandlerRouter.java:74)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:112)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:115)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:115)
at org.glassfish.jersey.server.internal.routing.RoutingStage._apply(RoutingStage.java:115)
at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:94)
at org.glassfish.jersey.server.internal.routing.RoutingStage.apply(RoutingStage.java:63)
at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197)
at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:263)
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:254)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1028)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:372)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:201)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:175)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:561)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
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:744)



 Comments   
Comment by Michal Gajdos [ 21/Jul/14 ]

This doesn't work in cases when package-scanning is involved in finding resources. If implementation of resources are directly registered in application subclass then app works as expected.

Moving to backlog.

Comment by Petr Bouda [ 14/Aug/15 ]

Package Scanning does not support an inheritance. A note about that was added to Jersey documentation. Please, use ResourceConfig class and register method.





[JERSEY-2831] Unable to parse wald.xsd schemas with newer jaxb plugin Created: 27/Mar/15  Updated: 14/Aug/15  Resolved: 14/Aug/15

Status: Resolved
Project: jersey
Component/s: None
Affects Version/s: 1.18.1
Fix Version/s: None

Type: Task Priority: Major
Reporter: puntogil Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: incomplete
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

org.jvnet.jaxb2.maven2:maven-jaxb22-plugin:0.12.3

Apache Maven 3.1.1 (NON-CANONICAL_2013-11-08_14-32_mockbuild; 2013-11-08 15:32:41+0100)
Maven home: /usr/share/maven
Java version: 1.7.0_75, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.75-2.5.4.2.fc20.i386/jre
Default locale: it_IT, platform encoding: UTF-8
OS name: "linux", version: "3.18.9-100.fc20.i686", arch: "i386", family: "unix"



 Description   

Newer jaxb plugin as jaxb package required a web connection for generate source code
I disabled schema validation since the validation code
doesn't respect the catalog and will do online lookups
and i used bindings.cat [1] instead of catalog.xml
Added this configuration to the jaxb plugin:

<executions>
  <execution>
    <id>bindings</id>
    <phase>generate-sources</phase>
    <goals>
      <goal>generate</goal>
    </goals>
    <configuration>
      <generatePackage>com.sun.research.ws.wadl</generatePackage>
      <catalog>${basedir}/etc/bindings.cat</catalog>
      <schemaDirectory>${basedir}/etc</schemaDirectory>
      <bindingDirectory>${basedir}</bindingDirectory>
      <bindingIncludes>
	<bindingInclude>wadl.xsd</bindingInclude>
      </bindingIncludes>
      <forceRegenerate>false</forceRegenerate>
      <episode>true</episode>
      <specVersion>2.2</specVersion>
      <extension>true</extension>
      <strict>false</strict>
      <args>
	<arg>-npa</arg>
      </args>
    </configuration>
  </execution>
</executions>

Our builder system don't provides a web connection
Please, consider these changes

Task info: http://koji.fedoraproject.org/koji/taskinfo?taskID=9346670

[1]

PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "XMLSchema.dtd"
PUBLIC "http://www.w3.org/2001/XMLSchema.dtd" "XMLSchema.dtd"
SYSTEM "http://www.w3.org/2001/XMLSchema.dtd" "XMLSchema.dtd"

PUBLIC "datatypes" "datatypes.dtd"
SYSTEM "datatypes.dtd" "datatypes.dtd"

SYSTEM "http://www.w3.org/2001/xml.xsd" "xml.xsd"


 Comments   
Comment by puntogil [ 27/Mar/15 ]

sorry forgot again one thing
modified also wadl.xsd
schemaLocation="./xml.xsd

Comment by Libor Kramolis [ 08/Apr/15 ]

@puntogil I'm sorry I have no idea what fedoraproject is.

And may you prepare full reproducible test case? Currently I don't see where exactly do you have problem with new JAXB plugin. You can use https://gist.github.com/ to prepare test app. Thanks.

Comment by Adam Lindenthal [ 03/Jul/15 ]

Hi puntogil, I also do not understand the core of your problem.
Could you please share some reproducer, that is more narrowed to jersey?

Comment by puntogil [ 03/Jul/15 ]

HI
the core of the problem is:
Fedora [1] use Koji [2] for build all rpm.
Since this service does not have access to the web,
it is not possible for us to use the plugin with the settings configured by you
because we can't vaildate the schemas in the/for wadl.xsd file
we can validate only locally
regards
[1] https://fedoraproject.org/wiki/Overview
[2] https://fedoraproject.org/wiki/Koji

Comment by Adam Lindenthal [ 14/Aug/15 ]

Hi puntogil,

I was just going to take a look at this again and try to gather some more info from you, when I realized that this is opened against the 1.x branch.
That branch has been in sustaining mode for quite some time already. We are only fixing critical bugs on commercially supported products on Jersey 1.
Community pull request would be also considered for inclusion in a potential future patch release.

So, I am sorry, but I have to close this issue.

Regards,
Adam





[JERSEY-2866] Cannot catch JSON Marshalling exceptions Created: 18/May/15  Updated: 14/Aug/15

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

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

System



 Description   

I hava a JAX RS API that produces a JSON response.
When I send an invalid json the exception is not caught by my exception mapper and therefore the container catches it and throws a different exception response.

The Error Message is

Unrecognized field "atstribute" (Class com.intuit.platform.webs.common.financial.model.PaymentDetails), not marked as ignorable at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@362435ae; line: 12, column: 62] (through reference chain: com.intuit.platform.webs.subscription.model.SubscriptionRequest["paymentDetails"]->com.intuit.platform.webs.common.financial.model.PaymentDetails["atstribute"])


 Comments   
Comment by Adam Lindenthal [ 14/Aug/15 ]

Hi, thanks for reporting the issue. Could you please share some code? Optimally, complete minimal reproducer test case or demo app with instructions how to reproduce.

Regards,
Adam





[JERSEY-2839] Invocable.create return Source.UNKNOWN on @Valid entity param Created: 09/Apr/15  Updated: 14/Aug/15

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

Type: Bug 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   
A resource method
@Inject
private ExtendedUriInfo extendedUriInfo;

@PUT
@Path("{id}")
public final Response replace(@PathParam("id") final String id, @NotNull @Valid final T model) {
extendedUriInfo.getMatchedResourceMethod().getInvocable().getParameters().get(1).getSource();// UNKNOWN
    ...
}
org.glassfish.jersey.server.model.Parameter
public static Parameter create(
            Class concreteClass,
            Class declaringClass,
            boolean keepEncoded,
            Class<?> rawType,
            Type type,
            Annotation[] annotations) {
.....
for (Annotation annotation : annotations) {  //annotations=[@NotNull,@Valid]
            if (ANNOTATION_HELPER_MAP.containsKey(annotation.annotationType())) {
                ParamAnnotationHelper helper = ANNOTATION_HELPER_MAP.get(annotation.annotationType());
                paramAnnotation = annotation;
                paramSource = helper.getSource();
                paramName = helper.getValueOf(annotation);
            } else if (Encoded.class == annotation.annotationType()) {
                paramEncoded = true;
            } else if (DefaultValue.class == annotation.annotationType()) {
                paramDefault = ((DefaultValue) annotation).value();
            } else {
                // Take latest unknown annotation, but don't override known annotation
                if ((paramAnnotation == null) || (paramSource == Source.UNKNOWN)) {
                    paramAnnotation = annotation;
                    paramSource = Source.UNKNOWN;
                    paramName = getValue(annotation);
                }
            }
        }
if (paramAnnotation == null) {
            paramSource = Parameter.Source.ENTITY;
}
.....
}


 Comments   
Comment by Adam Lindenthal [ 14/Aug/15 ]

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





[JERSEY-2876] SelectableEntityFilteringFeature w/Jackson does not serialize @JsonAnyGetter/Setter or @JsonSubtypes properties Created: 05/Jun/15  Updated: 13/Aug/15

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

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

Tags: entity-filtering, jackson

 Description   

I've run across an issue where if I have a base class that leverages either @JsonSubType or @JsonAnyGetter/Setter for polymorphism and enable the SelectableEntityFilteringFeature the extended properties are no longer serialized. Below is the sample output for each scenario (disabled vs. enabled). In each case, I'm simply making a GET request with no SelectableEntityFilteringFeature.QUERY_PARAM_NAME provided as a part of the request.

@JsonSubType - Jersey Entity Filtering Disabled
=====================================
{
  "categories": [
    {
      "extensionPoints": [
        {
          "someExtensionPoint": {
            "bar": "ugh"
          }
        },
        {
          "someOtherExtensionPoint": {
            "foo": "meh"
          }
        }
      ],
      "code": "001",
      "name": "Sports",
      "description": "Category for Sports related retailers.",
      "businessType": "MRCHNT"
    },
    {
      "code": "002",
      "name": "Fashion & Apparel",
      "description": "Category for Fashion & Apparel related retailers.",
      "businessType": "MRCHNT"
    },
    {
      "code": "003",
      "name": "Shopping Cart Provider",
      "description": "Category for shopping cart provider related service providers.",
      "businessType": "SRVC_PRVDR"
    }
  ]
}
@JsonSubType - Jersey Entity Filtering Enabled
=====================================
{
  "categories": [
    {
      "extensionPoints": [
        {
          "someExtensionPoint": {}
        },
        {
          "someOtherExtensionPoint": {}
        }
      ],
      "code": "001",
      "name": "Sports",
      "description": "Category for Sports related retailers.",
      "businessType": "MRCHNT"
    },
    {
      "code": "002",
      "name": "Fashion & Apparel",
      "description": "Category for Fashion & Apparel related retailers.",
      "businessType": "MRCHNT"
    },
    {
      "code": "003",
      "name": "Shopping Cart Provider",
      "description": "Category for shopping cart provider related service providers.",
      "businessType": "SRVC_PRVDR"
    }
  ]
}
@JsonAny - Jersey Entity Filtering Disabled
=================================
{
  "ranges": [
    {
      "code": "001",
      "name": "0 to 100",
      "businessType": "MRCHNT",
      "foo": "bar"
    },
    {
      "code": "002",
      "name": "101 to 1000",
      "businessType": "MRCHNT",
      "sillyExtension": {
        "ooh": "bloo",
        "ahh": "blah"
      }
    },
    {
      "code": "003",
      "name": "1001 to 10000",
      "businessType": "MRCHNT"
    }
  ]
}
@JsonAny - Jersey Entity Filtering Enabled
=================================
{
  "ranges": [
    {
      "code": "001",
      "name": "0 to 100",
      "businessType": "MRCHNT"
    },
    {
      "code": "002",
      "name": "101 to 1000",
      "businessType": "MRCHNT"
    },
    {
      "code": "003",
      "name": "1001 to 10000",
      "businessType": "MRCHNT"
    }
  ]
}


 Comments   
Comment by Adam Lindenthal [ 13/Aug/15 ]

Hi, thanks for reporting the issue.
I am moving it to backlog, so that we can plan the work on it into one of the future sprints.

Regards,
Adam





[JERSEY-2882] Jersey-client: No way to put non-retryable with digest auth Created: 10/Jun/15  Updated: 13/Aug/15

Status: Open
Project: jersey
Component/s: connectors
Affects Version/s: 2.17
Fix Version/s: backlog

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





[JERSEY-2936] sendError() is called even if entity is provided Created: 06/Aug/15  Updated: 13/Aug/15

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

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


 Description   

The documentation for HttpServletResponse.sendError says: "Sends an error response to the client using the specified status code and clears the buffer" (emphasis mine). This means it is always wrong to call sendError if an response entity has been specified because the servlet container will discard any message body that has been written.

ResponseWriter.commit does not explicitly check whether or not an entity has been specified, and instead checks only whether isCommitted returns true, which means the response entity will be lost if writing the response body does not cause the servlet container to commit the response (e.g., it is a small entity). Interestingly, Tomcat's isCommitted() always returns true if the number of bytes written exceeds the value specified in setContentLength, and since ResponseWriter.writeResponseStatusAndHeaders always sets a content length, this ends up working by accident. JERSEY-2176 added a check to ResponseWriter.commit for configSetStatusOverSendError, but I think that should only be used if a response entity has not been specified.

However, this interaction with isCommitted() does not work on Tomcat if a custom gzip javax.servlet.Filter is used because it must necessarily override/prevent setContentLength. I wonder if ResponseWriter.commit's lack of check for an entity body also causes incorrect behavior on other servlet containers that do not have this somewhat peculiar isCommitted() behavior, e.g. JERSEY-790.



 Comments   
Comment by Adam Lindenthal [ 13/Aug/15 ]

Hi, thanks for reporting the issue.
I am moving it to backlog, so that we can plan the work on it in one of the future sprints.

Regards,
Adam





[JERSEY-2939] JacksonFeature: JAX-WS controller http handler method returning a generic collection forces static type serialisation for that collection Created: 12/Aug/15  Updated: 13/Aug/15  Resolved: 13/Aug/15

Status: Resolved
Project: jersey
Component/s: None
Affects Version/s: 2.20
Fix Version/s: None

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

Jetty 9 + Jersey 2.20 + JacksonFeature



 Description   

Example:

class Controller {
    @GET 
    public Collection<MyClass> getCollection {
        return Arrays.<MyClass>asList(new SubclassOfMyClass())
    }
}

class MyClass {
    public getA() {
       ...
    }
}
class SubclassOfMyClass extends MyClass {
    public getB() {
       ...
    }
}

When used with JacksonFeature, JSON returned will only contain attribute A and not attribute B because static serialisation of the root type is forced and there is no way I can override that. If, however, I wrap the collection with some other non-generic type, then static serialisation will not be forced and I will get both attribute "a" and "b" in the JSON produced by this GET.



 Comments   
Comment by Adam Lindenthal [ 13/Aug/15 ]

Hi, thank you for reporting.

I just tried and can confirm, that the described behaviour occurs. But honestly, I don't think we can do something with this on our side without introducing some ugly workaround.

In WriterInterceptorExecutor.invokeWriteTo(), we call the MessageBodyWriter.writeTo() from the Jackson implementation - com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider (actually implemented in the superclass com.fasterxml.jackson.jaxrs.base.ProviderBase). In this phase, the context.getEntity(), which is passed as an argument to the Jackson's message body writer, returns correct result containing all the fields as expected. The problem seems to be with the genericType argument. If it is absent, the entity is serialised correctly, if present, Jackson sets its rootType and continues with static typing.

According to the comments in ProviderBase, there seem to be very aware of this problematics. I'd suggest to report the issue against Jackson.
I don't see a way how to fix this on our side (other than not passing this specific MessagerBodyWriter the genericType parameter, which would be an unacceptable workaround), hence I have to close the issue as invalid.

Regards,
Adam





[JERSEY-2931] Package Scanning not working for org.codehaus.jackson.jaxrs in Websphere Created: 04/Aug/15  Updated: 13/Aug/15  Resolved: 13/Aug/15

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

Type: Bug Priority: Blocker
Reporter: Vivek13 Assignee: Pavel Bucek
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

When the project is deployed in Websphere 8.5.5.4



 Description   

my web.xml entry has entry
==========================================================
<servlet>
<servlet-name>Jersey Spring REST Service</servlet-name>
<servletclass>com.sun.jersey.spi.spring.container.servlet.SpringServlet</ervlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>
com.myproject.rest.resources;
org.codehaus.jackson.jaxrs;
com.project.rest.exception;
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
==========================================================
Package scanning for org.codehaus.jackson.jaxrs gives me error "com.sun.jersey.core.spi.scanning.ScannerException: The URI scheme bundleresource of the URI bundleresource://104.fwk-1517849738/org/codehaus/jackson/jaxrs/ is not supported. Package scanning deployment is not supported for such URIs."

In com.sun.jersey.core.spi.scanning.PackageNamesScanner class no SchemaScanner is getting added which have "bundleresource" in their schemes HashSet. This result in UriSchemeScanner coming as null for bundleresouce.
But this is working fine when application is deployed in Weblogic sever. May be URI.getScheme() is returning desired value for jetsey in weblogic.
==========================================================
Detail trace log is below.
===
FFDC Exception:com.sun.jersey.core.spi.scanning.ScannerException SourceId:com.ibm.ws.webcontainer.servlet.ServletInstance.init ProbeId:181 Reporter:com.ibm.ws.webcontainer.servlet.ServletWrapperImpl@27f15909
com.sun.jersey.core.spi.scanning.ScannerException: The URI scheme bundleresource of the URI bundleresource://104.fwk-1517849738/org/codehaus/jackson/jaxrs/ is not supported. Package scanning deployment is not supported for such URIs.
Try using a different deployment mechanism such as explicitly declaring root resource and provider classes using an extension of javax.ws.rs.core.Application
at com.sun.jersey.core.spi.scanning.PackageNamesScanner.scan(PackageNamesScanner.java:228)
at com.sun.jersey.core.spi.scanning.PackageNamesScanner.scan(PackageNamesScanner.java:142)
at com.sun.jersey.api.core.ScanningResourceConfig.init(ScanningResourceConfig.java:80)
at com.sun.jersey.api.core.PackagesResourceConfig.init(PackagesResourceConfig.java:104)
at com.sun.jersey.api.core.PackagesResourceConfig.<init>(PackagesResourceConfig.java:78)
at com.sun.jersey.api.core.PackagesResourceConfig.<init>(PackagesResourceConfig.java:89)
at com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:696)
at com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:674)
at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:205)
at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:376)
at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:559)
at javax.servlet.GenericServlet.init(GenericServlet.java:161)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:342)
at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.init(ServletWrapperImpl.java:168)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.loadOnStartupCheck(ServletWrapper.java:1366)
at com.ibm.ws.webcontainer.webapp.WebApp.doLoadOnStartupActions(WebApp.java:623)
at com.ibm.ws.webcontainer.webapp.WebApp.commonInitializationFinally(WebApp.java:589)
at com.ibm.ws.webcontainer.webapp.WebAppImpl.initialize(WebAppImpl.java:425)
at com.ibm.ws.webcontainer.webapp.WebGroupImpl.addWebApplication(WebGroupImpl.java:88)
at com.ibm.ws.webcontainer.VirtualHostImpl.addWebApplication(VirtualHostImpl.java:169)
at com.ibm.ws.webcontainer.WSWebContainer.addWebApp(WSWebContainer.java:746)
at com.ibm.ws.webcontainer.WSWebContainer.addWebApplication(WSWebContainer.java:634)
at com.ibm.ws.webcontainer.component.WebContainerImpl.install(WebContainerImpl.java:424)
at com.ibm.ws.webcontainer.component.WebContainerImpl.start(WebContainerImpl.java:718)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:1177)
at com.ibm.ws.runtime.component.DeployedApplicationImpl.fireDeployedObjectStart(DeployedApplicationImpl.java:1370)
at com.ibm.ws.runtime.component.DeployedModuleImpl.start(DeployedModuleImpl.java:639)
at com.ibm.ws.runtime.component.DeployedApplicationImpl.start(DeployedApplicationImpl.java:968)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.startApplication(ApplicationMgrImpl.java:776)
at com.ibm.ws.runtime.component.ApplicationMgrImpl$5.run(ApplicationMgrImpl.java:2195)
at com.ibm.ws.security.auth.ContextManagerImpl.runAs(ContextManagerImpl.java:5387)
at com.ibm.ws.security.auth.ContextManagerImpl.runAsSystem(ContextManagerImpl.java:5603)
at com.ibm.ws.security.core.SecurityContext.runAsSystem(SecurityContext.java:255)
at com.ibm.ws.runtime.component.ApplicationMgrImpl.start(ApplicationMgrImpl.java:2200)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:435)
at com.ibm.ws.runtime.component.CompositionUnitImpl.start(CompositionUnitImpl.java:123)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.start(CompositionUnitMgrImpl.java:378)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl.access$500(CompositionUnitMgrImpl.java:126)
at com.ibm.ws.runtime.component.CompositionUnitMgrImpl$CUInitializer.run(CompositionUnitMgrImpl.java:984)
at com.ibm.wsspi.runtime.component.WsComponentImpl$_AsynchInitializer.run(WsComponentImpl.java:502)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1865)



 Comments   
Comment by Pavel Bucek [ 13/Aug/15 ]

Jersey 1 branch has been in sustaining mode for quite some time already. Only showstoppers on commercially supported products are being fixed on Jersey 1.

Community pull request would be also considered for inclusion in a potential future patch release.





[JERSEY-2937] @Named does not work with @Context Created: 12/Aug/15  Updated: 13/Aug/15  Resolved: 13/Aug/15

Status: Resolved
Project: jersey
Component/s: containers
Affects Version/s: 2.19
Fix Version/s: None

Type: Bug Priority: Major
Reporter: tutfoo Assignee: Pavel Bucek
Resolution: Works as designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I'm trying to inject separate instances of the same type into @Context by differentiating the instances with @Named. Turns out that @Named, and even qualifiers are not being considered when used in conjunction with @Context.

Here's an example:

    @GET
    public List<BlogPost> findPostsByTag(
                                         @QueryParam("tag") String tag,
                                         @QueryParam("all") boolean isAll,
                                         @Context @Named("slave") DSLContext slave,
                                         @Context @Named("master") DSLContext master) { ... }

HK2 supports @Named and qualifiers for Services and Contracts, but I feel like they should be available for @Context as well: https://hk2.java.net/hk2-api/#Injection_by_name

I've traced the code down to DelegatedInjectionValueFactoryProvider.getInjectee(), which just looks at the parameter's raw type, and sets qualifiers to an empty set. @Named isn't even inspected.

As a workaround, I've implemented a DSLContextValueFactoryProvider that overrides value provisioning when the @Named annotation and the parameter's raw type matches.



 Comments   
Comment by Adam Lindenthal [ 12/Aug/15 ]

Hi,

thanks for reporting the issue.
I will move it to backlog, so that we can work on it in one of the future sprints.

Regards,
Adam

Comment by Pavel Bucek [ 13/Aug/15 ]

@Context is JAX-RS defined injection and it does not (and won't) support @Named.

Closing as work as designed.





[JERSEY-2878] Jersey Client - request().get(InputStream.class) returns an InputStream that cannot be closed Created: 05/Jun/15  Updated: 13/Aug/15  Resolved: 13/Aug/15

Status: Resolved
Project: jersey
Component/s: core
Affects Version/s: 2.17
Fix Version/s: 2.21

Type: Bug Priority: Major
Reporter: seanjreilly Assignee: Stepan Vavra
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: Zip Archive JERSEY-2878-master.zip    

 Description   

The following code looks like it shouldn't leak resources:

InputStream stream = client.target("http://localhost:9999/foo").request().get(InputStream.class);
        try {
            while (stream.read() != -1) {
                //consume the stream fully
            }
        } finally {
            stream.close();
        }

But the InputStream returned by the request ignores does not close the underlying http connection when close is called, even though no buffering has been requested.



 Comments   
Comment by seanjreilly [ 05/Jun/15 ]

I've created a test case, but I don't seem to be able to attach any files, so I've created a small github project instead: https://github.com/seanjreilly/JERSEY-2878

Comment by Adam Lindenthal [ 05/Jun/15 ]

Hi Sean,

thanks for reporting. Unfortunately, users do not have the permission to attach files and we cannot change this behaviour.
I just attached it for you.

Thanks,
Adam

Comment by seanjreilly [ 05/Jun/15 ]

No problem. I figured that was the case, and a sample github project wasn't at all difficult to create. Thanks for attaching a summary for me.

Comment by Stepan Vavra [ 13/Aug/15 ]

Thanks for reporting this issue! It should be ok in next release.





[JERSEY-2897] change log level Created: 28/Jun/15  Updated: 13/Aug/15

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

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


 Description   

I get this error log, but this error is client accepts error, please change log level to info or debug

02:23:37.181 [Grizzly-worker(1)] ERROR o.g.j.m.i.WriterInterceptorExecutor - MessageBodyWriter not found for media type=

{image/webp, q=1000}

, type=class ameba.message.error.ErrorMessage, genericType=class ameba.message.error.ErrorMessage.
02:23:37.183 [Grizzly-worker(1)] ERROR o.g.j.server.ServerRuntime$Responder - Error occurred when processing a response created from an already mapped exception.



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

Hi icode,

I am sorry, but I will need a bit more explanation. The error probably comes from WriterInterceptorExecutor when the request cannot be processed, because there is no suitable MessageBodyWriter for the serialized type.

Could you briefly describe your use case and explain why you mind the severe log in such case?
What do you mean by client accepts error? Malformed/incorrect Accept http header in the request? Doesn't it only mean, that the server matched a different resource method (for another media type), which will fail with every invocation, because it returns a type, that the server is not able to serialize (missing MBW)?

Greetings,
Adam





[JERSEY-2746] RuntimeExceptions thrown by request filters do not propagate when using submit() with Futures. Created: 02/Jan/15  Updated: 13/Aug/15  Resolved: 13/Aug/15

Status: Resolved
Project: jersey
Component/s: core
Affects Version/s: 2.13
Fix Version/s: 2.20

Type: Bug Priority: Major
Reporter: mrandall_cerner_com Assignee: Petr Bouda
Resolution: Fixed Votes: 0
Labels: 1221
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The run() method in ClientRuntime.submit(...) invokes Stages.process(...) with no catch block for runtime exceptions. As a result, when a runtime exception is thrown in a filter, the submitted runnable dies. This throwable is never passed back to the response callback. This can leave to orphaned async processes, and wreaks havoc when attempting to troubleshoot bugs as the exceptions are swallowed.

Per 6.7.2 / 4.5.2 of the JAX-RS spec, the exception should be re-wrapped in a ProcessingException, and set as the failure in the corresponding response callback, which in turn will be re-wrapped in an ExecutionException per Invocation.submit()'s javadoc.






[JERSEY-2842] Improve error when http response is written Created: 17/Apr/15  Updated: 13/Aug/15

Status: Open
Project: jersey
Component/s: containers
Affects Version/s: 2.16
Fix Version/s: backlog

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-2642] IllegalStateException when mixing FormParam with MultivaluedMap in method signature Created: 10/Sep/14  Updated: 13/Aug/15  Resolved: 13/Aug/15

Status: Resolved
Project: jersey
Component/s: None
Affects Version/s: 2.12
Fix Version/s: 2.20

Type: Bug Priority: Minor
Reporter: prattm Assignee: Petr Bouda
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Mac OS X Mavericks (10.9.4), Java 7 1.7.0_55



 Description   

I am upgrading from Jersey 1 to 2 and having issues accepting form data. I am not sure if this is expected behavior and I did not see anything in the user guide to indicate this shouldn't work, but just in case.

Note: This was found in 2.12 but Jira doesn't have that listed.

We have a function that worked fine in Jersey 1:

@POST
@Path("/{entityID}/newaddress")
public Response newAddress(@PathParam("entityID")  int     entityID,
                           MultivaluedMap<String, String>  formParams
                           @FormParam("addr1")     String  addr1,
                           @FormParam("addr2")     String  addr2,
                           @FormParam("city")      String  city,
                           @FormParam("zip")       String  zip,
                           @FormParam("isPrimary") boolean isPrimary)
{
}

However, in Jersey 2 I get 500 responses and the resource is never actually invoked. I traced the problem to some Jersey code throwing an IllegalStateException because the input entity stream is already closed:

    // org.glassfish.jersey.server.spi.internal.ParameterValueHelper.java
    public final class ParameterValueHelper {

    /**
     * Get the array of parameter values.
     *
     * @param valueProviders a list of value providers.
     * @return array of parameter values provided by the value providers.
     */
    public static Object[] getParameterValues(List<Factory<?>> valueProviders) {
        final Object[] params = new Object[valueProviders.size()];
        try {
            int index = 0;
            for (Factory<?> valueProvider : valueProviders) {
                params[index++] = valueProvider.provide();
            }
            return params;
        } catch (WebApplicationException e) {
            throw e;
        } catch (MessageBodyProviderNotFoundException e) {
            throw new NotSupportedException(e);
        } catch (ProcessingException e) {
            throw e;
        } catch (RuntimeException e) {
            throw new MappableException("Exception obtaining parameters", e);
        }
    }

When the third provider is called, an IllegalStateException is thrown from here:

// org.glassfish.jersey.message.internal.EntityInputStream
public void ensureNotClosed() throws IllegalStateException {
    if (closed) {
        throw new IllegalStateException(LocalizationMessages.ERROR_ENTITY_STREAM_CLOSED());
    }
}

The exception is actually swallowed and never shown in logs, so it was a bit difficult to track down. The client sees a 500 response but without much indication. It appears the entity input stream is closed after the EntityValueFactory is done reading it, preventing it from being used by the subsequent FormParamValueFactory instances.

The work around is to-rearrange the method signature so that the MultivaluedMap is the last parameter:

@POST
@Path("/{entityID}/newaddress")
public Response newAddress(@PathParam("entityID")  int     entityID,
                           @FormParam("addr1")     String  addr1,
                           @FormParam("addr2")     String  addr2,
                           @FormParam("city")      String  city,
                           @FormParam("zip")       String  zip,
                           @FormParam("isPrimary") boolean isPrimary,
                           MultivaluedMap<String, String>  formParams)
{
}


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

Hi prattm,

I am also not sure from the top of my head (neither from a very brief documentation and specification search-through) if this should or should not work as you expect in Jersey 2. (the only example I found was with the MultiValuedMap only).

So I am moving this issue to backlog and in one of the future sprints, we will look at this and either fix it or at least update the documentation/migration guide to make it more clear.

Thanks,
Adam

Comment by Petr Bouda [ 13/Aug/15 ]

Fixed in version 2.20, MultivaluedMap as an entity provider does not influence a read of other FormParams from a body.





[JERSEY-2933] ClassCastException with SelectableEntityFilteringFeature Created: 05/Aug/15  Updated: 12/Aug/15

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

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

Glassfish 4.1


Issue Links:
Duplicate
is duplicated by JERSEY-2932 ClassCastException with SelectableEnt... Resolved

 Description   

When registering org.glassfish.jersey.message.filtering.SelectableEntityFilteringFeature to select fields to be marshalled in the response, objects with nested List fields (I suppose) throw a ClassCastException.

java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class
	at org.glassfish.jersey.message.filtering.spi.FilteringHelper._getEntityClass(FilteringHelper.java:140)
	at org.glassfish.jersey.message.filtering.spi.FilteringHelper.getEntityClass(FilteringHelper.java:98)
	at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspectEntityProperties(EntityInspectorImpl.java:163)
	at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspect(EntityInspectorImpl.java:103)
	at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspect(EntityInspectorImpl.java:110)
	at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspect(EntityInspectorImpl.java:110)
	at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspect(EntityInspectorImpl.java:110)
	at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspect(EntityInspectorImpl.java:110)
	at org.glassfish.jersey.message.filtering.spi.AbstractObjectProvider.getFilteringObject(AbstractObjectProvider.java:89)
	at org.glassfish.jersey.message.filtering.spi.AbstractObjectProvider.getFilteringObject(AbstractObjectProvider.java:83)
	at org.glassfish.jersey.moxy.json.internal.FilteringMoxyJsonProvider.preWriteTo(FilteringMoxyJsonProvider.java:80)
	at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:941)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
	at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:106)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
	at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:86)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
	at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1128)
	at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:677)
	at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:424)
	at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:414)
	at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:311)
	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:317)
	at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:291)
	at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1140)
	at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:403)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:334)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
	at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
	at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
	at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
	at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
	at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
	at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
	at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
	at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
	at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
	at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
	at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
	at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
	at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
	at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
	at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
	at java.lang.Thread.run(Thread.java:745)


 Comments   
Comment by heruan [ 05/Aug/15 ]

Here's the application code:

Application.java
package org.example;

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

@ApplicationPath("/api")
public class Application extends ResourceConfig {
    public Application() {
        this.packages("org.example.resource");
        this.register(SelectableEntityFilteringFeature.class);
        this.property(SelectableEntityFilteringFeature.QUERY_PARAM_NAME, "fields");
    }
}
HostResource.java
package org.example.resource;

import org.example.entity.Host;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hosts")
public class HostResource {
    @PersistenceContext
    EntityManager em;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Host> get() {
        return em.createNamedQuery("Host.findAll").getResultList();
    }
}
Host.java
package org.example.entity;

import java.util.List;

public class Host {
    long id;
    String host;
    List<Interface> interfaces;

    // getters and setters
}
Interface.java
package org.example.entity;

import java.util.List;

public class Interface {
    long id;
    boolean main;
    int type;
    String ip;
    String dns;
    List<Item> items;

    // getters and setters
}
Item.java
package org.example.entity;

import java.util.List;

public class Item {
    long id;
    String name;
    String key;
    List<Function> functions;

    // getters and setters
}
Function.java
package org.example.entity;

import java.util.List;

public class Function {
    long id;
    String function;
    Trigger trigger;

    // getters and setters
}
Trigger.java
package org.example.entity;

import java.util.List;

public class Trigger {
    long id;
    String expression;
    String description;
    int status;

    // getters and setters
}

And this is an unfiltered JSON response:

{
  "host": "10.26.5.158",
  "id": 12345,
  "interfaces": [
    {
      "dns": "",
      "id": 2615,
      "ip": "10.26.5.158",
      "items": [
        {
          "functions": [
            {
              "function": "max",
              "id": 32002,
              "trigger": {
                "description": "{HOST.NAME} is unavailable by ICMP",
                "expression": "{32002}=0",
                "id": 24961,
                "status": 0
              }
            }
          ],
          "id": 67019,
          "key": "icmpping",
          "name": "ICMP ping"
        },
        {
          "functions": [
            {
              "function": "min",
              "id": 24613,
              "trigger": {
                "description": "Ping loss is too high on {HOST.NAME}",
                "expression": "{24613}>20",
                "id": 24962,
                "status": 0
              }
            }
          ],
          "id": 67020,
          "key": "icmppingloss",
          "name": "ICMP loss"
        },
        {
          "functions": [
            {
              "function": "avg",
              "id": 46426,
              "trigger": {
                "description": "Response time is too high on {HOST.NAME}",
                "expression": "({TRIGGER.VALUE}=0&{46426}>0.5)|({TRIGGER.VALUE}=1&{46426}>0.25)",
                "id": 24963,
                "status": 0
              }
            }
          ],
          "id": 67021,
          "key": "icmppingsec",
          "name": "ICMP response time"
        }
      ],
      "main": true,
      "type": 2
    }
  ]
}

The exception reported is thrown on the first request with or without the query fields parameter, when the feature is registered; all is well when the feature isn't registered.

Comment by Adam Lindenthal [ 12/Aug/15 ]

Hi and thanks for creating the issue.
I just spent some time trying to reproduce the problem with no success.
Would you mind sharing a complete minimalistic ready-to-go app? E.g. maven-buildable and -runnable demo app or test case.

I just tried the selectable entity filtering feature with jackson using the code you provided (with minimal changes - I didn't want to configure the persistence, so I changed the querying the entity manager into returning sample test object right from the resource, but I left the rest of your code intact) and everything worked with the feature off and on, with or without the fields parameter.

it would be very helpful, if you could minimize your usecase into something standalone and share it with us.

Thanks,
Adam





[JERSEY-2912] SSE - NullPointerException while sending comment (':comment') without event ('data:' and 'event:) Created: 14/Jul/15  Updated: 12/Aug/15  Resolved: 12/Aug/15

Status: Resolved
Project: jersey
Component/s: media
Affects Version/s: 2.19
Fix Version/s: 2.21

Type: Bug Priority: Major
Reporter: 9rief Assignee: Marek Potociar
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Steps to reproduce:

output.write(new OutboundEvent.Builder().comment("any string").build());

Result:

java.lang.NullPointerException
	at org.glassfish.jersey.media.sse.OutboundEvent.getType(OutboundEvent.java:355)
	at org.glassfish.jersey.media.sse.OutboundEventWriter.writeTo(OutboundEventWriter.java:114)
	at org.glassfish.jersey.media.sse.OutboundEventWriter.writeTo(OutboundEventWriter.java:65)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)

As far as I can see, sending the commentary without the data was assumed according to the following code:

OutboundEvent.java:259
 public OutboundEvent build() {
            if (comment == null) {
                if ((data == null) && (type == null)) {{
                    throw new IllegalStateException(LocalizationMessages.OUT_EVENT_NOT_BUILDABLE());
                }
            }

            return new OutboundEvent(name, id, reconnectDelay, type, mediaType, data, comment);
        }

Looks like the builder accepts event with comment but without data and type

I currently use the following code as a temporary workaround:


OutboundEvent outboundEvent = new OutboundEvent.Builder().comment("any string").build();

try {
    GenericType genericType = new GenericType(String.class);

    Field field = genericType.getClass().getDeclaredField("rawType");

    field.setAccessible(true);
    field.set(genericType, null);

    field = outboundEvent.getClass().getDeclaredField("type");
    field.setAccessible(true);

    field.set(outboundEvent, genericType);

} catch (IllegalAccessException | NoSuchFieldException ignore) {}

output.write(outboundEvent);

However, this workaround causes comments being surrounded with newlines twice:

curl -s -H "Accept: text/event-stream" ...
:comment


:comment 


:comment







[JERSEY-2910] SSE EventSource does not shut down after calling close() until next event arrives Created: 13/Jul/15  Updated: 12/Aug/15  Resolved: 12/Aug/15

Status: Resolved
Project: jersey
Component/s: None
Affects Version/s: 2.17, 2.18, 2.19
Fix Version/s: 2.21

Type: Bug Priority: Major
Reporter: Berben Assignee: Marek Potociar
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Jersey SSE Event Source thread is still running after calling close(). It does however return after sending any event to it.

Making the thread a daemon thread would probably solve the problem for some.

Might be related to https://java.net/jira/browse/JERSEY-1473, still looks like an open issue.

Thread dump, application hung up on closing:

"jersey-sse-event-source-[http://xyz]" #17 prio=5 os_prio=0 tid=0x062fec00 nid=0x2214 runnable [0x076cf000]
   java.lang.Thread.State: RUNNABLE
	at java.net.SocketInputStream.socketRead0(Native Method)
	at java.net.SocketInputStream.socketRead(Unknown Source)
	at java.net.SocketInputStream.read(Unknown Source)
	at java.net.SocketInputStream.read(Unknown Source)
	at java.io.BufferedInputStream.fill(Unknown Source)
	at java.io.BufferedInputStream.read1(Unknown Source)
	at java.io.BufferedInputStream.read(Unknown Source)
	- locked <0x14eadc18> (a java.io.BufferedInputStream)
	at sun.net.www.http.ChunkedInputStream.readAheadBlocking(Unknown Source)
	at sun.net.www.http.ChunkedInputStream.readAhead(Unknown Source)
	at sun.net.www.http.ChunkedInputStream.read(Unknown Source)
	- locked <0x14eadc68> (a sun.net.www.http.ChunkedInputStream)
	at java.io.FilterInputStream.read(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(Unknown Source)
	at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(Unknown Source)
	at org.glassfish.jersey.client.HttpUrlConnector$2.read(HttpUrlConnector.java:186)
	at org.glassfish.jersey.message.internal.EntityInputStream.read(EntityInputStream.java:91)
	at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream.read(ReaderInterceptorExecutor.java:292)
	at org.glassfish.jersey.client.ChunkedInput$FixedBoundaryParser.readChunk(ChunkedInput.java:125)
	at org.glassfish.jersey.client.ChunkedInput.read(ChunkedInput.java:307)
	at org.glassfish.jersey.media.sse.EventSource$EventProcessor.run(EventSource.java:615)
	at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
	at java.util.concurrent.FutureTask.run(Unknown Source)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
	at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
	- <0x14da4c20> (a java.util.concurrent.ThreadPoolExecutor$Worker)






[JERSEY-2844] Content-Type header in response not set correctly when CXF present on classpath and 'Accept' header present Created: 20/Apr/15  Updated: 11/Aug/15  Resolved: 11/Aug/15

Status: Resolved
Project: jersey
Component/s: None
Affects Version/s: 2.16, 2.17
Fix Version/s: 2.21

Type: Bug Priority: Minor
Reporter: jgriswold Assignee: Adam Lindenthal
Resolution: Invalid Votes: 2
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Relates
relates to JERSEY-2847 AcceptableMediaType overrides toStrin... Resolved

 Description   

Thank you all for your amazing work on Jersey!

I have a Jersey app which uses the CXF client package for some web service requests. While upgrading to 2.16, I came across an issue when an incoming request includes an 'Accept' header. It looks like the response's ContentType header contains the result of AcceptableMediaType#toString, e.g.

Content-Type: {text/plain, q=1000}

The curly braces are causing problems for clients which inspect the response headers, so unfortunately this issue prevents me from upgrading. From my testing this issue is present as of 2.16 and cannot be reproduced in earlier versions.

Steps to reproduce:
1) Create a new app using the quickstart maven archetype

mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-grizzly2 \
-DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false \
-DgroupId=com.example -DartifactId=simple-service -Dpackage=com.example \
-DarchetypeVersion=2.16

2) Add a dependency on the latest CXF client in simple-service/pom.xml. One important note is that I can only reproduce this issue when the dependency is listed before jersey-container-grizzly2-http

      <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-rs-client</artifactId>
        <version>3.0.4</version>
      </dependency>

3) Start the service via mvn compile exec:java
4) Requests to /myapp/myresource will include a malformed Content-Type response header if the Accept request header is present:

simple-service% curl -v localhost:8080/myapp/myresource 2>&1 | grep '< Content-Type:'
< Content-Type: text/plain

vs.

simple-service% curl -H 'Accept: text/plain' -v localhost:8080/myapp/myresource 2>&1 | grep '< Content-Type:'
< Content-Type: {text/plain, q=1000}


 Comments   
Comment by mbknor [ 30/Apr/15 ]

We had this problem and it manifested itself sometimes on some servers - randomly.
It turns out that the cause was CXF including wrong version (2.0 instead of 2.0.1) of javax.ws.rs:javax.ws.rs-api.
Since we where not actually using CXF we fixed it by excluding it, which resulted in using the correct version of rs-api.

Comment by jgriswold [ 06/May/15 ]

Thanks for the info! I'll check to make sure that's not what's happening in my case.

Comment by Adam Lindenthal [ 03/Jul/15 ]

Hi jgriswold, any updates on this? Did you maybe already resolve the problem on your side in the meantime?

Thanks,
Adam

Comment by jgriswold [ 03/Jul/15 ]

Hi Adam, sorry for not posting back. We upgraded to 2.17 and hacked around the issue with a filter that does something like this:

   private void correctMediaTypeResponse(ContainerResponseContext containerResponseContext) {
     MediaType mediaType = containerResponseContext.getMediaType();
     if (mediaType != null) {
       MultivaluedMap<String, Object> headers = containerResponseContext.getHeaders();
       if (headers != null) headers.putSingle("Content-Type",
           new MediaType(mediaType.getType(),
             mediaType.getSubtype(),
             mediaType.getParameters()));
     }
   }
Comment by Adam Lindenthal [ 10/Aug/15 ]

Hi, glad to hear you managed to workaround this.
I just attached a related issue, that complaints about curly braces as well.

I will move the issue to backlog, so that we can look at it in one of the future sprints.

Regards,
Adam

Comment by Adam Lindenthal [ 11/Aug/15 ]

Hi, looks like this particular case is caused by different mechanism, how the headers are processed in Jersey vs. CXF and especially by mixing two JAX-RS implementations on the classpath.

We've found out, that the way your dependencies were configured, the HeaderUtils.asString method calls org.apache.cxf.jaxrs.impl.RuntimeDelegateImpl instead of the one from Jersey. The Runtime delagate from CXF returns null from rd.createHeaderDelegate(), so as a fallback the toString() method is called on the headerValue.

Under normal conditions, the result of the AcceptableMediaType.toString() method will not be propagated to the Content-Type header, this is caused by other logic used in the other (CXF) delegate.

So, this situation cannot be managed and solved by Jersey and obviously should by avoided in general. There can be whole bunch of other conflicts between the two implementations. If you will keep using both libraries on your classpath, you will have to really carefully check for what dependencies to exclude, so that you don't have conflicts on your classpath. Not sure if it is even achievable.

So, I am closing the issue now, as this is not a bug and actually there is nothing we can really do about this.

Regards,
Adam

Comment by jgriswold [ 11/Aug/15 ]

Thanks for all of the investigation and analysis, Adam! This makes sense and I think we may need to revisit using both libraries.





[JERSEY-2533] Jersey 2.8 and JSONP with missing closing parenthese for JsonStructure Created: 05/Jun/14  Updated: 11/Aug/15  Resolved: 27/Jun/14

Status: Resolved
Project: jersey
Component/s: media
Affects Version/s: 2.8
Fix Version/s: 2.11

Type: Bug Priority: Major
Reporter: forchel Assignee: Michal Gajdos
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Linux, Windows, Apache, Tomcat 7



 Description   

I'm using Jersey 2.8 to generate JSONP with JsonStructur (super type for the two structured types in JSON JsonObject and JsonArray) as return type. Unfortunately the generated JSONP is syntactically incorrect as the closing parenthese is missing, e.g.

callback(
{
    "madeByAdmin":false,
    "linesChanged":1,
    "logMessage":"fixing typo"
}

is returned. I've modified and tested the example given by Jersey (see examples/json-processing-webapp) and it the JUnit test fails with the following exception:

Schwerwiegend: An I/O error has occurred while writing a response message entity to the container output stream.
org.glassfish.jersey.server.internal.process.MappableException: java.io.IOException: stream closed
    at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:96)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
    at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1154)
    at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:613)
    at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:375)
    at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:365)
    at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:272)
    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.jdkhttp.JdkHttpHandlerContainer.handle(JdkHttpHandlerContainer.java:165)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source)
    at sun.net.httpserver.AuthFilter.doFilter(Unknown Source)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source)
    at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(Unknown Source)
    at com.sun.net.httpserver.Filter$Chain.doFilter(Unknown Source)
    at sun.net.httpserver.ServerImpl$Exchange.run(Unknown Source)
    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.io.IOException: stream closed
    at sun.net.httpserver.FixedLengthOutputStream.write(Unknown Source)
    at sun.net.httpserver.PlaceholderOutputStream.write(Unknown Source)
    at org.glassfish.jersey.message.internal.CommittingOutputStream.write(CommittingOutputStream.java:244)
    at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:106)
    at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
    at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:88)
    ... 24 more

It seems, that the used JsonStructureBodyWriter closes the Outputstream and the JsonWithPaddingInterceptor is not able to write the closing parenthese to the commiting OutputStream. To test this by yourself you can modify the ChangeListResource class from the mentioned example with this additional method:

/**
 * @param callback
 * @param type
 */
@GET
@Path( "latestJson" )
@JSONP( queryParam = JSONP.DEFAULT_QUERY )
public JsonObject getLastChangeAsJsonObject( @QueryParam( JSONP.DEFAULT_QUERY ) String callback, @QueryParam( "type" ) int type )
{
    return toJsonObject( changes.get( changes.size() - 1 ) );
}

private JsonObject toJsonObject( final ChangeRecordBean bean )
{
    if( bean != null )
    {
        return Json.createObjectBuilder().add( "madeByAdmin", bean.madeByAdmin ).add( "linesChanged", bean.linesChanged ).add( "logMessage", bean.logMessage ).build();
    }
    return null;
}

And the JsonWithPaddingTest class with this test method:

@Test
public void testGetOnLatestJsonJavascriptFormat()
{
    WebTarget target = target(ShoppingAPIApplication.CHANGES_PATH);
    String js = target.path("latestJson").request("application/x-javascript").get(String.class);
    assertTrue(js.startsWith("callback"));
    assertTrue(js.endsWith(")"));
}


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

Hi, thank you for the bug report. I am moving the issue to the backlog.

Mira

proposal for fix: simple fix could be to wrap the outputStream in JsonStructureBodyWriter and do not propagate the close method. Another option is to pass already wrapper output stream to MBWs so that no MBW can close the stream. The second option looks better for me.





[JERSEY-2705] Inputstream entity interruption in chunked mode issue Created: 14/Nov/14  Updated: 11/Aug/15  Resolved: 10/Aug/15

Status: Resolved
Project: jersey
Component/s: core
Affects Version/s: 1.18.1
Fix Version/s: 2.20

Type: Bug Priority: Major
Reporter: diorcety Assignee: Petr Bouda
Resolution: Cannot Reproduce Votes: 0
Labels: pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

If you stream an Inputstream in a chunked mode, and the inputstream raise an IOException an incorrect behavour happens.
Indeed the RequestWriter close the Inputstream (which is a ChunkedInputStream) this actually finishing correctly the chunked request.
On the server side no exception is raised like if the transfer finished correctly.

The good behavour is to NOT close the stream itself but to close the underlying connection which will raise an exception on server side (incomplet transaction)



 Comments   
Comment by diorcety [ 14/Nov/14 ]

Here an example:
Client:

ClientChunkEncodedPost3.java
package com.test;
 
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
 
 
import javax.ws.rs.core.MediaType;
import java.io.File;
import java.io.FileInputStream;
 
public class ClientChunkEncodedPost3 {
 
  public static void main(String[] args) throws Exception {
    if (args.length != 1)  {
      System.out.println("File path not given");
      System.exit(1);
    }
    File file = new File(args[0]);
    final long totalSize = file.length();
    System.out.println("File size: " + totalSize);
 
    final FileInputStream inputStream = new FileInputStream(file);
 
    Thread thread = new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          Thread.sleep(10000);
          inputStream.close();
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
    thread.start();
 
    Thread.sleep(2000);
    Client client = new Client();
    client.setChunkedEncodingSize(2048);
    WebResource resource = client.resource("http://localhost:8080/test");
    WebResource.Builder builder = resource.type(MediaType.APPLICATION_OCTET_STREAM);
 
    System.out.println("Executing request");
    builder.post(inputStream);
  }
}

Server:

ClientChunkEncodedPost3.java
package com.test;
 
import com.sun.jersey.spi.resource.Singleton;
import org.apache.commons.fileupload.MultiInputStreamPart;
 
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
@Singleton
@Path("/")
public class MyResource {
 
  @POST
  public void post(InputStream tt) throws IOException, InterruptedException {
    byte [] buffer = new byte[4096];
    long size = 0;
    long read;
    do {
      read = tt.read(buffer);
      size += read;
    } while (read >= 0);
    System.out.println("Size: " + size);
  }
}

You should use big file as client input.

With 1.x:
The server output is:
Size: 689528831
Which is the transmited size until InputStream closing. No exception. I can't detect an incomplet post of a complet one

Now with the following patch which remove flush and close on the outputstream and disconnect the the http connection on an IOException.

diff --git a/jersey-client/src/main/java/com/sun/jersey/api/client/RequestWriter.java b/jersey-client/src/main/java/com/sun/jersey/api/client/RequestWriter.java
index e04eb18..e95ce66 100644
--- a/jersey-client/src/main/java/com/sun/jersey/api/client/RequestWriter.java
+++ b/jersey-client/src/main/java/com/sun/jersey/api/client/RequestWriter.java
@@ -227,14 +227,11 @@ public class RequestWriter {
          */
         public void writeRequestEntity(OutputStream out) throws IOException {
             out = cr.getAdapter().adapt(cr, out);
-            try {
-                bw.writeTo(entity, entity.getClass(), entityType,
-                        EMPTY_ANNOTATIONS, mediaType, cr.getMetadata(),
-                        out);
-                out.flush();
-            } finally {
-                out.close();
-            }
+            bw.writeTo(entity, entity.getClass(), entityType,
+                    EMPTY_ANNOTATIONS, mediaType, cr.getMetadata(),
+                    out);
+            out.flush();
+            out.close();
         }
     }
 
@@ -296,18 +293,9 @@ public class RequestWriter {
         listener.onRequestEntitySize(size);
 
         final OutputStream out = ro.getAdapter().adapt(ro, listener.onGetOutputStream());
-        try {
-            bw.writeTo(entity, entityClass, entityType,
-                    EMPTY_ANNOTATIONS, mediaType, headers, out);
-            out.flush();
-        } catch (IOException ex) {
-            try { out.close(); } catch (Exception e) { }
-            throw ex;
-        } catch (RuntimeException ex) {
-            try { out.close(); } catch (Exception e) { }
-            throw ex;
-        }
-
+        bw.writeTo(entity, entityClass, entityType,
+                EMPTY_ANNOTATIONS, mediaType, headers, out);
+        out.flush();
         out.close();
     }
 
diff --git a/jersey-client/src/main/java/com/sun/jersey/client/urlconnection/URLConnectionClientHandler.java b/jersey-client/src/main/java/com/sun/jersey/client/urlconnection/URLConnectionClientHandler.java
index 58d3c35..d545e61 100644
--- a/jersey-client/src/main/java/com/sun/jersey/client/urlconnection/URLConnectionClientHandler.java
+++ b/jersey-client/src/main/java/com/sun/jersey/client/urlconnection/URLConnectionClientHandler.java
@@ -165,104 +165,109 @@ public final class URLConnectionClientHandler extends TerminatingClientHandler {
             uc = this.httpURLConnectionFactory.getHttpURLConnection(ro.getURI().toURL());
         }
 
-        Integer readTimeout = (Integer)ro.getProperties().get(
-                ClientConfig.PROPERTY_READ_TIMEOUT);
-        if (readTimeout != null) {
-            uc.setReadTimeout(readTimeout);
-        }
-
-        Integer connectTimeout = (Integer)ro.getProperties().get(
-                ClientConfig.PROPERTY_CONNECT_TIMEOUT);
-        if (connectTimeout != null) {
-            uc.setConnectTimeout(connectTimeout);
-        }
+        try {
+            Integer readTimeout = (Integer) ro.getProperties().get(
+                    ClientConfig.PROPERTY_READ_TIMEOUT);
+            if (readTimeout != null) {
+                uc.setReadTimeout(readTimeout);
+            }
 
-        Boolean followRedirects = (Boolean)ro.getProperties().get(
-                ClientConfig.PROPERTY_FOLLOW_REDIRECTS);
-        if (followRedirects != null) {
-            uc.setInstanceFollowRedirects(followRedirects);
-        }
+            Integer connectTimeout = (Integer) ro.getProperties().get(
+                    ClientConfig.PROPERTY_CONNECT_TIMEOUT);
+            if (connectTimeout != null) {
+                uc.setConnectTimeout(connectTimeout);
+            }
 
-        if (uc instanceof HttpsURLConnection) {
-            HTTPSProperties httpsProperties = (HTTPSProperties) ro.getProperties().get(
-                    HTTPSProperties.PROPERTY_HTTPS_PROPERTIES);
-            if (httpsProperties != null) {
-                httpsProperties.setConnection((HttpsURLConnection)uc);
+            Boolean followRedirects = (Boolean) ro.getProperties().get(
+                    ClientConfig.PROPERTY_FOLLOW_REDIRECTS);
+            if (followRedirects != null) {
+                uc.setInstanceFollowRedirects(followRedirects);
             }
-        }
 
-        Boolean httpUrlConnectionSetMethodWorkaround = (Boolean)ro.getProperties().get(
-                PROPERTY_HTTP_URL_CONNECTION_SET_METHOD_WORKAROUND);
-        if (httpUrlConnectionSetMethodWorkaround != null && httpUrlConnectionSetMethodWorkaround == true) {
-            setRequestMethodUsingWorkaroundForJREBug(uc, ro.getMethod());
-        } else {
-            uc.setRequestMethod(ro.getMethod());
-        }
+            if (uc instanceof HttpsURLConnection) {
+                HTTPSProperties httpsProperties = (HTTPSProperties) ro.getProperties().get(
+                        HTTPSProperties.PROPERTY_HTTPS_PROPERTIES);
+                if (httpsProperties != null) {
+                    httpsProperties.setConnection((HttpsURLConnection) uc);
+                }
+            }
 
-        // Write the request headers
-        writeOutBoundHeaders(ro.getHeaders(), uc);
+            Boolean httpUrlConnectionSetMethodWorkaround = (Boolean) ro.getProperties().get(
+                    PROPERTY_HTTP_URL_CONNECTION_SET_METHOD_WORKAROUND);
+            if (httpUrlConnectionSetMethodWorkaround != null && httpUrlConnectionSetMethodWorkaround == true) {
+                setRequestMethodUsingWorkaroundForJREBug(uc, ro.getMethod());
+            } else {
+                uc.setRequestMethod(ro.getMethod());
+            }
 
-        // Write the entity (if any)
-        Object entity = ro.getEntity();
-        if (entity != null) {
-            uc.setDoOutput(true);
+            // Write the request headers
+            writeOutBoundHeaders(ro.getHeaders(), uc);
 
-            if(ro.getMethod().equalsIgnoreCase("GET")) {
-                final Logger logger = Logger.getLogger(URLConnectionClientHandler.class.getName());
-                if(logger.isLoggable(Level.INFO)) {
-                    logger.log(Level.INFO, "GET method with entity will be most likely replaced by POST, see http://java.net/jira/browse/JERSEY-1161");
-                }
-            }
+            // Write the entity (if any)
+            Object entity = ro.getEntity();
+            if (entity != null) {
+                uc.setDoOutput(true);
 
-            writeRequestEntity(ro, new RequestEntityWriterListener() {
-                public void onRequestEntitySize(long size) {
-                    if (size != -1 && size < Integer.MAX_VALUE) {
-                        // HttpURLConnection uses the int type for content length
-                        uc.setFixedLengthStreamingMode((int)size);
-                    } else {
-                        // TODO it appears HttpURLConnection has some bugs in
-                        // chunked encoding
-                        // uc.setChunkedStreamingMode(0);
-                        Integer chunkedEncodingSize = (Integer)ro.getProperties().get(
-                                ClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE);
-                        if (chunkedEncodingSize != null) {
-                            uc.setChunkedStreamingMode(chunkedEncodingSize);
-                        }
+                if (ro.getMethod().equalsIgnoreCase("GET")) {
+                    final Logger logger = Logger.getLogger(URLConnectionClientHandler.class.getName());
+                    if (logger.isLoggable(Level.INFO)) {
+                        logger.log(Level.INFO, "GET method with entity will be most likely replaced by POST, see http://java.net/jira/browse/JERSEY-1161");
                     }
                 }
 
-                public OutputStream onGetOutputStream() throws IOException {
-                    return new CommittingOutputStream() {
-                        @Override
-                        protected OutputStream getOutputStream() throws IOException {
-                            return uc.getOutputStream();
+                writeRequestEntity(ro, new RequestEntityWriterListener() {
+                    public void onRequestEntitySize(long size) {
+                        if (size != -1 && size < Integer.MAX_VALUE) {
+                            // HttpURLConnection uses the int type for content length
+                            uc.setFixedLengthStreamingMode((int) size);
+                        } else {
+                            // TODO it appears HttpURLConnection has some bugs in
+                            // chunked encoding
+                            // uc.setChunkedStreamingMode(0);
+                            Integer chunkedEncodingSize = (Integer) ro.getProperties().get(
+                                    ClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE);
+                            if (chunkedEncodingSize != null) {
+                                uc.setChunkedStreamingMode(chunkedEncodingSize);
+                            }
                         }
+                    }
 
-                        @Override
-                        public void commit() throws IOException {
-                            writeOutBoundHeaders(ro.getHeaders(), uc);
-                        }
-                    };
-                }
-            });
-        } else {
-            writeOutBoundHeaders(ro.getHeaders(), uc);
-        }
+                    public OutputStream onGetOutputStream() throws IOException {
+                        return new CommittingOutputStream() {
+                            @Override
+                            protected OutputStream getOutputStream() throws IOException {
+                                return uc.getOutputStream();
+                            }
+
+                            @Override
+                            public void commit() throws IOException {
+                                writeOutBoundHeaders(ro.getHeaders(), uc);
+                            }
+                        };
+                    }
+                });
+            } else {
+                writeOutBoundHeaders(ro.getHeaders(), uc);
+            }
 
 
-        final int code = uc.getResponseCode();
-        final String reasonPhrase = uc.getResponseMessage();
-        final Response.StatusType status = reasonPhrase == null ?
-            Statuses.from(code) : Statuses.from(code, reasonPhrase);
+            final int code = uc.getResponseCode();
+            final String reasonPhrase = uc.getResponseMessage();
+            final Response.StatusType status = reasonPhrase == null ?
+                    Statuses.from(code) : Statuses.from(code, reasonPhrase);
 
 
-        // Return the in-bound response
-        return new URLConnectionResponse(
-                status,
-                getInputStream(uc),
-                ro.getMethod(),
-                getInBoundHeaders(uc),
-                uc);
+            // Return the in-bound response
+            return new URLConnectionResponse(
+                    status,
+                    getInputStream(uc),
+                    ro.getMethod(),
+                    getInBoundHeaders(uc),
+                    uc);
+        } catch (IOException e) {
+            uc.disconnect();
+            throw e;
+        }
     }
 
     /**

The output of the server

java.io.IOException: Invalid chunk header
	at org.apache.coyote.http11.filters.ChunkedInputFilter.doRead(ChunkedInputFilter.java:166)
	at org.apache.coyote.http11.AbstractInputBuffer.doRead(AbstractInputBuffer.java:346)
	at org.apache.coyote.Request.doRead(Request.java:422)
	at org.apache.catalina.connector.InputBuffer.realReadBytes(InputBuffer.java:290)
	at org.apache.tomcat.util.buf.ByteChunk.substract(ByteChunk.java:449)
	at org.apache.catalina.connector.InputBuffer.read(InputBuffer.java:315)
	at org.apache.catalina.connector.CoyoteInputStream.read(CoyoteInputStream.java:167)
	at com.test.MyResource.post(MyResource.java:46)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
	at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$VoidOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:167)
	at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
	at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302)
	at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
	at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
	at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
	at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1542)
	at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1473)
	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419)
	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409)
	at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409)
	at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:558)
	at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:733)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
	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.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at java.lang.Thread.run(Thread.java:745)

My patch is maybe not the good solution but seems to behave like we could expect

Comment by Petr Bouda [ 10/Aug/15 ]

Cannot be reproduced in Jersey version 2.21. A server application throws the below-mentioned exception in case of a client closes the connection while a server is still reading the data.

FINE    14:33:11 [org.glassfish.grizzly.http.server.HttpHandler] service exception
org.glassfish.jersey.server.ContainerException: java.io.EOFException
	at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer$ResponseWriter.rethrow(GrizzlyHttpContainer.java:316)
	at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer$ResponseWriter.failure(GrizzlyHttpContainer.java:298)
	at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:486)
	at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:317)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
Comment by diorcety [ 10/Aug/15 ]

Hi,
Thanks for the feedback, but, there is no more bug fixing on 1.x branch?
Regards,

Comment by Petr Bouda [ 11/Aug/15 ]

Hi,
I tested Jersey 1.18.1 and it looks OK too. You likely configured your logger improperly on the server side. Try it out:

ChunkedResource.java
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.logging.LogManager;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.UriBuilder;

import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory;
import com.sun.jersey.api.core.DefaultResourceConfig;

import org.glassfish.grizzly.http.server.HttpServer;

@Path("/chunked")
public class ChunkedResource {

    public static void main(String[] args) throws IOException {
        LogManager.getLogManager().readConfiguration(ChunkedResource.class.getResourceAsStream("/logging.properties"));
        URI BASE_URI = UriBuilder.fromUri("http://localhost/").port(8080).build();
        HttpServer httpServer = GrizzlyServerFactory.createHttpServer(BASE_URI, new DefaultResourceConfig(ChunkedResource.class));
        System.in.read();
        httpServer.stop();
    }

    @POST
    public void post(InputStream tt) throws IOException {
        byte[] buffer = new byte[4096];
        long size = 0;
        long read;
        do {
            read = tt.read(buffer);
            size += read;
        } while (read >= 0);
        System.out.println("Size: " + size);
    }
}

and your logging.properties file should look similar to:

logging.properties
handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=FINE
java.util.logging.SimpleFormatter.format=%4$-7s %tT [%3$s] %5$s%6$s%n
.level=FINE
Comment by diorcety [ 11/Aug/15 ]

Hi,
It takes me something to refind the issue, i will explain it. In my example code the main part is the inputstream closing in the client.
I uploaded here a maven project http://dl.free.fr/bOH5WHuoI
mvn tomcat7:run in server
mvn exec:java in streamer (change the pom.xml in order to point on a big file)
After 10 seconds a thread will close the input stream which will occur an exception on the client side
"java.io.IOException: Stream Closed"
But on the server side you will have a
"Size: xxxxx"
So no exception on server side.

I discover the issue by doing a relay: Web Browser -POST> Relay --(Streaming)-> Server
If the browser stop the post (cancel or tab closing for example) i had no issue on server side, but a IOException on Relay(the server part is a simple HttpServlet not jersey resources). So on server i can't make a difference between a incomplete request and a complete one





[JERSEY-2868] MoxyObjectProvider does not handle classes with instance variables of same type correctly Created: 20/May/15  Updated: 11/Aug/15

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

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-2864] HttpAuthenticationFeature should have a callback mechanism to get credentials Created: 14/May/15  Updated: 11/Aug/15

Status: Open
Project: jersey
Component/s: security
Affects Version/s: 2.17
Fix Version/s: backlog

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-2859] NullPointerException when SecurityEntityFilteringFeature enabled Created: 12/May/15  Updated: 10/Aug/15

Status: Open
Project: jersey
Component/s: extensions, security
Affects Version/s: 2.17
Fix Version/s: backlog

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


 Description   

Hi,

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





[JERSEY-2921] Client LoggingFilter should print headers setted by other client filters Created: 26/Jul/15  Updated: 10/Aug/15

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

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


 Description   

The LoggingFilter is not really relevant when registered by a Client because it will not logged every headers that have been added by others ClientRequestFilter.

For example :

        ClientConfig config = new ClientConfig()
                .register(LoggingFilter.class)
                .register(new EncodingFeature("gzip", GZipEncoder.class));

        Client client = ClientBuilder.newBuilder()
                .withConfig(config)
                .build();

        Response response = client.target("https://www.google.com")
                .request()
                .get();

        response.close();

Output :

13:00:31.743 [main] INFO  o.g.jersey.filter.LoggingFilter - 1 * Sending client request on thread main
1 > GET https://www.google.com

Instead of:

13:00:31.743 [main] INFO  o.g.jersey.filter.LoggingFilter - 1 * Sending client request on thread main
1 > GET https://www.google.com
1 > Accept-Encoding: gzip, x-gzip

IMO the LoggingFilter priority is too low and doesn't reflect what is really sent by the client.

@Priority(Integer.MIN_VALUE)

I think a good solution could be to separate the logging filter into 2 separate filters that could be registered with a Feature :

@Priority(HEADER_DECORATOR + 100)
public class RequestLoggingFilter implements ContainerRequestFilter, ClientRequestFilter, WriterInterceptor {
   // filter code
}

@Priority(Integer.MIN_VALUE)
public class ResponseLoggingFilter implements ContainerResponseFilter, ClientResponseFilter {
   // filter code
}

The cons of this solution is that the filter will not log anymore requests which are aborted earlier in the filter chain. But given that this filter is used for dev purpose It should provide accurate and not false information on queries.

I can work on it if you are ok.



 Comments   
Comment by Adam Lindenthal [ 10/Aug/15 ]

Hi and thanks for the suggestion. I will move it to backlog, so that we can get back to it later and eventually plan the work on it into one of the sprints.

Regards,
Adam





[JERSEY-2841] @NameBinding is not working on method Created: 16/Apr/15  Updated: 10/Aug/15  Resolved: 10/Aug/15

Status: Resolved
Project: jersey
Component/s: None
Affects Version/s: 2.16
Fix Version/s: None

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

jetty 8, java 7, mac os, jersey 2.17



 Description   

I have the following RootResource class

@Path(value = "/root")
@Produces(value = {MediaType.APPLICATION_XML + RestUtil.CHARSET_UTF8, MediaType.APPLICATION_JSON + RestUtil.CHARSET_UTF8})
public class RootResource implements Resource {
  public RootResource() {
  }

  @Path(value = "/mysubresource")
  @OAuth
  public SubresourceSubresource sub_Mysubresource() {
    return new SubresourceSubresource();
  }
}

There is a filter @OAuth on method sub_Mysubesource() but it's never called for some reason.

OAuth.java

@Retention(RetentionPolicy.RUNTIME)
@NameBinding
public @interface OAuth {
}

OAuthRequestFilter.java

@OAuth
public class OAuthRequestFilter implements ContainerRequestFilter, ContainerResponseFilter {

  public OAuthRequestFilter() {
  }

  public void filter(ContainerRequestContext request) {
    System.out.println("Start OAUTH!");
  }

  public void filter(ContainerRequestContext request, ContainerResponseContext response) {
    System.out.println("End OAUTH!");
  }
  
}

Documentation says that it's a valid case to attach @NameBinding to method. https://jersey.java.net/apidocs/2.17/jersey/javax/ws/rs/NameBinding.html



 Comments   
Comment by Adam Lindenthal [ 10/Aug/15 ]

Hi, your use case seems to be valid indeed, but to me it also seems to be working correctly.
This testcase does the very same thing that you are describing: NameBindingTest.java.

Are you sure, that you have registered the filter into JAX-RS runtime (the same way as you register resources)? Is the correct resource method called for sure?

I will close the issue now, feel free to contact us (comment) if you think I am wrong. If you are still experiencing the problem, it would be very appreciated if you could create complete runnable minimalistic testcase that shows the problem.

Thanks,
Adam

Comment by zeckson [ 10/Aug/15 ]

It was indeed configuration problem. Sorry about that. You may close this issue freely.





[JERSEY-2873] java web start client authentification security Created: 29/May/15  Updated: 10/Aug/15

Status: Open
Project: jersey
Component/s: connectors
Affects Version/s: 2.17
Fix Version/s: backlog

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


 Description   

when a java web start application is launched in a SSL environment we have to keep the sslsocketfactory and hostnameversifier used an initied by the browser.
The only way to do is to get these from HttpsURLConnection.getDefaultSSLSocketFactory()
and : HttpsURLConnection.getDefaultHostnameVerifier()
see :
https://docs.oracle.com/javase/tutorial/deployment/webstart/security.html

But it is impossible to provide them to HttpUrlConnector
I would like to do that :

  private class MyConnectionfactory implements HttpUrlConnectorProvider.ConnectionFactory
   {

      @Override
      public HttpURLConnection getConnection(URL url) throws IOException
      {
         HttpURLConnection connect = (HttpURLConnection) url.openConnection();  
         if (connect instanceof HttpsURLConnection)
         {
            ((HttpsURLConnection) connect).setSSLSocketFactory(HttpsURLConnection.getDefaultSSLSocketFactory());
            ((HttpsURLConnection) connect).setHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier());
         }
         return connect;
      }
   }

and :

Client myclient =   ClientBuilder.newClient(clientConfig.connectorProvider(new HttpUrlConnectorProvider().connectionFactory(new MyConnectionfactory())));

but it don't work because in HttpConnector we override these sslsocketfactory and hostnameverifier by the ones coming from the sslcontext

From HttpUtlconnector :

  if (uc instanceof HttpsURLConnection) {
            HttpsURLConnection suc = (HttpsURLConnection) uc;
            final JerseyClient client = request.getClient();
            final HostnameVerifier verifier = client.getHostnameVerifier();
            if (verifier != null) {
                suc.setHostnameVerifier(verifier);
            }
            suc.setSSLSocketFactory(sslSocketFactory.get());
        }

So the only way I found is to change the source myself but it is not a good solution for maintenance.

Is it possible to add a parameter to avoid to override the sslsocketfactory and hostnameverifier, in particular when a specific httpsurlconnection is provided ?



 Comments   
Comment by Adam Lindenthal [ 10/Aug/15 ]

Hi zlounes,

thanks for reporting this. I will put it to backlog, so that we can take a look at it later.

Regards,
Adam

Comment by Adam Lindenthal [ 10/Aug/15 ]

Just a quick thought without really looking in the code - have you considered using an alternative transport connector?
Wouldn't it solve your problem, at least temporarily as a workaround?





[JERSEY-2902] Enable EntityFiltering will cause jackson annotation JsonProperty acting unexpectedly. Created: 02/Jul/15  Updated: 10/Aug/15

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

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

OS X 10.10.4
Jersey Version: 2.19
jackson-jaxrs-json-provider: jackson-jaxrs-json-provider
jersey-spring3: 2.19
spring Version: 4.1.6.RELEASE



 Description   

I am using Jersey with Jackson 2.5.4.

I have a POJO like this:

public class SectionViewObj {
    @JsonProperty("id")
    private String indexId;

    @EditView
    private SectionType type;

    @EditView
    private SectionPermission permission;

    @EditView
    @Preview
    @JsonRawValue
    private String value;
    
    //... getters and setters
}

When not enabling the EntityFiltering feature, the serialised json result will include "id" field.

When I turn on the EntityFiltering feature, the "id" field is missing.

When I remove the JsonProperty annotation, the "indexId" field will present in the json result.

It looks like the JsonProperty annotation conflicts with EntityFiltering. But the JsonRawValue works very well no matter EntityFiltering turned on or off.



 Comments   
Comment by Adam Lindenthal [ 10/Aug/15 ]

Hi dtong, 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.

Small (minimalistic) but complete reproducer test case (demo app) would be appreciated.

Regards,
Adam





[JERSEY-2849] @BeanParam injection behavior changed with 2.17 Created: 30/Apr/15  Updated: 10/Aug/15

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

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 Open

 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





[JERSEY-2928] declarative-linking: @BeanParam linking support Created: 03/Aug/15  Updated: 10/Aug/15

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

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

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



 Description   

Add handling for @BeanParam annotated parameters.
The BeanParam beans can have @QueryParam fields and methods.

See also https://github.com/jersey/jersey/pull/185



 Comments   
Comment by s_fuhrm [ 03/Aug/15 ]

The pull request is wrong, sorry. The correct one is https://github.com/jersey/jersey/pull/186

Comment by Adam Lindenthal [ 10/Aug/15 ]

Thanks for the pull request and opening the issue. I will move it to backlog, until the pull request is processed.

Regards,
Adam





[JERSEY-2845] @POST methods require @Consumes("application/x-www-form-urlencoded") now Created: 22/Apr/15  Updated: 10/Aug/15  Resolved: 07/Aug/15

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

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


 Description   

In version 2.5.1, methods annotated with @POST automatically accepted the content type application/x-www-form-urlencoded . So, there was no need to add an @Consumes annotation to specify that. In version 2.17, this seems to have changed: By default, only the content type text/plain seems to be accepted and to accept a normal form submission, the annotation @Consumes("application/x-www-form-urlencoded") has to be added to the method, otherwise the response is "415 Unsupported Media Type".

If this change is intended, it should at least be mentioned in the "Migration Guide" in the User Guide, I think.



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

Hi Jonas,

if no acceptable media types are defined using the @Consumes annotation, Jersey should assume /. I just quickly tried with 2.17 using curl and chrome rest console and did not see your problem appearing.

Could the problem be in the client?

Closing the issue as invalid. I would suggest, if your problem persist, to prepare a small easy to run reproducing test case that shows the problem. Than we either find the problem in your code or re-open this issue.

Regards,
Adam

Comment by Jonas Thedering [ 07/Aug/15 ]

Hello Adam,
my client is just a normal web browser. With Jersey 2.5.1, you could have a form with method post and a post method without an @Consumes annotation and it worked. With Jersey 2.17, if the @Consumes annotation is omitted, the server responds with "415 Unsupported Media Type".

Here is a simple example class to demonstrate the problem:

@Path("/consumesTest")
public class ConsumesTest
{
    @GET
    @Produces("text/html")
    public String get()
    {
        StringBuilder sb = new StringBuilder();
        sb.append("<!DOCTYPE html>\n");
        sb.append("<html>\n<body>\n");
        sb.append("<form method=\"POST\" action=\"consumesTest\">\n");
        sb.append("<input type=\"text\" name=\"text\">\n");
        sb.append("<button type=\"submit\">Submit</button>\n");
        sb.append("</form>\n");
        sb.append("</body>\n</html>\n");
        return sb.toString();
    }

    @POST
    public String post(@FormParam("text") String text)
    {
        StringBuilder sb = new StringBuilder();
        sb.append("<!DOCTYPE html>\n");
        sb.append("<html>\n<body>\n");
        sb.append("Received text \"" + text + "\".");
        sb.append("</body>\n</html>\n");
        return sb.toString();
    }
}

Just access the path /consumesTest via a web browser and submit the form. It will work with Jersey 2.5.1, but not with Jersey 2.17.

Regards,
Jonas

Comment by Adam Lindenthal [ 07/Aug/15 ]

Hi Jonas,
I am sorry to say that (I'd prefer to see a clear failure rather than a problem, that occurs only under certain circumstances), but I just took your code, put it in a small example app and tried what you suggested...

... and I still see it working. I receive the expected response: Received text "test".. I tried Chrome and Safari against Grizzly container with Jersey 2.17.

Any other ideas? Have you also changed some other things in your tech stack? What environment are you running the app in? Is there something, that might be coming into play?

And just for the sake of curiosity - have you tried newer Jersey? If your project is on maven or gradle, it should be matter of few seconds to try that out.
Also, have you tried to send the request with curl, some rest testing tool (I tried REST Console Chrome extension), ajax, ...?

If nothing helps, please try to switch on the tracing feature to see, how Jersey tried to match the resource method and share the log.

As I wrote earlier, no @Consumes should mean */* and on my environment it seems to work fine. Hopefully we will find a way to reproduce it (or the problem on your side), as we don't want to have such bug in Jersey

Cheers,
Adam

Comment by Jonas Thedering [ 10/Aug/15 ]

Hi Adam,
thank you for verifying that the test case works.

I found out that the problem doesn't occur when I use the JAR files from jaxrs-ri-2.19.zip directly. The problem was introduced when repackaging the JAR files into a single JAR file because one file (META-INF\services\org.glassfish.jersey.internal.spi.ForcedAutoDiscoverable) was existing in multiple JAR files and was overwritten.

Therefore, this issue is correctly marked as invalid.

Regards,
Jonas

Comment by Adam Lindenthal [ 10/Aug/15 ]

Hi Jonas,
glad to hear that the problem is gone.

Have a nice day,
Adam





[JERSEY-2879] Link HTTP Header: Comma separated links don't get parsed correctly Created: 08/Jun/15  Updated: 07/Aug/15

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

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

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



 Description   

Fix for comma separated multiple header values as described in http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2

See also examples http://tools.ietf.org/html/rfc5988#section-5.5

This kind of link header

   Link: </TheBook/chapter2>;
         rel="previous"; title*=UTF-8'de'letztes%20Kapitel,
         </TheBook/chapter4>;
         rel="next"; title*=UTF-8'de'n%c3%a4chstes%20Kapitel

will get parsed as ONE link, but it is actually TWO links.

Please see the given pull request for my patch:

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

I'd suggest including the patch with the next release since valid server responses can't get parsed correctly with the current implementation.



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

Hi Stephan, thanks for reporting the issue and for providing the pull request.
I am moving it to backlog, until the patch is reviewd and merged on github.

Thanks,
Adam





[JERSEY-2829] javax.ws.rs.core.Response#readEntity sometimes returns an empty string, if hasEntity() is called first Created: 26/Mar/15  Updated: 07/Aug/15  Resolved: 07/Aug/15

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

Type: Bug Priority: Major
Reporter: eiden Assignee: Unassigned
Resolution: Invalid Votes: 1
Labels: incomplete
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

OSX Yosemite, 1.8.0_31



 Description   

javax.ws.rs.core.Response#readEntity(String.class) sometimes returns an empty string if hasEntity() is called prior to readEntity.

This test case fails:

import org.junit.Before;
import org.junit.Test;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

import static javax.ws.rs.client.ClientBuilder.newClient;
import static org.fest.assertions.api.Assertions.assertThat;

public class ReadEntityTestCase {

    static final String RESPONSE_VALUE = "value";

    WebTarget target;

    @Before
    public void setUp() throws Exception {
        Client client = newClient()
                    .register(new ClientRequestFilter() {
                        @Override
                        public void filter(ClientRequestContext requestContext) throws IOException {
                            ByteArrayInputStream entity = new ByteArrayInputStream(RESPONSE_VALUE.getBytes(StandardCharsets.UTF_8));
                            requestContext.abortWith(Response.ok(entity).build());
                        }
                    });

        target = client.target("http://127.0.0.1:-1");
    }

    @Test
    public void hasEntityAndReadEntity() throws Exception {
        Response response = target.request().get();
        response.bufferEntity();

        for (int i = 0; i < 10; i++) {
            response.hasEntity();
            String value = response.readEntity(String.class);

            assertThat(value).isEqualTo(RESPONSE_VALUE);
        }
    }
}

If I comment out response.hasEntity();, the test passes.



 Comments   
Comment by Libor Kramolis [ 08/Apr/15 ]

@eiden Thanks for the report. How often is sometimes? Does it mean it sometimes passes also with calling response.hasEntity()?

Comment by Adam Lindenthal [ 15/May/15 ]

Hi eiden,
are you still with us?

Comment by katrin_r49083 [ 22/Jun/15 ]

Hi Adam,
I faced to the same problem. I use org.glassfish.jersey.test.JerseyTest for unit-testing, v2.14 with in-memory servlet container (jersey-test-framework-provider-inmemory).

Sometimes (often, 50 / 50 chance) entity is not present. For example, expected response is

2 < 400
2 < Content-Length: 90
2 < Content-Type: application/json
{
  "errorCode" : "InvalidParameter",
  "message" : null,
  "parameterName" : "from"
}

Sometimes it is returned, but sometimes I only get the following

8 < 400
8 < Content-Length: 0

As I can see "hasEntity" checking doesn't matter: if it is not called - the behaviour is still unstable.

Comment by katrin_r49083 [ 22/Jun/15 ]

Exclusion of 'asm-debug-all-5.0.2' (org.ow2.asm) dependency and usage 'asm-3.1' instead causes unstable behaviour described above. If 'asm-debug-all' dependency is active - tests work stable.

Comment by Adam Lindenthal [ 05/Aug/15 ]

Hi Katrin,
this is strange. I don't understand the mechanism, how it is failing "randomly" with missing debug library.

Would you be willing to share your unstable testcase?
Also, in the meantime, the dependency was updated to 5.0.4. Could you also confirm the unstable behaviour with the latest snapshot?

Thanks,
Adam

Comment by katrin_r49083 [ 07/Aug/15 ]

Hi Adam,
sorry, there was another reason.

Actually there were 2 mappers for one type of exception:
1. Jersey's mapper that doesn't return http response body
2. Our custom mapper that returns http response body

They were binded to context in unpredictable order. So we faced to described issue.

We also faced to troubles with version conflicts of asm-lib but the described issue was not related to it.

Thanks.

Comment by Adam Lindenthal [ 07/Aug/15 ]

Hi Katrin,

thanks for the response. So if I understand it correctly, you do not experience any random behaviour regarding readEntity any more?
Glad to hear that. In that case, I will close the issue, as Eiden does not seem to respond for quite a few months.

Eiden: feel free to contact us/comment here if your problem still appears and you will be able to provide us with a little more details.

Thanks,
Adam





[JERSEY-2929] Wrong context class loader used when reload feature is invoked from a different webapp Created: 03/Aug/15  Updated: 07/Aug/15

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

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


 Description   

This bug could be reproduced using an EAR packaged application with two WARs, when the first web application tries to reload the other one (using Container.reload() feature.
In such case Jersey ServiceFinder (during Jersey bootstrap) uses wrong context class loader, as the class loader is taken from the current thread, that belongs to the other web application.



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

Moving to backlog.





[JERSEY-2932] ClassCastException with SelectableEntityFilteringFeature Created: 05/Aug/15  Updated: 07/Aug/15  Resolved: 07/Aug/15

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

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

Glassfish 4.1


Issue Links:
Duplicate
duplicates JERSEY-2933 ClassCastException with SelectableEnt... Open

 Description   

When registering org.glassfish.jersey.message.filtering.SelectableEntityFilteringFeature to select fields to be marshalled in the response, objects with nested Lists fields (I suppose) throw a ClassCastException.

java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to java.lang.Class
at org.glassfish.jersey.message.filtering.spi.FilteringHelper._getEntityClass(FilteringHelper.java:140)
at org.glassfish.jersey.message.filtering.spi.FilteringHelper.getEntityClass(FilteringHelper.java:98)
at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspectEntityProperties(EntityInspectorImpl.java:163)
at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspect(EntityInspectorImpl.java:103)
at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspect(EntityInspectorImpl.java:110)
at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspect(EntityInspectorImpl.java:110)
at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspect(EntityInspectorImpl.java:110)
at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspect(EntityInspectorImpl.java:110)
at org.glassfish.jersey.message.filtering.spi.AbstractObjectProvider.getFilteringObject(AbstractObjectProvider.java:89)
at org.glassfish.jersey.message.filtering.spi.AbstractObjectProvider.getFilteringObject(AbstractObjectProvider.java:83)
at org.glassfish.jersey.moxy.json.internal.FilteringMoxyJsonProvider.preWriteTo(FilteringMoxyJsonProvider.java:80)
at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:941)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.JsonWithPaddingInterceptor.aroundWriteTo(JsonWithPaddingInterceptor.java:106)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundWriteTo(MappableExceptionWrapperInterceptor.java:86)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1128)
at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:677)
at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:424)
at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:414)
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:311)
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:317)
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:291)
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1140)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:403)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:386)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:334)
at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
at java.lang.Thread.run(Thread.java:745)



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

Closing as duplicate of JERSEY-2933.





[JERSEY-2858] Adding support for queryParam check in PostReplaceFilter in jersey-server Created: 10/May/15  Updated: 07/Aug/15

Status: Open
Project: jersey
Component/s: containers
Affects Version/s: 1.18.1
Fix Version/s: 1.x-backlog

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

Tags: filters, jersey-server, post, postreplace

 Description   

Hello Team,

I was working with PostReplaceFilter.java in jersey-sever-1.8 jar. Currently the filter only supports Header Param as input to override the POST request.
I feel this is not inline with the other web APIs provided by other vendors for ex OAuth API supports security /token both in Header Param and Query Param.
Jersey API should also support something like "method" in query param.
If everyone agrees, I can create a pull request for the same.



 Comments   
Comment by Adam Lindenthal [ 03/Jul/15 ]

Hi, sure you are welcome to create a pull request. But please note, that the release cycle on Jersey 1.x is quite a bit less frequent than on the newer one, so it will take some time, until your change (if merged) will propagate to a stable version.

Regards,
Adam

Comment by Adam Lindenthal [ 03/Jul/15 ]

One more thing - once you are done, please paste a link to github here and also mutually place a link to the jira issue to the pull request description.

Thanks.

Comment by Adam Lindenthal [ 07/Aug/15 ]

Moving to backlog in the meantime.





[JERSEY-2856] UriBuilder#queryParam encodes parameters that have the '%' character followed by two hexadecimal digits in an unexpected manner Created: 06/May/15  Updated: 07/Aug/15

Status: Open
Project: jersey
Component/s: core
Affects Version/s: 1.8, 1.19
Fix Version/s: 1.x-backlog, backlog

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


 Description   

UriBuilder#queryParam(String name, Object... values) encodes parameters that have the '%' character followed by two hexadecimal digits in an unexpected manner.

For example:

import javax.ws.rs.core.UriBuilder;

public class main {
    private static final String URI = "http://jersey.java.net/";
    private static final String PARAMETER_NAME = "param";
    private static final String PARAMETER_VALUE = "%20 myvalue %AF";

    public static void main(String[] args) {
        // This gives the unexpected result
        System.out.println(UriBuilder.fromUri(URI)
                .queryParam(PARAMETER_NAME, PARAMETER_VALUE)
                .build().toString());

        // This gives the expected result
        System.out.println(UriBuilder.fromUri(URI)
                .queryParam(PARAMETER_NAME, "{value}")
                .build(PARAMETER_VALUE).toString());
    }
}

Produces:

http://jersey.java.net/?param=%20+myvalue+%AF
http://jersey.java.net/?param=%2520+myvalue+%25AF

While I would expect:

http://jersey.java.net/?param=%2520+myvalue+%25AF
http://jersey.java.net/?param=%2520+myvalue+%25AF

Is it meant to work like this?



 Comments   
Comment by Gertux [ 07/May/15 ]

This same behaviour exists in the latest (2.17) version. Observe that %1G get encoded correctly to %251G

import static org.junit.Assert.assertEquals;

import javax.ws.rs.core.UriBuilder;

import org.junit.Test;

public class UriBuilderTest {
	private static final String URI = "http://jersey.java.net/";
	private static final String PARAMETER_NAME = "param";
	private static final String PARAMETER_VALUE = "%1G noent %20 myvalue %AF";

	@Test
	public void testQueryParam() {
		assertEquals("http://jersey.java.net/?param=%251G+noent+%2520+myvalue+%25AF", 
                    UriBuilder.fromUri(URI)
				.queryParam(PARAMETER_NAME, PARAMETER_VALUE).build().toString());
	}

	@Test
	public void testQueryParamTempl() {
		assertEquals("http://jersey.java.net/?param=%251G+noent+%2520+myvalue+%25AF", 
                     UriBuilder.fromUri(URI)
				.queryParam(PARAMETER_NAME, "{value}").build(PARAMETER_VALUE).toString());
	}
}
Comment by Adam Lindenthal [ 07/Aug/15 ]

Hi, thanks for reporting and commenting.
I will move the issue to backlog and look at it.

Regards,
Adam

Comment by Adam Lindenthal [ 07/Aug/15 ]

Please note, that after this is resolved, it might take longer until it propagates to a stable version in the 1.x branch, as the releases are not that frequent any more.





[JERSEY-2887] Add the support of the @Resource annotation to the Spring3 extension Created: 12/Jun/15  Updated: 07/Aug/15

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

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-2830] Memory leak when of response.readEntity when using JAX-RS Client API Created: 27/Mar/15  Updated: 07/Aug/15  Resolved: 07/Aug/15

Status: Resolved
Project: jersey
Component/s: None
Affects Version/s: 2.17
Fix Version/s: 2.20

Type: Bug Priority: Critical
Reporter: nogyara Assignee: Petr Bouda
Resolution: Cannot Reproduce Votes: 3
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Windows 7
OracleJDK 1.7.0 u67
Tomcat 7.0.47
Jersey 2.17/HK2 2.4.0 b10


Tags: incomplete, memory-leak

 Description   

This is basically the same issue as described in JERSEY-2463 which I cannot reopen so I've created a new issue.

It's easy to reproduce: working with the same Client instance for multiple REST API calls implemented using code like this:

PrtgRestClient.java
	PrtgGroup getRootGroup() {
		Builder builder = baseTarget()
				.register(new ContentTypeClientResponseFilter(MediaType.APPLICATION_XML_TYPE))
				.path("table.xml")
				.queryParam("content", "sensortree")
				.queryParam("id", rootGroupId)
				.queryParam("output", "xml")
				.request(MediaType.APPLICATION_XML_TYPE);
//		String response = builder.get(String.class);
//		PrtgResponse prtgResponse = parseEntity(response, PrtgResponse.class);
		PrtgResponse prtgResponse = builder.get(PrtgResponse.class);

		List<PrtgGroup> groups = assertState("There must be exactly one root group", prtgResponse.getTree().getGroups(), hasSize(1));
		return groups.get(0);
	}

this creates a new instance of PerThreadContext for each and every invocation of this method (all invocations come from the same thread). Because we call REST API often, we soon end up with OutOfMemoryError - and analysis of the memory dump shows that 1.8 GB of memory is retained for more than 4000 instances of PerThreadContext (and objects retained by them of course).

When parsing is done manually, like in the commented out part of the sample code, no superfluous instances of PerThreadContext get created.

Like I mentioned, this looks pretty serious to me for it can cause massive memory leaking in production.

This is the stacktrace:

Daemon Thread [http-bio-8080-exec-5] (Suspended (entry into method <init> in PerThreadContext))	
	owns: Object  (id=18580)	
	owns: Object  (id=18581)	
	owns: SocketWrapper<E>  (id=18582)	
	PerThreadContext.<init>() line: 62	
	NativeConstructorAccessorImpl.newInstance0(Constructor, Object[]) line: not available [native method]	
	NativeConstructorAccessorImpl.newInstance(Object[]) line: 57	
	DelegatingConstructorAccessorImpl.newInstance(Object[]) line: 45	
	Constructor<T>.newInstance(Object...) line: 526	
	ReflectionHelper.makeMe(Constructor<?>, Object[], boolean) line: 1129	
	ClazzCreator<T>.createMe(Map<SystemInjecteeImpl,Object>) line: 274	
	ClazzCreator<T>.create(ServiceHandle<?>, SystemDescriptor<?>) line: 368	
	SystemDescriptor<T>.create(ServiceHandle<?>) line: 471	
	SingletonContext$1.compute(ContextualInput<Object>) line: 82	
	SingletonContext$1.compute(Object) line: 70	
	Cache$OriginThreadAwareFuture$1.call() line: 97	
	FutureTask<V>.run() line: 262	
	Cache$OriginThreadAwareFuture.run() line: 154	
	Cache<K,V>.compute(K) line: 199	
	SingletonContext.findOrCreate(ActiveDescriptor<T>, ServiceHandle<?>) line: 121	
	Utilities.createService(ActiveDescriptor<T>, Injectee, ServiceLocatorImpl, ServiceHandle<T>, Class<?>) line: 2064	
	ServiceHandleImpl<T>.getService(ServiceHandle<T>) line: 105	
	ServiceHandleImpl<T>.getService() line: 87	
	ServiceLocatorImpl._resolveContext(Class<Annotation>) line: 2047	
	ServiceLocatorImpl.access$000(ServiceLocatorImpl, Class) line: 120	
	ServiceLocatorImpl$2.compute(Class<Annotation>) line: 186	
	ServiceLocatorImpl$2.compute(Object) line: 182	
	Cache$OriginThreadAwareFuture$1.call() line: 97	
	FutureTask<V>.run() line: 262	
	Cache$OriginThreadAwareFuture.run() line: 154	
	Cache<K,V>.compute(K) line: 199	
	ServiceLocatorImpl.resolveContext(Class<Annotation>) line: 2066	
	Utilities.createService(ActiveDescriptor<T>, Injectee, ServiceLocatorImpl, ServiceHandle<T>, Class<?>) line: 2042	
	ServiceHandleImpl<T>.getService(ServiceHandle<T>) line: 105	
	ServiceHandleImpl<T>.getService() line: 87	
	ContextInjectionResolver$2.provide() line: 126	
	XmlRootElementJaxbProvider$App(XmlRootElementJaxbProvider).readFrom(Class<Object>, MediaType, Unmarshaller, InputStream) line: 138	
	XmlRootElementJaxbProvider$App(AbstractRootElementJaxbProvider).readFrom(Class<Object>, Type, Annotation[], MediaType, MultivaluedMap<String,String>, InputStream) line: 123	
	ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorContext, MessageBodyReader, EntityInputStream) line: 266	
	ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorContext) line: 236	
	ReaderInterceptorExecutor.proceed() line: 156	
	MessageBodyFactory.readFrom(Class<?>, Type, Annotation[], MediaType, MultivaluedMap<String,String>, PropertiesDelegate, InputStream, Iterable<ReaderInterceptor>, boolean) line: 1085	
	ClientResponse(InboundMessageContext).readEntity(Class<T>, Type, Annotation[], PropertiesDelegate) line: 853	
	ClientResponse(InboundMessageContext).readEntity(Class<T>, PropertiesDelegate) line: 785	
	ClientResponse.readEntity(Class<T>) line: 326	
	JerseyInvocation.translate(ClientResponse, RequestScope, Class<T>) line: 790	
	JerseyInvocation.access$500(JerseyInvocation, ClientResponse, RequestScope, Class) line: 91	
	JerseyInvocation$2.call() line: 687	
	Errors.process(Callable<T>, boolean) line: 315	
	Errors.process(Producer<T>, boolean) line: 297	
	Errors.process(Producer<T>) line: 228	
	RequestScope.runInScope(Producer<T>) line: 444	
	JerseyInvocation.invoke(Class<T>) line: 683	
	JerseyInvocation$Builder.method(String, Class<T>) line: 411	
	JerseyInvocation$Builder.get(Class<T>) line: 307	
	PrtgRestClient.getRootGroup() line: 104	
	PrtgAdapter.getPodGroup(PodEntity) line: 55	
	PrtgModule.retrievePodGroup(PodEntity) line: 43	
	PrtgModule.deleteEmptyDevices(MessageCollector, PodEntity) line: 54	
	PrtgModule.deleteUselessObjects(MessageCollector, PodEntity) line: 48	
	PrtgModule.synchronize(SyncerModule$Context, MessageCollector) line: 36	
	SyncerFormView$1.buttonClick(Button$ClickEvent) line: 115	
	...


 Comments   
Comment by Michal Gajdos [ 01/Apr/15 ]

I think this is already fixed in master and should be in 2.18. Can you, please, confirm either on 2.18-SNAPSHOT or wait until 2.18 is released and confirm then? In the meantime, please, refer to this [1] article when you can find what to avoid when using Jersey Client.

[1] https://blogs.oracle.com/japod/entry/how_to_use_jersey_client

Comment by nogyara [ 09/Apr/15 ]

Hi Michal,
if the behaviour from the article you linked here is going to stick for a while, it should be definitely documented. I just re-checked the latest Jersey 2.17 docs and there's no warning about this at all, I'd even say that the config inheritance described in the docs for both the Client and WebTarget (https://jersey.java.net/documentation/latest/client.html#d0e4405) promotes this config without reuse.

I'd prefer to test it on the final version 2.18, any guess when it's going to be out? According to the roadmap, it should be any day by now, right?

Comment by kam5FCC [ 22/Apr/15 ]

Hi Michal and nogyara,
I, too, am having the same issue with readEntity() causing memory leaks. I hoped that 2.15's fix would solve the issue but no. Reading this JIRA I hoped that it would be fixed in 2.18 - but I don't think so either.
I got the 2.18-SNAPSHOT code from https://java.net/projects/jersey/sources (git://java.net/jersey~code precisely) and built the code (mvn install) and loaded my .m2 directory with the jars (jersey-client, jersey-server & jersey-common).

This Works
            Response r = RestClient.sendRestRequest(rcb);
            switch (Status.fromStatusCode(r.getStatus())) {
                case OK:
                    Log.info("heart beat."); return SUCCESS;
                default:
                    Log.info("heart beat failed.");  return NOT_RESPONSIVE;
            }
This Doesn't
            Response r = RestClient.sendRestRequest(rcb);
            ApplicationStatus st = r.readEntity(ApplicationStatus.class);
            switch (Status.fromStatusCode(r.getStatus())) {
                case OK:
                    Log.info("AppStat Responsive is {} and activeCount is {}",
                             st.isResponsive ? "True" : "False", st.getActiveCount());
                    Log.info("heart beat.");  return SUCCESS;
                default:
                    Log.info("heart beat failed."); return NOT_RESPONSIVE;
            }

Wish I could attach images and show the javaMelody memory graphs that show a flat saw-tooth pattern for the first code and a rising pattern for the second code.

I can show the javaMelody memory Histogram top 20 though:

Class Size (Kb) % size Instances % instances Source
java.util.HashMap$Entry 43,059 10 1,377,900 14  
java.lang.reflect.Method 34,807 8 445,534 4  
byte[] 31,909 7 50,986 0  
java.util.HashMap$Entry[] 29,372 7 315,461 3  
char[] 24,613 5 301,761 3  
java.util.LinkedHashMap$Entry 18,024 4 461,436 4  
int[] 13,268 3 31,064 0  
java.util.LinkedHashMap 13,156 3 240,583 2  
org.glassfish.hk2.utilities.reflection.internal.MethodWrapperImpl 10,256 2 437,595 4 var/lib/tomcat7/webapps/matrix/WEB-INF/lib/hk2-utils-2.4.0-b12.jar
java.lang.reflect.Field 10,153 2 144,403 1  
java.util.HashMap 9,230 2 196,911 2  
java.util.LinkedList 9,081 2 290,598 2  
java.util.LinkedList$Node 7,763 1 331,239 3  
java.util.concurrent.ConcurrentHashMap$HashEntry 7,493 1 239,786 2  
java.util.concurrent.FutureTask 6,848 1 219,138 2  
java.lang.String 6,701 1 285,939 2  
java.lang.Object[] 6,215 1 104,873 1  
org.glassfish.hk2.utilities.cache.LRUHybridCache$OriginThreadAwareFuture 5,605 1 143,491 1 var/lib/tomcat7/webapps/matrix/WEB-INF/lib/hk2-utils-2.4.0-b12.jar
org.jvnet.hk2.internal.SystemDescriptor 4,891 1 52,176 0 var/lib/tomcat7/webapps/matrix/WEB-INF/lib/hk2-locator-2.4.0-b12.jar
org.glassfish.hk2.utilities.cache.LRUHybridCache$HybridCacheEntryImpl 4,484 1 143,491 1 var/lib/tomcat7/webapps/matrix/WEB-INF/lib/hk2-utils-2.4.0-b12.jar

We don't use the hk2 libraries explicitly in our code, not those concurrent libraries and while we use some HashMaps when I do a heap dump the data inside is definitely not from our code.

Long story short - it doesn't look like 2.18 will solve this problem.

Kevin

Comment by Michal Gajdos [ 19/May/15 ]

Hi Kevin,

can you, please, provide a reproducible test-case? Or at least, can you provide or describe what RestClient.sendRestRequest does?

Thanks.

Comment by kam5FCC [ 20/May/15 ]
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation.Builder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

// From previous call
//            rcb.setURI(uri);
//            rcb.setMethodType("GET");
//            rcb.setAcceptType(MediaType.APPLICATION_XML);
//            rcb.setContentType(MediaType.APPLICATION_XML);

    public static Response sendRestRequest(RestClientBuilder rcb) {
        return request(rcb, rcb.getMethodType());
    }

    @SuppressWarnings("unchecked")
    private static Response request(RestClientBuilder rcb, RestMethodType reqType) {
        Response clientResp = null;
        Client client = ClientBuilder.newClient();
        WebTarget target = client.target(rcb.getURI());

        target = target.path(rcb.getPath());
        target = target.register(new LoggingFilter());

        for (Map.Entry<String, String> queryPair : rcb.getQueryParams().entrySet()) {
            target.queryParam(queryPair.getKey(), queryPair.getValue());
        }

        Builder builder = target.request(rcb.getContentType()).accept(rcb.getAcceptType());
        for (Map.Entry<String, Object> headerPair : rcb.getHeaderParams().entrySet()) {
            builder = builder.header(headerPair.getKey(), headerPair.getValue());
        }

        switch (reqType) {
            case POST:
                clientResp = builder.post(Entity.entity(rcb.getBody(), rcb.getContentType()));
                break;
            case GET:
                clientResp = builder.get();
                break;
            case PUT:
                clientResp = builder.put(Entity.entity(rcb.getBody(), rcb.getContentType()));
                break;
            case DELETE:
                clientResp = builder.delete();
                break;
            default:
                break;
        }
        return clientResp;
    }    

The rcb is just a bean that transports the information.

Point of this is - From the code above all that gets changed is the readEntity function is added to the Response object and hk, hashMap and LinkedHashMap object are produced. We don't use hk explicity (only via jersey/jackson) only a few hashmaps and no LinkedHashMaps at all.

Also, something to point out is that we run this call every minute and can start to see something after 4 hours running. After 12 hours, it can be about 500M.

Thanks,
Kevin

Comment by Michal Gajdos [ 21/May/15 ]

This approach is very inefficient. I guess we should update our documentation.

You shouldn't create new JAX-RS (Jersey) client for every request you want to make - it's expensive and when client is not needed anymore it should be closed. Try to do something like this instead:

    private static final Client client = ClientBuilder.newClient().register(LoggingFilter.class);

    @SuppressWarnings("unchecked")
    private static Response request(RestClientBuilder rcb, RestMethodType reqType) {
        WebTarget target = client.target(rcb.getURI())
            .path(rcb.getPath());

        for (Map.Entry<String, String> queryPair : rcb.getQueryParams().entrySet()) {
            target.queryParam(queryPair.getKey(), queryPair.getValue());
        }

        Builder builder = target.request(rcb.getContentType()).accept(rcb.getAcceptType());
        for (Map.Entry<String, Object> headerPair : rcb.getHeaderParams().entrySet()) {
            builder = builder.header(headerPair.getKey(), headerPair.getValue());
        }

        switch (reqType) {
            case POST:
                clientResp = builder.post(Entity.entity(rcb.getBody(), rcb.getContentType()));
                break;
            case GET:
                clientResp = builder.get();
                break;
            case PUT:
                clientResp = builder.put(Entity.entity(rcb.getBody(), rcb.getContentType()));
                break;
            case DELETE:
                clientResp = builder.delete();
                break;
            default:
                break;
        }
        return clientResp;
    }

This should ensure that client initialisation is done only once and keep the heap calm

Comment by Odelya [ 04/Jun/15 ]

Michal thanks. Will it be fixed? if so, any ETA?

Comment by Odelya [ 05/Jun/15 ]

The problem that I can't reuse the same client if I want to make multiple requests with it - as it will block it.
Can't the memory leak be fixed?

Comment by phil-lift [ 21/Jul/15 ]

I was hoping for 2.18 release, then 2.19... 2.20 maybe?
Using single client, within a synchronized block for now.. but this won't scale.

Comment by Petr Bouda [ 07/Aug/15 ]

nogyara or kam5FCC, could you please provide the entire example of an application in which is above-mentioned bug reproduces? Since I am not able to reproduce it, I let to run the overnight test with the application contains a basic resource with an incoming and outgoing entity and created a client application using your provided snapshot, and everything looks fine regarding Profiler Statistics.

Comment by svileng [ 07/Aug/15 ]

Hi All,
I have just managed to reproduce it using the attached zip from https://java.net/jira/browse/JERSEY-2463
I even modified it a little bit, closing the client instance after each of the 10000 post requests. (it appears that i cannot attach files to this issu...)

Still the leak is there, using MAT to analyze the heap just after Jersey2463ITCase has been terminated:

19 instances of "org.glassfish.hk2.internal.PerThreadContext$PerContextThreadWrapper", loaded by "org.apache.catalina.loader.WebappClassLoader @ 0x783db6590" occupy 2,660,536 (13.36%) bytes.

And those are indeed never GC'ed.





[JERSEY-2872] ConnectionCallback does not fire when client dropped a connection Created: 28/May/15  Updated: 07/Aug/15

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

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-2875] JettyHttpContainerFactory leaves server in limbo after throwing a ProcessingException during createServer() Created: 04/Jun/15  Updated: 07/Aug/15

Status: Open
Project: jersey
Component/s: containers
Affects Version/s: 2.16
Fix Version/s: backlog

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

Jetty 9.1.1



 Description   

(This is a copy of my post at Stack overflow: https://stackoverflow.com/questions/29826433/how-to-shut-down-a-jersey-generated-jetty-webserver-in-case-createserver-throw. It appears to be a bug.)

I use Jersey to create a Jetty webserver like this:

ResourceConfig context = new ResourceConfig();
...
URI baseUri = ...
Server server = JettyHttpContainerFactory.createServer(baseUri, context);

If the port the Jetty server attempts to bind to is taken, the createServer() method throws a ProcessingException. However, the server stays alive in some kind of limbo with several threads running, but (obviously) without functioning.

Since the ProcessingException was thrown during the createServer() call, my server variable is never set, and I thus have no way to access the server just created in order to call the stop() method on it.

How do I shut it down the broken server in a clean way? I do not want to kill the entire application using System.exit().



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

Hi, thanks for reporting the issue.
I am not sure, if calling server.stop() will solve this, or if anything reasonable we can do in the catch clause will help at all, but we should try it.

Moving the issue to backlog, so that we can take a look at it in one of the future sprints.

Regards,
Adam





[JERSEY-2892]