[JERSEY-2902] Enable EntityFiltering will cause jackson annotation JsonProperty acting unexpectedly. Created: 02/Jul/15  Updated: 02/Jul/15

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

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.






[JERSEY-2901] Return CompletableFuture from ApplicationHandler.apply() instead of Future Created: 01/Jul/15  Updated: 01/Jul/15

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

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


 Description   

It would be great if ApplicationHandler.apply(x, y) could return CompletableFuture instead of Future.

The problem with Future is that there is no way for client asynchronously getting result without blocking the thread. It's highly ineffective in high-load server.

CompletableFuture was instroduced in JDK 1.8. If dependency on 1.8 is blocker we could use vanilla interface such as

public interface CompletionCallback {
    public void onComplete(ContainerResponse response);
}

and add ApplicationHandler.setCompletionHandler(CompletionCallback callback).

Currently I have to use ugly hack as follows

    class OutputStreamCompletion<T> extends OutputStream {

        final private OutputStream stream;
        final private Promise<Future<T>> promise;

        private Future<T> javaFuture;

        public OutputStreamCompletion(@NotNull OutputStream stream, @NotNull Promise<Future<T>> promise) {
            this.stream = stream;
            this.promise = promise;
        }

        @Override
        public void write(int b) throws IOException {
            stream.write(b);
        }

        @Override
        public void write(@NotNull byte b[]) throws IOException {
            stream.write(b);
        }

        @Override
        public void write(@NotNull byte b[], int off, int len) throws IOException {
            stream.write(b, off, len);
        }

        @Override
        public void flush() throws IOException {
            stream.flush();
        }

        @Override
        public void close() throws IOException {
            stream.close();
            promise.success(javaFuture);
        }

        public void setJavaFuture(@NotNull Future<T> future) {
            this.javaFuture = future;
        }
    }


 Comments   
Comment by Michal Gajdos [ 01/Jul/15 ]

This won't happen in Jersey 2.x, which implements JAX-RS 2.0, because the spec says that the implementation has to run on Java 7. However JAX-RS 2.1 (currently in progress) will require Java 8 and that's the moment when this topic can be discussed. Work on the next version of Jersey (based on JAX-RS 2.1) should start soon so stay tuned Moving to backlog for now.

Comment by cppexpert [ 01/Jul/15 ]

How about using custom `CompletionCallback` ? It will work on 1.7 and won't violate the standard I assume.





[JERSEY-2900] Jersey client randomly tries to perform CONNECT requests receiving 400 Bad Request Created: 01/Jul/15  Updated: 01/Jul/15

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

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


 Description   

We use jersey client to make GET requests to an external party. The external party responds with 400 Bad Request 2 out of 5 times.
This started happening after updating jersey to 2.17 from 2.13. Jersey 2.13 has 100% succes rate.

The reason is the jersey client 2.17 sometimes randomly performs a CONNECT request instead of a GET request. It is also striking that the User-Agent header in the request is different.
The good requests has "Jersey / 2:17 (Http URLConnection 1.7.0_79)" and the bad requests this "Java / 1.7.0_79".

Client code:

ClientConfig clientConfig = new ClientConfig();
clientConfig.register(JacksonXMLProvider.class);
Client client = ClientBuilder.newClient(clientConfig);
webTarget = client.target("https://api.externalEndpoint.com/api/");
String messageResponse = webTarget.request(MediaType.APPLICATION_XML_TYPE).get(String.class);

Stack trace:

javax.ws.rs.BadRequestException: HTTP 400 Bad Request
at org.glassfish.jersey.client.JerseyInvocation.convertToException(JerseyInvocation.java:981) ~[jersey-client-2.17.jar:na]
at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:799) ~[jersey-client-2.17.jar:na]
at org.glassfish.jersey.client.JerseyInvocation.access$500(JerseyInvocation.java:91) ~[jersey-client-2.17.jar:na]
at org.glassfish.jersey.client.JerseyInvocation$2.call(JerseyInvocation.java:687) ~[jersey-client-2.17.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:315) ~[jersey-common-2.17.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:297) ~[jersey-common-2.17.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:228) ~[jersey-common-2.17.jar:na]
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:444) ~[jersey-common-2.17.jar:na]
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:683) ~[jersey-client-2.17.jar:na]
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:411) ~[jersey-client-2.17.jar:na]
at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:307) ~[jersey-client-2.17.jar:na]

The following request, sent by the Jersey client about 3 out of 5 times, can be processed successfully:

T 192.168.1.1:37907 -> 192.168.1.12:81 [AP]
GET /api/call/?responsetype=XML&username=xxxx&
&sender=xxxxx&body=xxxxxxx&destination=
xxxxxxxxx HTTP/1.1..Accept: application/xml..User-Agent: Jersey/2.17 (Http
UrlConnection 1.7.0_79)..Cache-Control: no-cache..Pragma: no-cache..Host: a
pi.externalEndpoint.com..Connection: keep-alive..X-Forwarded-For: 213.206.243.18
..X-Forwarded-Proto: https....

But the following request, sent by the Jersey client about 2 out of 5 times, results in a response stating "400 Bad request":

T 2015/06/18 12:12:20.741123 192.168.1.1:43322 -> 192.168.1.11:81 [AP]
CONNECT api.externalEndpoint.com:443 HTTP/1.1..User-Agent: Java/1.7.0_79..Host:
api.externalEndpoint.com..Accept: text/html, image/gif, image/jpeg, ; q=.2, */
; q=.2..Proxy-Connection: keep-alive..X-Forwarded-For: 213.206.243.18..X-Fo
rwarded-Proto: https....

We can not find any pattern why this is happening.






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

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

Type: Bug Priority: Major
Reporter: brcolow Assignee: Unassigned
Resolution: Unresolved 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.






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

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

Type: Bug Priority: Minor
Reporter: ralphwen Assignee: Unassigned
Resolution: Unresolved 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






[JERSEY-2897] change log level Created: 28/Jun/15  Updated: 28/Jun/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: None
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.






[JERSEY-2896] Port to simpleframework 6.0.1 Created: 27/Jun/15  Updated: 27/Jun/15

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

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


 Comments   
Comment by puntogil [ 27/Jun/15 ]

diff -Nru jersey-2.18/containers/simple-http/pom.xml jersey-2.18.simple/containers/simple-http/pom.xml
— jersey-2.18/containers/simple-http/pom.xml 2015-06-27 19:55:52.092656409 +0200
+++ jersey-2.18.simple/containers/simple-http/pom.xml 2015-06-27 20:03:12.623837317 +0200
@@ -61,7 +61,18 @@
</dependency>
<dependency>
<groupId>org.simpleframework</groupId>

  • <artifactId>simple</artifactId>
    + <artifactId>simple-common</artifactId>
    + <version>$ {simple.version}</version>
    + </dependency>
    + <dependency>
    + <groupId>org.simpleframework</groupId>
    + <artifactId>simple-http</artifactId>
    + <version>${simple.version}

    </version>
    + </dependency>
    + <dependency>
    + <groupId>org.simpleframework</groupId>
    + <artifactId>simple-transport</artifactId>
    + <version>$

    {simple.version}</version>
    </dependency>
    </dependencies>

    diff -Nru jersey-2.18/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java jersey-2.18.simple/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java
    — jersey-2.18/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java 2015-06-03 19:07:50.000000000 +0200
    +++ jersey-2.18.simple/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainerFactory.java 2015-06-27 19:10:22.696774254 +0200
    @@ -57,8 +57,7 @@
    import org.glassfish.hk2.api.ServiceLocator;

    import org.simpleframework.http.core.Container;
    -import org.simpleframework.http.core.ContainerServer;
    -import org.simpleframework.transport.Server;
    +import org.simpleframework.http.core.ContainerSocketProcessor;
    import org.simpleframework.transport.connect.Connection;
    import org.simpleframework.transport.connect.SocketConnection;

    @@ -180,10 +179,11 @@
    public static SimpleServer create(final URI address,
    final SSLContext context,
    final SimpleContainer container) {
    - return _create(address, context, container, new UnsafeValue<Server, IOException>() {
    + return _create(address, context, container, new UnsafeValue<ContainerSocketProcessor, IOException>() {
    @Override
    - public Server get() throws IOException {
    - return new ContainerServer(container);
    + public ContainerSocketProcessor get() throws IOException { + ContainerSocketProcessor csp = new ContainerSocketProcessor(container); + return csp; }
    });
    }
    @@ -241,10 +241,11 @@
    final int count,
    final int select) throws ProcessingException {

    - return _create(address, context, container, new UnsafeValue<Server, IOException>() {
    + return _create(address, context, container, new UnsafeValue<ContainerSocketProcessor, IOException>() {
    @Override
    - public Server get() throws IOException {
    - return new ContainerServer(container, count, select);
    + public ContainerSocketProcessor get() throws IOException { + ContainerSocketProcessor csp = new ContainerSocketProcessor(container, count, select); + return csp; }
    });
    }
    @@ -252,7 +253,7 @@
    private static SimpleServer _create(final URI address,
    final SSLContext context,
    final SimpleContainer container,
    - final UnsafeValue<Server, IOException> serverProvider) throws ProcessingException {
    + final UnsafeValue<ContainerSocketProcessor, IOException> serverProvider) throws ProcessingException {
    if (address == null) { throw new IllegalArgumentException(LocalizationMessages.URI_CANNOT_BE_NULL()); }
    @@ -277,7 +278,7 @@
    final InetSocketAddress listen = new InetSocketAddress(port);
    final Connection connection;
    try {
    - final Server server = serverProvider.get();
    + final ContainerSocketProcessor server = serverProvider.get();
    connection = new SocketConnection(server);

    final SocketAddress socketAddr = connection.connect(listen, context);
    diff -Nru jersey-2.18/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java jersey-2.18.simple/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java
    — jersey-2.18/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java 2015-06-03 19:07:50.000000000 +0200
    +++ jersey-2.18.simple/containers/simple-http/src/main/java/org/glassfish/jersey/simple/SimpleContainer.java 2015-06-27 19:58:50.104243748 +0200
    @@ -280,7 +280,8 @@

    @Override
    public Principal getUserPrincipal() { - return request.getSecuritySession().getLocalPrincipal(); + Principal rqst = (Principal) request.getClientCertificate(); + return rqst; }

    @Override
    diff -Nru jersey-2.18/pom.xml jersey-2.18.simple/pom.xml
    — jersey-2.18/pom.xml 2015-06-27 19:55:52.100656031 +0200
    +++ jersey-2.18.simple/pom.xml 2015-06-27 20:04:00.236587182 +0200
    @@ -1229,7 +1229,17 @@

    <dependency>
    <groupId>org.simpleframework</groupId>
    - <artifactId>simple</artifactId>
    + <artifactId>simple-common</artifactId>
    + <version>${simple.version}

    </version>
    + </dependency>
    + <dependency>
    + <groupId>org.simpleframework</groupId>
    + <artifactId>simple-http</artifactId>
    + <version>$

    {simple.version}</version>
    + </dependency>
    + <dependency>
    + <groupId>org.simpleframework</groupId>
    + <artifactId>simple-transport</artifactId>
    <version>${simple.version}

    </version>
    </dependency>

@@ -1637,7 +1647,7 @@
<rxjava.version>1.0.4</rxjava.version>
<servlet2.version>2.4</servlet2.version>
<servlet3.version>3.0.1</servlet3.version>

  • <simple.version>5.1.4</simple.version>
    + <simple.version>6.0.1</simple.version>
    <spring3.version>3.2.3.RELEASE</spring3.version>
    <validation.api.version>1.1.0.Final</validation.api.version>
    <weld.version>2.2.8.Final</weld.version>




[JERSEY-2895] WebComponent eats the HeaderValueException silent without giving any clue. Created: 26/Jun/15  Updated: 26/Jun/15

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

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


 Description   

The actual code is here: https://github.com/jersey/jersey/blob/master/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/WebComponent.java#L411-L421

This piece of code is working fine. However, the actual hve instance is valuable for debugging/troubleshooting purpose. We should log this in the appropriate level so when user set up j.u.l properly, this information is logged.

P.S. No patch since it is just a one-liner. But would not mind to submit a PR if asked.






[JERSEY-2894] [jersey-entity-filter] ConcurrentModificationException Created: 26/Jun/15  Updated: 03/Jul/15

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

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

Jetty9.2. Java8



 Description   

https://jersey.java.net/documentation/latest/entity-filtering.html
After enable `SelectableEntityFilteringFeature`, it trigger `ConcurrentModificationException` and causing response data corrupted.

register(SelectableEntityFilteringFeature.class);
property(SelectableEntityFilteringFeature.QUERY_PARAM_NAME, "field");

The stack trace:

Caused by: java.util.ConcurrentModificationException: null
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429) ~[na:1.8.0_25]
at java.util.HashMap$EntryIterator.next(HashMap.java:1463) ~[na:1.8.0_25]
at java.util.HashMap$EntryIterator.next(HashMap.java:1461) ~[na:1.8.0_25]
at jersey.repackaged.com.google.common.collect.AbstractMapBasedMultimap$AsMap$AsMapIterator.next(AbstractMapBasedMultimap.java:1352) ~[jersey-guava-2.13.jar:na]
at jersey.repackaged.com.google.common.collect.AbstractMapBasedMultimap$AsMap$AsMapIterator.next(AbstractMapBasedMultimap.java:1340) ~[jersey-guava-2.13.jar:na]
at java.util.AbstractMap$2$1.next(AbstractMap.java:396) ~[na:1.8.0_25]
at jersey.repackaged.com.google.common.collect.AbstractMultimap.containsValue(AbstractMultimap.java:45) ~[jersey-guava-2.13.jar:na]
at jersey.repackaged.com.google.common.collect.HashMultimap.containsValue(HashMultimap.java:49) ~[jersey-guava-2.13.jar:na]
at org.glassfish.jersey.message.filtering.EntityGraphImpl.presentInScopes(EntityGraphImpl.java:197) ~[jersey-entity-filtering-2.13.jar:na]
at org.glassfish.jersey.message.filtering.DefaultEntityProcessor.process(DefaultEntityProcessor.java:95) ~[jersey-entity-filtering-2.13.jar:na]
at org.glassfish.jersey.message.filtering.DefaultEntityProcessor.process(DefaultEntityProcessor.java:79) ~[jersey-entity-filtering-2.13.jar:na]
at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspectEntityProperties(EntityInspectorImpl.java:166) ~[jersey-entity-filtering-2.13.jar:na]
at org.glassfish.jersey.message.filtering.EntityInspectorImpl.inspect(EntityInspectorImpl.java:102) ~[jersey-entity-filtering-2.13.jar:na]
at org.glassfish.jersey.message.filtering.spi.AbstractObjectProvider.getFilteringObject(AbstractObjectProvider.java:86) ~[jersey-entity-filtering-2.13.jar:na]
at org.glassfish.jersey.message.filtering.spi.AbstractObjectProvider.getFilteringObject(AbstractObjectProvider.java:80) ~[jersey-entity-filtering-2.13.jar:na]
at org.glassfish.jersey.moxy.json.internal.FilteringMoxyJsonProvider.preReadFrom(FilteringMoxyJsonProvider.java:96) ~[jersey-media-moxy-2.13.jar:na]
at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.readFrom(MOXyJsonProvider.java:568) ~[org.eclipse.persistence.moxy-2.5.0.jar:na]
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:258) ~[jersey-common-2.13.jar:na]
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:234) ~[jersey-common-2.13.jar:na]
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:154) ~[jersey-common-2.13.jar:na]
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:73) ~[jersey-server-2.13.jar:na]
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:154) ~[jersey-common-2.13.jar:na]
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1124) ~[jersey-common-2.13.jar:na]
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:851) ~[jersey-common-2.13.jar:na]
at org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:270) ~[jersey-server-2.13.jar:na]
at org.glassfish.jersey.server.internal.inject.EntityParamValueFactoryProvider$EntityValueFactory.provide(EntityParamValueFactoryProvider.java:96) ~[jersey-server-2.13.jar:na]
at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:81) ~[jersey-server-2.13.jar:na]
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:121) ~[jersey-server-2.13.jar:na]



 Comments   
Comment by Adam Lindenthal [ 03/Jul/15 ]

Hi,
thanks for reporting.
Does this occur every time you just turn on the feature, regardless the application? Even with the smallest possible jersey test case (some hello-world app)?
Or do I need some additional steps to reproduce? A minimalistic reproducer test-case or mini-app would be appreciated (ideally something maven-based), you could share it through github or send me a zip and I would attach it here.

Thanks,
Adam





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

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

Type: Bug Priority: Major
Reporter: diar_ahmed Assignee: Unassigned
Resolution: Unresolved 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
a. the packages api explicitly creates an instance of PackageNamesScanner and registers a the packages, which creates a ResourceFinderStack()
b. 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.
c. ResourceConfig.getClasses() then caches the classes in the ResourceConfig instance.
d. When runtime rest processing starts, a WrappingResourceConfig is created which copies the internal state of the ResourceConfig, but doesn't copy the class cache
e. 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"); }

}





[JERSEY-2892] If the same class appears in the object graph more than once, EntityFiltering incorrectly filters its properties Created: 23/Jun/15  Updated: 23/Jun/15

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

Type: Bug Priority: Major
Reporter: bedag-moo Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: entity-filtering
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

If objects of the same class appear more than once in the serialization graph, JacksonObjectProvider causes their properties to be filtered even if there are no filtering annotations present.

*test case*
The resource

@Path("test")
@Produces(MediaType.APPLICATION_JSON)
public class TestResource {

    @GET
    public Issue issue() {
        return new Issue();
    }

    public static class Issue {
        public Person reporter = new Person();
        public Person assignee = new Person();
    }

    public static class Person {
        public Address address = new Address();
    }

    public static class Address {
        public Name name = new Name();
        public String town = "Town";
    }

    public static class Name {
        public String first = "John";
        public String last = "Doe";
    }
}

returns the following JSON document

{
  "reporter":{
    "address":{
      "name":{
        "first":"John",
        "last":"Doe"
      },
      "town":"Town"
     }
  },
  "assignee":{
    "address":{
      "town":"Town"
    }
  }
}

As you can see, even though assignee and reporter refer to equal objects, their "name" property is only serialized the first time.



 Comments   
Comment by bedag-moo [ 23/Jun/15 ]

In rather painstaking labor, I have tracked this down to JacksonObjectProvider.createSubfilters, which reads:

            final String fieldName = entry.getKey();
            final ObjectGraph graph = entry.getValue();

            final String path = parent + "." + fieldName;

            // Subgraph Fields.
            final Map<String, ObjectGraph> subgraphs = graph.getSubgraphs(path);

            final Class<?> subEntityClass = graph.getEntityClass();
            final String processedSubgraph = getProcessedSubgraph(entityClass, fieldName, subEntityClass);

            Map<String, FilteringPropertyFilter> subSubfilters = new HashMap<>();
            if (!subgraphs.isEmpty() && !processed.contains(processedSubgraph)) {
                processed.add(processedSubgraph);
                subSubfilters = createSubfilters(path, subEntityClass, subgraphs, processed);
            }

            subfilters.put(fieldName, new FilteringPropertyFilter(graph.getEntityClass(), graph.getFields(path), subSubfilters));

The last line creates a new FilteringPropertyFilter for the field, passing it `subSubfilters`, which is only added to if `!processed.contains(processedSubgraph)`. However, processedSubgraph only depends on the subfield being checked. Therefore, if the same class is encountered more than once, this condition is false for all but the first occurence, causing subfilters to remain empty, which in turn causes all properties of complex type to be filtered out for all but the first occurence of that class in the object graph.





[JERSEY-2891] ExceptionMapper not chosen correctly in case of multiple ExtendedExceptionMappers with same generic type Created: 22/Jun/15  Updated: 24/Jun/15  Resolved: 24/Jun/15

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

Type: Bug Priority: Minor
Reporter: tknappek Assignee: Michal Gajdos
Resolution: Fixed Votes: 0
Labels: pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

If there are two extended mappers defined as the following:

public final class ExceptionMapper1 implements ExtendedExceptionMapper<RuntimeException> {

    @Override
    public Response toResponse(RuntimeException e) {
        // whatever
    }

    @Override
    public boolean isMappable(RuntimeException exception) {      
        return exception instanceof IllegalStateException || exception instanceof IllegalArgumentException;
    }
}
public final class ExceptionMapper2 implements ExtendedExceptionMapper<RuntimeException> {

    @Override
    public Response toResponse(RuntimeException e) {
        // whatever
    }

    @Override
    public boolean isMappable(RuntimeException exception) {      
        return exception instanceof NullPointerException || exception instanceof ClassCastException;
    }
}

If there is any resource which (for example) throws IllegalStateException, then sometimes the exception is handled by the correct handler (ExceptionMapper1) in this case and sometimes it is not handled at all.

The reason is that org.glassfish.jersey.internal.ExceptionMapperFactory#find(final Class<T> type, final T exceptionInstance) does the following:

for (final ExceptionMapperType mapperType : exceptionMapperTypes) {
            final int d = distance(type, mapperType.exceptionType);
            if (d >= 0) {
                orderedMappers.put(d, mapperType.mapper.getService());
            }
        }

Since both mappers have the same distance (1) the mappers are overwritten in the orderedMappers map.






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

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

Type: Bug Priority: Major
Reporter: sampatn Assignee: Adam Lindenthal
Resolution: Unresolved Votes: 0
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
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?





[JERSEY-2889] spring-jersey assumes all beans have a definition Created: 15/Jun/15  Updated: 15/Jun/15

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

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


 Description   

From the Spring documentation:

In addition to bean definitions that contain information on how to create a specific bean, the ApplicationContext implementations also permit the registration of existing objects that are created outside the container, by users. This is done by accessing the ApplicationContext’s BeanFactory via the method getBeanFactory() which returns the BeanFactory implementation DefaultListableBeanFactory. DefaultListableBeanFactory supports this registration through the methods registerSingleton(..) and registerBeanDefinition(..). However, typical applications work solely with beans defined through metadata bean definitions.

However, spring-jersey will throw an Exception that will stop startup if it encounters a bean with no definition.

https://github.com/jersey/jersey-1.x/blob/master/contribs/spring/src/main/java/com/sun/jersey/spi/spring/container/SpringComponentProviderFactory.java#L145

I think these beans should simply be ignored with a log message explaining why they are being skipped.






[JERSEY-2888] NoClassDefFoundError when doing bean validation Created: 15/Jun/15  Updated: 15/Jun/15

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

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

Glassfish 4.1 nightly as of Jun 14, 2015



 Description   

When using bean validation with @RequestScoped Rest beans,
the exception occurs.
However, when @RequestScoped is replaced by @Stateless,
the exception goes away.

Code:

package com.baw.website.restapi.internal;

import java.net.URI;
import javax.enterprise.context.RequestScoped;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.ws.rs.FormParam;
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.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * REST Web Service
 *
 * @author lprimak
 */
@Path("/sample")
@RequestScoped @Slf4j
public class Sample
{
    /**
     * How to test:
     * curl --data "name=lenny&age=39" --dump-header headers -D - --header "Accept: application/json" http://localhost:8080/baw-website/internalapi/sample
     * 
     * @param name
     * @param age
     * @param context
     * @return 
     */
    @POST
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response postXml(@NotNull @Size(min = 2, max = 100) @FormParam("name") String name, 
            @NotNull @Digits(integer = 3, fraction = 0) @FormParam("age") Integer age,
            @Context UriInfo context)
    {
        URI absPath = context.getAbsolutePath();
        return Response.created(absPath).entity(new Person(name, age)).build();
    }

    
    @AllArgsConstructor @NoArgsConstructor
    @Getter @XmlRootElement 
    @XmlAccessorType(XmlAccessType.FIELD)
    private static class Person
    {
        private String name;
        private Integer age;
    }
}

Exception:

[2015-06-15T16:27:53.794-0400] [glassfish 4.1] [WARNING] [] [javax.enterprise.web] [tid: _ThreadID=192 _ThreadName=ajp-listener-1(3)] [timeMillis: 1434400073794] [levelValue: 900] [[
  StandardWrapperValve[com.baw.website.restapi.config.InternalApiConfig]: Servlet.service() for servlet com.baw.website.restapi.config.InternalApiConfig threw exception
java.lang.NoClassDefFoundError: Could not initialize class org.eclipse.persistence.jaxb.BeanValidationHelper
	at org.eclipse.persistence.jaxb.JAXBBeanValidator.isConstrainedObject(JAXBBeanValidator.java:257)
	at org.eclipse.persistence.jaxb.JAXBBeanValidator.shouldValidate(JAXBBeanValidator.java:208)
	at org.eclipse.persistence.jaxb.JAXBMarshaller.validateAndTransformIfNeeded(JAXBMarshaller.java:587)
	at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:481)
	at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:949)
	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.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
	at com.flowlogix.filters.EjbPingFilter.doFilter(EjbPingFilter.java:61)
	at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
	at com.baw.website.restapi.config.InternalApiProtectionFilter.doFilter(InternalApiProtectionFilter.java:27)
	at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
	at com.baw.website.filters.CmsFilter.doFilter(CmsFilter.java:32)
	at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
	at org.omnifaces.filter.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:122)
	at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
	at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
	at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
	at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
	at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
	at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
	at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316)
	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:565)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
	at java.lang.Thread.run(Thread.java:745)
]]


 Comments   
Comment by lprimak [ 15/Jun/15 ]

Actually, @Stateless fails too.
I think it has something to do with @Digits annotation,
as other annotations not not fail.

Comment by lprimak [ 15/Jun/15 ]

Maybe not digits, perhaps it's related to this:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=463169

Comment by lprimak [ 15/Jun/15 ]

Definitely related to EclipseLink:

java.lang.ClassNotFoundException: org.xml.sax.helpers.DefaultHandler not found by org.eclipse.persistence.moxy [188]
	at org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532)
	at org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
	at org.apache.felix.framework.BundleWiringImpl$BundleClassLoader.loadClass(BundleWiringImpl.java:1955)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at org.eclipse.persistence.jaxb.BeanValidationHelper.<clinit>(BeanValidationHelper.java:53)
	at org.eclipse.persistence.jaxb.JAXBBeanValidator.isConstrainedObject(JAXBBeanValidator.java:257)
	at org.eclipse.persistence.jaxb.JAXBBeanValidator.shouldValidate(JAXBBeanValidator.java:208)
	at org.eclipse.persistence.jaxb.JAXBMarshaller.validateAndTransformIfNeeded(JAXBMarshaller.java:587)
	at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:481)
	at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:949)
Comment by lprimak [ 15/Jun/15 ]

It is indeed an EclipseLink issue above. Please close this ticket





[JERSEY-2887] Add the support of the @Resource annotation to the Spring3 extension Created: 12/Jun/15  Updated: 15/Jun/15

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

Type: New Feature Priority: Major
Reporter: olivier.billiard Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: spring
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: spring3

 Description   

At the moment only the Autowire annotation is supported by the Spring3 extension. In most of the cases this is enough but when the generics are involved it is better to look for the beans by their name and not their type.
To solve this we need to add the support of the Resource annotation.



 Comments   
Comment by olivier.billiard [ 12/Jun/15 ]

I already prepared the fix and modified an example to show how to use it.
How can I give that to you or push it to the git? At the moment I have a permission denied.

Thanks

Comment by Michael Osipov [ 13/Jun/15 ]

Fork on GitHub, provide a pull request.

Comment by olivier.billiard [ 15/Jun/15 ]

Thanks Michael, I created the pull request.





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

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

Type: Bug Priority: Major
Reporter: justin.emery Assignee: Unassigned
Resolution: Unresolved 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





[JERSEY-2885] Chunked responses can be corrupt and truncated: broken synchronization Created: 10/Jun/15  Updated: 10/Jun/15

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

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


 Description   

We have services streaming responses using ChunkedOutput. These responses are sometimes corrupt causing the client to reset the connection.

Inspecting the packets show bad response chunks - e.g. chunk length is 8192 but following chunk is longer and contain corrupt data (looks like one chunk scribbled on top of another).

Found a synchronization problem in ChunkedOutput - fixing has stopped the problem (so far).

ChunkedOutput line 196: synchronized(this) should be synchronized(ChunkedOutput.this)

See: https://gist.github.com/anonymous/cd4fe0076a39d10caeb2






[JERSEY-2884] jersey version 2.18 does not contain ResourceConfig Created: 10/Jun/15  Updated: 10/Jun/15

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

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


 Description   

no classes
org.glassfish.jersey.media.multipart.MultiPartFeature;
org.glassfish.jersey.server.ResourceConfig
com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
org.glassfish.jersey.jackson.JacksonFeature;
org.glassfish.jersey.media.multipart.FormDataContentDisposition;
org.glassfish.jersey.media.multipart.FormDataParam;

after moving to 2.18
maybe some workaround exiats?






[JERSEY-2883] Refactor Jersey Proxy Client Created: 10/Jun/15  Updated: 10/Jun/15

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

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


 Description   

Currently its implementation is somewhat big blob like method which dosen't even follow good practices of structural code.

We should divide its functionality in a more OOP like manner befor expanding it.

I'll prepare a pull request suggesting the direction I would like to take.






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

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

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

java 1.8, Win8.1



 Description   

I see no way to put a stream or other non-retryable payload while using DIGEST auth. This is something we could do with Jersey 1.17 client.

Since digest requires a challenge-response, we have two choices for non-retryable payloads:
1) buffer the stream and send it with both the first and second request
2) make a separate auth-only request first to get the Authorization token then use it to put the non-retryable payload

I see no way to do either using Jersey/Jax-RS 2.17, even when using httpclient as the connector. httpclient offers AuthCache but I see no way to access that via Jersey/JAX-RS.

Am I right to consider it a MUST requirement for Jersey/JAX-RS to support digest auth and non-retryable payloads (such as InputStream)?

Here's the code that fails with "IOException: Stream closed". I'm testing it against MarkLogic server but any web service which supports digest would have the same problem.

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.RequestEntityProcessing;

import java.io.StringReader;

public class Jersey217Test {
public static void main(String[] args)

{ String user = "admin"; String pass = "admin"; ClientConfig clientConfig = new ClientConfig(); clientConfig.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.BUFFERED); Client client = ClientBuilder.newClient(clientConfig); client.register(HttpAuthenticationFeature.digest(user, pass)); StringReader reader = new StringReader("test"); WebTarget connection = client.target("http://localhost:8000/v1/documents"); connection .queryParam("uri", "test.txt") .request((String) null) .put(Entity.entity(reader, "text/plain")); Response response = connection .queryParam("uri", "test.txt") .request("text/plain").get(); String body = response.readEntity(String.class); System.out.println("Body=[" + body + "]"); }

}



 Comments   
Comment by sammefford [ 15/Jun/15 ]

Here's a follow-up. I found a work-around but it's not what I need. If I use the same WebTarget it looks like follow-up requests are authenticated:

public class Jersey217Test {
    public static void main(String[] args) {
        String user = "admin";
        String pass = "admin";
        String baseUri = "http://localhost:8000/v1/";

        ClientConfig clientConfig = new ClientConfig();

        Client client = ClientBuilder.newClient(clientConfig);
        client.register(HttpAuthenticationFeature.digest(user, pass));
        StringReader reader = new StringReader("test");
        WebTarget base = client.target(baseUri).path("documents")
            .queryParam("uri", "test.txt");
        Response response = base
            .request(MediaType.MEDIA_TYPE_WILDCARD)
            .head();
        response.close();
        response = base
            .request(MediaType.MEDIA_TYPE_WILDCARD)
            .put(Entity.entity(reader, "text/plain"));
        response.close();
        response = base
            .request("text/plain").get();
        String body = response.readEntity(String.class);
        System.out.println("Body=[" + body + "]");
    }
}

The problem is that any method that generates a new WebTarget (such as queryParam) loses the authentication. So I'm seeing no viable way to authenticate once then make multiple requests with the same authentication. More specifically, I see no way to make an auth-only request prior to a non-retryable put method request unless the auth-only request can match exactly the url of the non-retryable request which is not always going to work in my scenario.





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

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

Type: Bug Priority: Major
Reporter: duanem Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
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





[JERSEY-2880] Link HTTP Header: Headers may contain double-quote-less parameters. Created: 08/Jun/15  Updated: 08/Jun/15

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

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



 Description   

The current implementation of the client doesn't accept valid-formed parameters without double-quotes:

Link: </TheBook/chapter2>; rel=previous

doesn't get accepted, but

Link: </TheBook/chapter2>; rel="previous"

is ok.

Please see http://tools.ietf.org/html/rfc5988#section-5
which permits rel, rev, type and many more being without double quotes:

Link           = "Link" ":" #link-value
  link-value     = "<" URI-Reference ">" *( ";" link-param )
  link-param     = ( ( "rel" "=" relation-types )
                 | ( "anchor" "=" <"> URI-Reference <"> )
                 | ( "rev" "=" relation-types )
                 | ( "hreflang" "=" Language-Tag )
                 | ( "media" "=" ( MediaDesc | ( <"> MediaDesc <"> ) ) )
                 | ( "title" "=" quoted-string )
                 | ( "title*" "=" ext-value )
                 | ( "type" "=" ( media-type | quoted-mt ) )
                 | ( link-extension ) )
  link-extension = ( parmname [ "=" ( ptoken | quoted-string ) ] )
                 | ( ext-name-star "=" ext-value )
  ext-name-star  = parmname "*" ; reserved for RFC2231-profiled
                                ; extensions.  Whitespace NOT
                                ; allowed in between.
  ptoken         = 1*ptokenchar
  ptokenchar     = "!" | "#" | "$" | "%" | "&" | "'" | "("
                 | ")" | "*" | "+" | "-" | "." | "/" | DIGIT
                 | ":" | "<" | "=" | ">" | "?" | "@" | ALPHA
                 | "[" | "]" | "^" | "_" | "`" | "{" | "|"
                 | "}" | "~"
  media-type     = type-name "/" subtype-name
  quoted-mt      = <"> media-type <">
  relation-types = relation-type
                 | <"> relation-type *( 1*SP relation-type ) <">
  relation-type  = reg-rel-type | ext-rel-type
  reg-rel-type   = LOALPHA *( LOALPHA | DIGIT | "." | "-" )
  ext-rel-type   = URI

The jersey client doesn't accept valid server responses without this change. I'd suggest including the pull request in the next release.






[JERSEY-2879] Link HTTP Header: Comma separated links don't get parsed correctly Created: 08/Jun/15  Updated: 08/Jun/15

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

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.






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

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

Type: Bug Priority: Major
Reporter: seanjreilly Assignee: Unassigned
Resolution: Unresolved 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.





[JERSEY-2877] Cookie parameter name when given an MBCS(Multi-Byte) text is not accepted in jsersey Rest Services Created: 05/Jun/15  Updated: 10/Jun/15

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

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

JDEVADF_MAIN_GENERIC_150530.2131.S



 Description   

Jersey Rest Services in Oracle Jdeveloper:
1.Create a jersey Rest Service is created with GET,PUT, POST, DELETE methods
2.Configure parameter as "Cookie Parameter Type" (For eg: DELETE METHOD)
3.Specify the parameter name some MBCS text
4.Run the Jersey Rest Service

Observed Behavior:
When the cookie parameter name is MBCS, the operation is not getting performed
When the cookie parameter name is ASCII. it works fine



 Comments   
Comment by RekhaTavvala [ 10/Jun/15 ]

This issue is not a real usecase. It is a corner case which the developers may not using. This issue can be closed





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

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

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

]
}






[JERSEY-2875] JettyHttpContainerFactory leaves server in limbo after throwing a ProcessingException during createServer() Created: 04/Jun/15  Updated: 04/Jun/15

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

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().






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

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

Type: Bug Priority: Major
Reporter: jehrlich Assignee: Unassigned
Resolution: Unresolved 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-2873] java web start client authentification security Created: 29/May/15  Updated: 29/May/15

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

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 ?






[JERSEY-2872] ConnectionCallback does not fire when client dropped a connection Created: 28/May/15  Updated: 28/May/15

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

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


 Comments   
Comment by weichengpan [ 28/May/15 ]

Hi, I have a use case to execute expensive computations,
and I would like to check if connection is drop or not before executing expensive computation.

It'll be great if the callback fired when client dropped, not at the time when writing something to ChunkedOutput.

AsyncResource.java
@Path("/async/Expensive")
@Singleton
public class AsyncResource {
    @Context ExecutorService executorService;
    @Context BusinessLogic businessLogic;
    static Logger logger = LoggerFactory.getLogger(AsyncResource.class);

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @ManagedAsync
    public void getExpensive (
        @PathParam("value") Integer value,
        @Suspended final AsyncResponse res) {
        final Future<?> submit;

        submit = executorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    res.resume(businessLogic.getExpensive(value));
                } catch (InterruptedException e) {
                }
            }
        });

        res.register(new ConnectionCallback() {
            @Override
            public void onDisconnect(AsyncResponse disconnected) {
                submit.cancel(false);
            }
        });
    }




[JERSEY-2871] LoggingFilter does not match request and response numbers (like jersey 1.x did) Created: 26/May/15  Updated: 24/Jun/15  Resolved: 24/Jun/15

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

Type: Bug Priority: Major
Reporter: mtiihone Assignee: Michal Gajdos
Resolution: Fixed Votes: 1
Labels: logging, pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Tags: regression

 Description   

Jersey 1.x LoggingFilter logged request and response pairs with same request number prefix.

Jersey 2.x LoggingFilter always allocates a new prefix number also for responses. This makes it impossible to associate request and response pairs based on the prefix if there are concurrent requests using the same filter.



 Comments   
Comment by mtiihone [ 26/May/15 ]

Pull request fixing the issue: https://github.com/jersey/jersey/pull/168

Comment by Adam Lindenthal [ 26/May/15 ]

Hi,

thank you for opening the issue. As there is a pull request, I'll put the issue right in the backlog, where it stays until the pull request is processed and merged.

Thanks,
Adam





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

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

Type: Bug Priority: Major
Reporter: puntogil Assignee: Unassigned
Resolution: Unresolved 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





[JERSEY-2869] Jersey Client SSE Stream Chunking Incorrectly, Causing "in" notifications to be discarded Created: 20/May/15  Updated: 20/May/15

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

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

Windows 7, Eclipse Kepler SR2 (4.3.2), jdk1.7.0_75, jersey-media-sse 2.17, jersey-client 2.17



 Description   

I have a client application that utilizes the EventSource and EventListener classes to access an SSE stream on a separate server. Below is an example code snippet:

client = ClientBuilder.newClient()
	.register(SseFeature.class)
	.register(LoggingFilter.class);
	
WebTarget target = client.target("my_address_here");
eventSource = EventSource.target(target).build();

EventListener listener = new EventListener() {
	public void onEvent(InboundEvent inboundEvent) {
		System.out.println(inboundEvent.getId() + ":" + inboundEvent.getName());
	}
};

eventSource.register(listener);
eventSource.open();

The server I am connecting to sends keep-alive messages every ten seconds. These conform to the SSE standards as outlined below:

http://www.w3.org/TR/eventsource/#event-stream-interpretation

The stream must then be parsed by reading everything line by line, with a U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF) character pair, a single U+000A LINE FEED (LF) character not preceded by a U+000D CARRIAGE RETURN (CR) character, and a single U+000D CARRIAGE RETURN (CR) character not followed by a U+000A LINE FEED (LF) character being the ways in which a line can end.

When a stream is parsed, a data buffer, an event type buffer, and a last event ID buffer must be associated with it. They must be initialized to the empty string

Lines must be processed, in the order they are received, as follows:

If the line is empty (a blank line)
    Dispatch the event, as defined below.

If the line starts with a U+003A COLON character (:)
    Ignore the line.

If the line contains a U+003A COLON character (:)
    Collect the characters on the line before the first U+003A COLON character (:), and let field be that string.

    Collect the characters on the line after the first U+003A COLON character (:), and let value be that string. If value starts with a U+0020 SPACE character, remove it from value.

    Process the field using the steps described below, using field as the field name and value as the field value.

Otherwise, the string is not empty but does not contain a U+003A COLON character (:)
    Process the field using the steps described below, using the whole line as the field name, and the empty string as the field value.

Once the end of the file is reached, any pending data must be discarded. (If the file ends in the middle of an event, before the final empty line, the incomplete event is not dispatched.)

The steps to process the field given a field name and a field value depend on the field name, as given in the following list. Field names must be compared literally, with no case folding performed.

If the field name is "event"
    Set the event type buffer to field value.

If the field name is "data"
    Append the field value to the data buffer, then append a single U+000A LINE FEED (LF) character to the data buffer.

If the field name is "id"
    Set the last event ID buffer to the field value.

If the field name is "retry"
    If the field value consists of only ASCII digits, then interpret the field value as an integer in base ten, and set the event stream's reconnection time to that integer. Otherwise, ignore the field.

Otherwise
    The field is ignored.

The keep alive message is something like the following:

hex = 0x6B, 0x61, 0xD, 0xA, 0x3A, 0x20, 0xA, 0xA, 0xA, 0xD, 0xA
ascii = ['k', 'a', CR, LF, ‘:’, ‘ ‘, LF, LF, LF, CR, LF]

According to the W3C standard, the message should be parsed in the following way:
1) ['k', 'a', CR, LF] is identified as the first line, due to CRLF ending
2) Process the field and check if it is "event", "data", "id", or "retry". Since it is "ka" and does not match any of those options, ignore it.
3) Next line is identified as [':', ' ', LF] due to LF ending
4) The line starts with a colon character so ignore it.
5) Next line is [LF] due to LF ending. It is empty and therefore ignored.
6) Next line is [LF] due to LF ending. It is empty and therefore ignored.
7) Last line is [CR, LF] due to CRLF ending. It is empty and therefore ignored.
8) Close stream and finish processing using message body reader.

However, the observed behavior is different. The root of the issue is in the following code:

EventInput.java
public class EventInput extends ChunkedInput<InboundEvent> {
    /**
     * SSE event chunk parser - SSE chunks are delimited with a fixed "\n\n" delimiter in the response stream.
     */
    private static final ChunkParser SSE_EVENT_PARSER = ChunkedInput.createParser("\n\n");

['k', 'a', CR, LF, ‘:’, ‘ ‘, LF, LF, LF, CR, LF]
Because Jersey is looking for [LF,LF] to end events, this is what we get:
1) ['k', 'a', CR, LF, ':', ' ', LF, LF] is read as a line since it ends in [LF, LF]
2) "ka: " is not a recognized event, it is ignored.
3) [LF, CR, LF] is read in for this chunk and combined with the next chunk since no [LF, LF] was found to end the stream.
4) Next chunk has data and is ended with [LF, LF] so the chunk results in [LF, 'd', 'a', 't', 'a', 'e', 't', 'c', '.'].
5) The InboundEventReader.java sees that the chunk starts with a LF and it breaks out of processing the rest of the data in the stream and returns with object InboundEvent

{name='null', id='null', data=}

Below is the code that produces the behavior of #5:

InboundEventReader.java
    public InboundEvent readFrom(final Class<InboundEvent> type,
                                 final Type genericType,
                                 final Annotation[] annotations,
                                 final MediaType mediaType,
                                 final MultivaluedMap<String, String> headers,
                                 final InputStream entityStream) throws IOException, WebApplicationException {
        /**
         * SSE Event parsing based on:
         *
         * http://dev.w3.org/html5/eventsource/
         * last editors draft from 13 March 2012
         */
        final ByteArrayOutputStream tokenData = new ByteArrayOutputStream();
        final InboundEvent.Builder eventBuilder =
                new InboundEvent.Builder(messageBodyWorkers.get(), annotations, mediaType, headers);

        int b = -1;
        State currentState = State.NEW_LINE;
        loop:
        do {
            switch (currentState) {
                case NEW_LINE:
                    b = entityStream.read();
                    if (b == '\n' || b == -1) {
                        break loop;
                    }

                    if (b == ':') {
                        currentState = State.COMMENT;
                    } else {
                        tokenData.write(b);
                        currentState = State.FIELD;
                    }
                    break;
                case COMMENT:
                    // skipping comment data
                    b = readLineUntil(entityStream, '\n', null);
                    currentState = State.NEW_LINE;
                    break;
                case FIELD:
                    // read field name
                    b = readLineUntil(entityStream, ':', tokenData);
                    final String fieldName = tokenData.toString(MessageUtils.getCharset(mediaType).name());
                    tokenData.reset();

                    if (b == ':') {
                        // read field value
                        b = entityStream.read();
                        if (b == ' ') {
                            // first space in value has to be skipped
                            b = entityStream.read();
                        }

                        if (b != '\n' && b != -1) {
                            tokenData.write(b);
                            b = readLineUntil(entityStream, '\n', tokenData);
                        }
                    }

                    processField(eventBuilder, fieldName, mediaType, tokenData.toByteArray());
                    tokenData.reset();

                    currentState = State.NEW_LINE;
                    break;
            }
        } while (b != -1);

        return eventBuilder.build();
    }





[JERSEY-2868] MoxyObjectProvider does not handle classes with instance variables of same type correctly Created: 20/May/15  Updated: 03/Jun/15

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

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

Using Jersey 2.17, running on Grizzly, using the Moxy to marshal to and from JSON. Running a resource with @Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)



 Description   

There seems to be a bug in how the MoxyObjectProvider breaks cycles in the object graph.

I think the bug is related to this code in the createSubgraphs(String, Subgraph, Class<?>, Map<String, ObjectGraph>, Set<String> processed) method (line 123):

  final String processedSubgraph = getProcessedSubgraph(entityClass, fieldName, subEntityClass);

            if (!subgraphs.isEmpty() && !processed.contains(processedSubgraph)) {
                processed.add(processedSubgraph);
                createSubgraphs(path, subgraph, subEntityClass, subgraphs, processed);
            } 

I have a class looking like this:

public class Foo {

	private Bar a;
	private Bar b;
	private Bar c;
}

All classes are with the appropriate getters, setters, and zero args constructor.

Bar looks like this:

public class Bar {

	private Baz k1;
}

Baz looks like this:

public class Baz {

	private Boz boz;
	private String s;
 }

Boz:

public class Boz {
	private int a;
}

In this case the Bar instances are only serialised properly for the first encountered instance, the two other does not serialise properly as the string "Bar_k1_Baz" is now appearing in the processed set, and thus resulting in the other subgraphs getting ignored. This will later result in Moxy not generating the subgraphs. The result is below.

{
   "a" : {
      "k1" : {
         "s" : "string A"
      }
   },
   "b" : {
      "k1" : {
         "s" : "string B"
      }
   },
   "c" : {
      "k1" : {
         "boz" : {
            "a" : 24
         },
         "s" : "string C"
      }
   }
} 


 Comments   
Comment by Iaroslav Savytskyi [ 26/May/15 ]

Can you please provide part of java code where you instantiate and fill Foo with other objects?

Comment by jdn [ 26/May/15 ]
@Path("bug/")
public class BugResource {

	@POST
	@PermitAll
	@Consumes(MediaType.APPLICATION_JSON)
	@Produces(MediaType.APPLICATION_JSON)
	public Foo createOrganization() {

		Foo foo = new Foo();

		Bar b = new Bar();
		Baz bazB = this.createBaz("String B");
		b.setK1(bazB);
		foo.setB(b);

		Bar c = new Bar();
		Baz bazC = this.createBaz("String C");
		c.setK1(bazC);
		foo.setC(c);

		Bar a = new Bar();
		Baz bazA = this.createBaz("String A");
		a.setK1(bazA);
		foo.setA(a);

		return foo;
	}

	private Baz createBaz(String s) {
		Boz boz = new Boz();
		Baz baz = new Baz();
		baz.setBoz(boz);
		baz.setS(s);
		return baz;
	}
}

What is the preferred way to share/format code?

Comment by jdn [ 03/Jun/15 ]

Any comments...





[JERSEY-2867] Apache HTTP client connection manager sharing Created: 19/May/15  Updated: 08/Jun/15  Resolved: 08/Jun/15

Status: Resolved
Project: jersey
Component/s: connectors
Affects Version/s: 2.17
Fix Version/s: 2.18

Type: Improvement Priority: Major
Reporter: Jakub Podlesak Assignee: Jakub Podlesak
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

When using Apache HTTP client, it is currently not possible to share a connection manager among individual client runtime instances.
This limitation is quite annoying especially in the "client as a service" scenario when you try to re-use a single JAX-RS client configuration,
but multiple client runtime instances are being created.

There you might face the following exception quite easily:

javax.ws.rs.ProcessingException: java.lang.IllegalStateException: Connection pool shut down
	at org.apache.http.util.Asserts.check(Asserts.java:34)
	at org.apache.http.pool.AbstractConnPool.lease(AbstractConnPool.java:184)
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.requestConnection(PoolingHttpClientConnectionManager.java:251)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:175)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:71)
	at org.glassfish.jersey.apache.connector.ApacheConnector.apply(ApacheConnector.java:435)





[JERSEY-2866] Cannot catch JSON Marshalling exceptions Created: 18/May/15  Updated: 18/May/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: None
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"])






[JERSEY-2865] BufferOverflowException in SSE Created: 15/May/15  Updated: 24/Jun/15  Resolved: 24/Jun/15

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

Type: Bug Priority: Major
Reporter: panghy Assignee: Michal Gajdos
Resolution: Fixed Votes: 0
Labels: 1221, pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Emitting large data with SSE can cause a BufferOverflowException.

! java.nio.BufferOverflowException: null
! at java.nio.Buffer.nextPutIndex(Buffer.java:513) ~[na:1.7.0_65]
! at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:163) ~[na:1.7.0_65]
! at org.eclipse.jetty.util.BufferUtil.append(BufferUtil.java:377) ~[queryserver.jar:na]! at org.eclipse.jetty.server.HttpOutput.write(HttpOutput.java:231) ~[queryserver.jar:na]
! at org.glassfish.jersey.servlet.internal.ResponseWriter$NonCloseableOutputStreamWrapper.write(ResponseWriter.java:289) ~[queryserver.jar:na]! at org.glassfish.jersey.message.internal.CommittingOutputStream.write(CommittingOutputStream.java:244) ~[queryserver.jar:na]
! at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$UnCloseableOutputStream.write(WriterInterceptorExecutor.java:289) ~[queryserver.jar:na]
! at org.glassfish.jersey.media.sse.OutboundEventWriter$1.write(OutboundEventWriter.java:152) ~[queryserver.jar:na]
! at java.io.OutputStream.write(OutputStream.java:116) ~[na:1.7.0_65]
! at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221) ~[na:1.7.0_65]
! at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291) ~[na:1.7.0_65]
! at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295) ~[na:1.7.0_65]
! at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141) ~[na:1.7.0_65]
! at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229) ~[na:1.7.0_65]
! at org.glassfish.jersey.message.internal.ReaderWriter.writeToAsString(ReaderWriter.java:190) ~[queryserver.jar:na]
! at org.glassfish.jersey.message.internal.AbstractMessageReaderWriterProvider.writeToAsString(AbstractMessageReaderWriterProvider.java:130) ~[queryserver.jar:n
a]
! at org.glassfish.jersey.message.internal.StringMessageProvider.writeTo(StringMessageProvider.java:99) ~[queryserver.jar:na]
! at org.glassfish.jersey.message.internal.StringMessageProvider.writeTo(StringMessageProvider.java:59) ~[queryserver.jar:na]
! at org.glassfish.jersey.media.sse.OutboundEventWriter.writeTo(OutboundEventWriter.java:135) ~[queryserver.jar:na]
! at org.glassfish.jersey.media.sse.OutboundEventWriter.writeTo(OutboundEventWriter.java:65) ~[queryserver.jar:na]
! at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265) ~[queryserver.jar:na]
! at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250) ~[queryserver.jar:na]
! at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162) ~[queryserver.jar:na]
! at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1128) ~[queryserver.jar:na]
! at org.glassfish.jersey.server.ChunkedOutput$1.call(ChunkedOutput.java:219) ~[queryserver.jar:na]
! at org.glassfish.jersey.server.ChunkedOutput$1.call(ChunkedOutput.java:190) ~[queryserver.jar:na]
! at org.glassfish.jersey.internal.Errors.process(Errors.java:315) ~[queryserver.jar:na]
! at org.glassfish.jersey.internal.Errors.process(Errors.java:242) ~[queryserver.jar:na]
! at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:367) ~[queryserver.jar:na]
! at org.glassfish.jersey.server.ChunkedOutput.flushQueue(ChunkedOutput.java:190) ~[queryserver.jar:na]
! at org.glassfish.jersey.server.ChunkedOutput.write(ChunkedOutput.java:180) ~[queryserver.jar:na]


 Comments   
Comment by panghy [ 15/May/15 ]

I am pretty sure there's a synchronization bug in ChunkedOutput.java line 196

    private void flushQueue() throws IOException {
...
            requestScope.runInScope(requestScopeInstance, new Callable<Void>() {
                @Override
                public Void call() throws IOException {
                     ...
                     synchronized (this) {
                        if (flushing) {
                            // if another thread is already flushing the queue, we don't have to do anything
                            return null;
                        }
...

The synchronized should be on "ChunkedOutput.this" instead of "this" since it's just referring to the Callable (hence there is no thread safety contrary to what the comment would suggest).

Comment by panghy [ 15/May/15 ]

The original code was right in the first place:

Fixed issue JERSEY-1256
ChunkedResponse.flushQueue now returns immediately if other thread is already
flushing the queue instead of blocking on synchronized.
Only small pieces of the method are synchronized now.

Change-Id: I7625d9d68f4da9e719333a198332b37261e08b15
commit 898f408108ed9f888c3d30c85222e95d86853c44 1 parent 0606c34
@mmatula mmatula authored on Jul 1, 2012

It was "broken" when it got wrapped in a Callable in this check-in

Fixed: ChunkedOutput not writing data in request scope.
Change-Id: I262d48aad3308133de415c12a44e8b3ab92d20b8
Signed-off-by: Marek Potociar <marek.potociar@oracle.com>
commit 1e428d7b82baefea401ed3cd92f3d1a727abd2c3 1 parent a71fe9e
@mpotociar mpotociar authored on Sep 23, 2013
Comment by panghy [ 15/May/15 ]

Pull request created: https://github.com/jersey/jersey/pull/165

Comment by panghy [ 15/May/15 ]

The title and description of this bug should probably be changed to reflect the actual issue and scope (it's not really limited to SSE, all ChunkedOutput that's called by multiple threads is affected by this bug).

Comment by Adam Lindenthal [ 15/May/15 ]

Hi panghy,

thanks for reporting and for the pull request. I'll move the issue to backlog, as we are waiting for review/merge your pull request.

Thanks,
Adam





[JERSEY-2864] HttpAuthenticationFeature should have a callback mechanism to get credentials Created: 14/May/15  Updated: 14/May/15

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

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

all



 Description   

Instead of configuring the credentials directly on the HttpAuthenticationFeature you should be able to provide a callback. That way, in pre-emptive mode, the credentials can be obtained by asking the user for them on-demand. The HttpAuthenticationFeature should then cache them for the given authentication realm.

I currently implement this with my own ClientRequestFilter that adds the authorization header from a cache of credentials, and a reflection-based proxy in my client that intercepts the 401 status, populates the credentials cache via a callback (where I can present a GUI), then retries the call. It works, but it is the sort of thing that should be built-in if you ask me.






[JERSEY-2863] Declarative linking should use uriInfo to fill Links Created: 13/May/15  Updated: 20/May/15  Resolved: 20/May/15

Status: Resolved
Project: jersey
Component/s: extensions
Affects Version/s: 2.17
Fix Version/s: 2.18

Type: Improvement Priority: Major
Reporter: jccounio Assignee: Michal Gajdos
Resolution: Fixed Votes: 0
Labels: pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Right now, all parameters of the resource have to be defined in the Bindings of the @InjectLink annotation. It comes with 2 issues :

  • It assumes all parameters can be retrieved through instance/entity/resource. This may not always be the case
  • It forces to redeclare in Bindings what is already present in uriInfo which is a burden and makes the annotation declaration big and hard to maintain when you have a lot of parameters.

The fix would be to get the pathParameters and queryParameters and add them by default to the list of values. Those values can be overridden if the name is set in one of the Bindings



 Comments   
Comment by jccounio [ 13/May/15 ]

Patch is available here
https://gist.github.com/anonymous/bb457425728291ae7e7c

Comment by Adam Lindenthal [ 15/May/15 ]

Hi,
just to make things easier to find, there is also a pull request you've created:
https://github.com/jersey/jersey/pull/163

I will move the issue to backlog now, as we are waiting for your OCA to get approved, the patch to get reviewed and finally merged.

Thank you,
Adam





[JERSEY-2862] File upload is broken in Jersey 2.17 Created: 13/May/15  Updated: 15/May/15

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

Type: Bug 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:

Windows 7 64-bit
Java 8u40


Tags: regression, upload

 Description   

This is the commit that did it:

https://github.com/jersey/jersey/commit/d90369ca0e872df280979f04669894871f5c8189#diff-71e5b60df38390f13c313b6cc9847efd

The problem is that the temp file can't be renamed because an empty file with the destination name is created and left there, blocking the moveTo from succeeding.

https://github.com/jersey/jersey/blob/master/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueFactoryProvider.java#L253

The problem is hidden because the ultimate renameTo call in WeakDataFile simply logs the failure without letting the caller know that the rename failed.

May 12, 2015 11:40:50 AM org.jvnet.mimepull.WeakDataFile renameTo
INFO: File C:\Users\SCOTT~1.PAL\AppData\Local\Temp\MIME9174014175637264696.tmp was not moved to C:\Users\SCOTT~1.PAL\AppData\Local\Temp\rep818068880122345050tmp

The result is that the web service, with a parameter declared as: @FormDataParam("file") File file, is always given a reference to an empty temp file.

Reverting to Jersey 2.16 fixes the issue.



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

Hi, thanks for opening the issue.
I am moving it to backlog, so that we can plan the work on it.

Regards,
Adam





[JERSEY-2861] Glassfish REST API - OPTIONS request is broken after Jersey 2.16 integration Created: 12/May/15  Updated: 01/Jul/15  Resolved: 01/Jul/15

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

Type: Bug Priority: Blocker
Reporter: Arindam Bandyopadhyay Assignee: Unassigned
Resolution: Invalid Votes: 0
Labels: incomplete
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Glassfish trunk


Issue Links:
Blocks
blocks GLASSFISH-21314 Cannot create JDBC Connection Pool In Progress
blocks GLASSFISH-21353 Cannot Create JDBC Resource or Connec... In Progress
Dependency
blocks GLASSFISH-21353 Cannot Create JDBC Resource or Connec... In Progress

 Description   

After Jersey 2.16 integration (in Glassfish revision r63775,) no response is coming for OPTIONS request.For example,

curl -X OPTIONS -H "Accept: application/json" http://localhost:4848/management/domain/resources/jdbc-connection-pool

The above rest request is not producing any response.The same behaviour is observed with the Accept header application/xml and text/html.
However in the Jersey 2.15 integration (upto Glassfish revision r63774) the above request successfully produces response for application/json application/xml and text/html.
If we don't include any Accept header we are getting the following response.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application xmlns="http://wadl.dev.java.net/2009/02">
<doc xmlns:jersey="http://jersey.java.net/" jersey:generatedBy="Jersey: 2.17 2015-03-11 13:44:09"/>
<grammars/>
<resources base="http://localhost:4848/management/">
<resource path="domain/resources/jdbc-connection-pool">
<method id="createResource" name="POST">
<request>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
<representation mediaType="application/x-www-form-urlencoded"/>
</request>
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
</response>
</method>
<method id="post" name="POST">
<request>
<representation mediaType="multipart/form-data"/>
</request>
<response>
<representation mediaType="/"/>
</response>
</method>
<method id="options" name="OPTIONS">
<response>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="text/html;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
</response>
</method>
<method id="get" name="GET">
<request>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="expandLevel" style="query" type="xs:int" default="1"/>
</request>
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
</response>
</method>
<resource path="

{Name}/">
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="Name" style="template" type="xs:string"/>
<method id="optionsLegacyFormat" name="OPTIONS">
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
<representation mediaType="application/x-www-form-urlencoded;qs=0.5"/>
</response>
</method>
<method id="getEntityLegacyFormat" name="GET">
<request>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="expandLevel" style="query" type="xs:int" default="1"/>
</request>
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
<representation mediaType="application/x-www-form-urlencoded;qs=0.5"/>
</response>
</method>
<method id="createOrUpdateEntityLegacyFormat" name="POST">
<request>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
<representation mediaType="application/x-www-form-urlencoded"/>
</request>
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
<representation mediaType="application/x-www-form-urlencoded;qs=0.5"/>
</response>
</method>
<method id="createOrUpdateEntity" name="POST">
<request>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
<representation mediaType="application/x-www-form-urlencoded"/>
</request>
<response>
<representation mediaType="application/vnd.oracle.glassfish+json;qs=0.5"/>
</response>
</method>
<method id="postLegacyFormat" name="POST">
<request>
<representation mediaType="multipart/form-data"/>
</request>
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
<representation mediaType="application/x-www-form-urlencoded;qs=0.5"/>
</response>
</method>
<method id="post" name="POST">
<request>
<representation mediaType="multipart/form-data"/>
</request>
<response>
<representation mediaType="application/vnd.oracle.glassfish+json;qs=0.5"/>
</response>
</method>
<method id="getEntity" name="GET">
<request>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="expandLevel" style="query" type="xs:int" default="1"/>
</request>
<response>
<representation mediaType="application/vnd.oracle.glassfish+json;qs=0.5"/>
</response>
</method>
<method id="options" name="OPTIONS">
<response>
<representation mediaType="application/vnd.oracle.glassfish+json;qs=0.5"/>
</response>
</method>
<method id="delete" name="DELETE">
<request>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
<representation mediaType="application/x-www-form-urlencoded"/>
</request>
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
<representation mediaType="application/x-www-form-urlencoded;qs=0.5"/>
</response>
</method>
<resource path="property/">
<method id="createProperties" name="POST">
<request>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
<representation mediaType="application/x-www-form-urlencoded"/>
</request>
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
</response>
</method>
<method id="replaceProperties" name="PUT">
<request>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
<representation mediaType="application/x-www-form-urlencoded"/>
</request>
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
</response>
</method>
<method id="get" name="GET">
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
</response>
</method>
<method id="delete" name="DELETE">
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
</response>
</method>
<resource path="{Name}

/">
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="Name" style="template" type="xs:string"/>
<method id="optionsLegacyFormat" name="OPTIONS">
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
<representation mediaType="application/x-www-form-urlencoded;qs=0.5"/>
</response>
</method>
<method id="getEntityLegacyFormat" name="GET">
<request>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="expandLevel" style="query" type="xs:int" default="1"/>
</request>
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
<representation mediaType="application/x-www-form-urlencoded;qs=0.5"/>
</response>
</method>
<method id="createOrUpdateEntityLegacyFormat" name="POST">
<request>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
<representation mediaType="application/x-www-form-urlencoded"/>
</request>
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
<representation mediaType="application/x-www-form-urlencoded;qs=0.5"/>
</response>
</method>
<method id="createOrUpdateEntity" name="POST">
<request>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
<representation mediaType="application/x-www-form-urlencoded"/>
</request>
<response>
<representation mediaType="application/vnd.oracle.glassfish+json;qs=0.5"/>
</response>
</method>
<method id="postLegacyFormat" name="POST">
<request>
<representation mediaType="multipart/form-data"/>
</request>
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
<representation mediaType="application/x-www-form-urlencoded;qs=0.5"/>
</response>
</method>
<method id="post" name="POST">
<request>
<representation mediaType="multipart/form-data"/>
</request>
<response>
<representation mediaType="application/vnd.oracle.glassfish+json;qs=0.5"/>
</response>
</method>
<method id="getEntity" name="GET">
<request>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="expandLevel" style="query" type="xs:int" default="1"/>
</request>
<response>
<representation mediaType="application/vnd.oracle.glassfish+json;qs=0.5"/>
</response>
</method>
<method id="options" name="OPTIONS">
<response>
<representation mediaType="application/vnd.oracle.glassfish+json;qs=0.5"/>
</response>
</method>
<method id="delete" name="DELETE">
<request>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
<representation mediaType="application/x-www-form-urlencoded"/>
</request>
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
<representation mediaType="application/x-www-form-urlencoded;qs=0.5"/>
</response>
</method>
</resource>
</resource>
<resource path="ping/">
<method id="processGet" name="GET">
<response>
<representation mediaType="application/vnd.oracle.glassfish+json;qs=0.5"/>
</response>
</method>
<method id="processGetLegacyFormat" name="GET">
<response>
<representation mediaType="text/html"/>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="application/xml;qs=0.5"/>
<representation mediaType="application/x-www-form-urlencoded;qs=0.5"/>
</response>
</method>
<method id="processSseGet" name="GET">
<response>
<representation mediaType="text/event-stream;qs=0.5"/>
</response>
</method>
<method id="optionsLegacyFormat" name="OPTIONS">
<response>
<representation mediaType="application/json;qs=0.5"/>
<representation mediaType="text/html"/>
<representation mediaType="application/xml;qs=0.5"/>
</response>
</method>
<method id="options" name="OPTIONS">
<response>
<representation mediaType="application/vnd.oracle.glassfish+json;qs=0.5"/>
</response>
</method>
</resource>
</resource>
</resource>
</resources>
</application>



 Comments   
Comment by Arindam Bandyopadhyay [ 12/May/15 ]

This issue completely breaks GF admin gui resource section when we try to create new resource. In GF admin gui resource section we depend on OPTIONS request to populate the default value for the resource . We are getting NPE when we try to create new resource as OPTIONS request result in blank response.

Comment by Arindam Bandyopadhyay [ 13/May/15 ]

In 4.1 (before the feature was broken we got the following response)

Request :
curl -X OPTIONS -H "Accept: application/json" http://localhost:4848/management/domain/resources/jdbc-connection-pool

Response :

{"message":"","command":"jdbc-connection-pool","exit_code":"SUCCESS","extraProperties":{"commands":[],"methods":[

{"name":"GET"}

,{},{"name":"POST","messageParameters":{"allowNonComponentCallers":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"associateWithThread":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"connectionCreationRetryAttempts":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"0"}

,"connectionCreationRetryIntervalInSeconds":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"10"}

,"connectionLeakReclaim":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"connectionLeakTimeoutInSeconds":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"0"}

,"connectionValidationMethod":

{"acceptableValues":"auto-commit,meta-data,table,custom-validation","optional":"true","type":"string","defaultValue":"table"}

,"datasourceClassname":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"description":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"driverClassname":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"failAllConnections":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"idleTimeoutInSeconds":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"300"}

,"initSql":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"isConnectionValidationRequired":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"isIsolationLevelGuaranteed":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"true"}

,"lazyConnectionAssociation":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"lazyConnectionEnlistment":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"matchConnections":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"maxConnectionUsageCount":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"0"}

,"maxPoolSize":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"32"}

,"maxWaitTimeInMillis":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"60000"}

,"name":

{"acceptableValues":"","optional":"false","type":"string","defaultValue":""}

,"nonTransactionalConnections":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"ping":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"poolResizeQuantity":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"2"}

,"pooling":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"true"}

,"property":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"resType":

{"acceptableValues":"javax.sql.DataSource,javax.sql.XADataSource,javax.sql.ConnectionPoolDataSource,java.sql.Driver","optional":"true","type":"string","defaultValue":""}

,"sqlTraceListeners":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"statementCacheSize":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"0"}

,"statementLeakReclaim":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"statementLeakTimeoutInSeconds":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"0"}

,"statementTimeoutInSeconds":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"-1"}

,"steadyPoolSize":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"8"}

,"target":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"transactionIsolationLevel":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"validateAtmostOncePeriodInSeconds":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"0"}

,"validationClassname":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"validationTableName":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"wrapJdbcObjects":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"true"}

}}],"childResources":

{"DerbyPool":"http:\/\/localhost:4848\/management\/domain\/resources\/jdbc-connection-pool\/DerbyPool","__TimerPool":"http:\/\/localhost:4848\/management\/domain\/resources\/jdbc-connection-pool\/__TimerPool"}

}}

Request :
curl -X OPTIONS -H "Accept: application/xml" http://localhost:4848/management/domain/resources/jdbc-connection-pool

Response:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><map><entry key="extraProperties"><map><entry key="methods"><list><map><entry key="name" value="GET"/></map><map/><map><entry key="name" value="POST"/><entry key="messageParameters"><map><entry key="allowNonComponentCallers"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="false"/><entry key="type" value="boolean"/></map></entry><entry key="connectionValidationMethod"><map><entry key="acceptableValues" value="auto-commit,meta-data,table,custom-validation"/><entry key="optional" value="true"/><entry key="defaultValue" value="table"/><entry key="type" value="string"/></map></entry><entry key="statementTimeoutInSeconds"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="-1"/><entry key="type" value="string"/></map></entry><entry key="validationClassname"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value=""/><entry key="type" value="string"/></map></entry><entry key="connectionLeakReclaim"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="false"/><entry key="type" value="boolean"/></map></entry><entry key="maxConnectionUsageCount"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="0"/><entry key="type" value="string"/></map></entry><entry key="associateWithThread"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="false"/><entry key="type" value="boolean"/></map></entry><entry key="matchConnections"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="false"/><entry key="type" value="boolean"/></map></entry><entry key="description"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value=""/><entry key="type" value="string"/></map></entry><entry key="datasourceClassname"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value=""/><entry key="type" value="string"/></map></entry><entry key="name"><map><entry key="acceptableValues" value=""/><entry key="optional" value="false"/><entry key="defaultValue" value=""/><entry key="type" value="string"/></map></entry><entry key="failAllConnections"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="false"/><entry key="type" value="boolean"/></map></entry><entry key="isConnectionValidationRequired"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="false"/><entry key="type" value="boolean"/></map></entry><entry key="maxWaitTimeInMillis"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="60000"/><entry key="type" value="string"/></map></entry><entry key="poolResizeQuantity"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="2"/><entry key="type" value="string"/></map></entry><entry key="ping"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="false"/><entry key="type" value="boolean"/></map></entry><entry key="isIsolationLevelGuaranteed"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="true"/><entry key="type" value="boolean"/></map></entry><entry key="lazyConnectionAssociation"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="false"/><entry key="type" value="boolean"/></map></entry><entry key="connectionCreationRetryIntervalInSeconds"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="10"/><entry key="type" value="string"/></map></entry><entry key="connectionCreationRetryAttempts"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="0"/><entry key="type" value="string"/></map></entry><entry key="wrapJdbcObjects"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="true"/><entry key="type" value="boolean"/></map></entry><entry key="lazyConnectionEnlistment"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="false"/><entry key="type" value="boolean"/></map></entry><entry key="property"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value=""/><entry key="type" value="string"/></map></entry><entry key="statementLeakReclaim"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="false"/><entry key="type" value="boolean"/></map></entry><entry key="statementCacheSize"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="0"/><entry key="type" value="string"/></map></entry><entry key="idleTimeoutInSeconds"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="300"/><entry key="type" value="string"/></map></entry><entry key="transactionIsolationLevel"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value=""/><entry key="type" value="string"/></map></entry><entry key="driverClassname"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value=""/><entry key="type" value="string"/></map></entry><entry key="steadyPoolSize"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="8"/><entry key="type" value="string"/></map></entry><entry key="statementLeakTimeoutInSeconds"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="0"/><entry key="type" value="string"/></map></entry><entry key="nonTransactionalConnections"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="false"/><entry key="type" value="boolean"/></map></entry><entry key="connectionLeakTimeoutInSeconds"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="0"/><entry key="type" value="string"/></map></entry><entry key="pooling"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="true"/><entry key="type" value="boolean"/></map></entry><entry key="maxPoolSize"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="32"/><entry key="type" value="string"/></map></entry><entry key="initSql"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value=""/><entry key="type" value="string"/></map></entry><entry key="target"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value=""/><entry key="type" value="string"/></map></entry><entry key="sqlTraceListeners"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value=""/><entry key="type" value="string"/></map></entry><entry key="validateAtmostOncePeriodInSeconds"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value="0"/><entry key="type" value="string"/></map></entry><entry key="validationTableName"><map><entry key="acceptableValues" value=""/><entry key="optional" value="true"/><entry key="defaultValue" value=""/><entry key="type" value="string"/></map></entry><entry key="resType"><map><entry key="acceptableValues" value="javax.sql.DataSource,javax.sql.XADataSource,javax.sql.ConnectionPoolDataSource,java.sql.Driver"/><entry key="optional" value="true"/><entry key="defaultValue" value=""/><entry key="type" value="string"/></map></entry></map></entry></map></list></entry><entry key="commands"><list/></entry><entry key="childResources"><map><entry key="_TimerPool" value="http://localhost:4848/management/domain/resources/jdbc-connection-pool/_TimerPool"/><entry key="DerbyPool" value="http://localhost:4848/management/domain/resources/jdbc-connection-pool/DerbyPool"/></map></entry></map></entry><entry key="message" value=""/><entry key="exit_code" value="SUCCESS"/><entry key="command" value="jdbc-connection-pool"/></map>

Request :
curl -X OPTIONS -H "Accept: text/html" http://localhost:4848/management/domain/resources/jdbc-connection-pool

Response:
<html><head><title>GlassFish Server Open Source Edition 4.1 REST Interface</title> <link rel="stylesheet" type="text/css" href="http://localhost:4848/management/static/std.css" /> <script type="text/javascript" src="http://localhost:4848/management/static/ajax.javascript"></script></head><body><h1 class="mainheader">GlassFish Server Open Source Edition 4.1 REST Interface</h1><hr/><h2>Create jdbc-connection-pool</h2><div><form action="http://localhost:4848/management/domain/resources/jdbc-connection-pool" method="post"><dl><dt><label for="allowNonComponentCallers">allowNonComponentCallers: </label></dt><dd><select name=allowNonComponentCallers><option>true<br><option selected>false<br></select></dd><dt><label for="associateWithThread">associateWithThread: </label></dt><dd><select name=associateWithThread><option>true<br><option selected>false<br></select></dd><dt><label for="connectionCreationRetryAttempts">connectionCreationRetryAttempts: </label></dt><dd><input name="connectionCreationRetryAttempts" value ="0" type="text"></dd><dt><label for="connectionCreationRetryIntervalInSeconds">connectionCreationRetryIntervalInSeconds: </label></dt><dd><input name="connectionCreationRetryIntervalInSeconds" value ="10" type="text"></dd><dt><label for="connectionLeakReclaim">connectionLeakReclaim: </label></dt><dd><select name=connectionLeakReclaim><option>true<br><option selected>false<br></select></dd><dt><label for="connectionLeakTimeoutInSeconds">connectionLeakTimeoutInSeconds: </label></dt><dd><input name="connectionLeakTimeoutInSeconds" value ="0" type="text"></dd><dt><label for="connectionValidationMethod">connectionValidationMethod: </label></dt><dd><select name=connectionValidationMethod><option>auto-commit<br><option>meta-data<br><option selected>table<br><option>custom-validation<br></select></dd><dt><label for="datasourceClassname">datasourceClassname: </label></dt><dd><input name="datasourceClassname" type="text"></dd><dt><label for="description">description: </label></dt><dd><input name="description" type="text"></dd><dt><label for="driverClassname">driverClassname: </label></dt><dd><input name="driverClassname" type="text"></dd><dt><label for="failAllConnections">failAllConnections: </label></dt><dd><select name=failAllConnections><option>true<br><option selected>false<br></select></dd><dt><label for="idleTimeoutInSeconds">idleTimeoutInSeconds: </label></dt><dd><input name="idleTimeoutInSeconds" value ="300" type="text"></dd><dt><label for="initSql">initSql: </label></dt><dd><input name="initSql" type="text"></dd><dt><label for="isConnectionValidationRequired">isConnectionValidationRequired: </label></dt><dd><select name=isConnectionValidationRequired><option>true<br><option selected>false<br></select></dd><dt><label for="isIsolationLevelGuaranteed">isIsolationLevelGuaranteed: </label></dt><dd><select name=isIsolationLevelGuaranteed><option selected>true<br><option>false<br></select></dd><dt><label for="lazyConnectionAssociation">lazyConnectionAssociation: </label></dt><dd><select name=lazyConnectionAssociation><option>true<br><option selected>false<br></select></dd><dt><label for="lazyConnectionEnlistment">lazyConnectionEnlistment: </label></dt><dd><select name=lazyConnectionEnlistment><option>true<br><option selected>false<br></select></dd><dt><label for="matchConnections">matchConnections: </label></dt><dd><select name=matchConnections><option>true<br><option selected>false<br></select></dd><dt><label for="maxConnectionUsageCount">maxConnectionUsageCount: </label></dt><dd><input name="maxConnectionUsageCount" value ="0" type="text"></dd><dt><label for="maxPoolSize">maxPoolSize: </label></dt><dd><input name="maxPoolSize" value ="32" type="text"></dd><dt><label for="maxWaitTimeInMillis">maxWaitTimeInMillis: </label></dt><dd><input name="maxWaitTimeInMillis" value ="60000" type="text"></dd><dt><label for="name">name<sup>*</sup>: </label></dt><dd><input name="name" type="text"></dd><dt><label for="nonTransactionalConnections">nonTransactionalConnections: </label></dt><dd><select name=nonTransactionalConnections><option>true<br><option selected>false<br></select></dd><dt><label for="ping">ping: </label></dt><dd><select name=ping><option>true<br><option selected>false<br></select></dd><dt><label for="poolResizeQuantity">poolResizeQuantity: </label></dt><dd><input name="poolResizeQuantity" value ="2" type="text"></dd><dt><label for="pooling">pooling: </label></dt><dd><select name=pooling><option selected>true<br><option>false<br></select></dd><dt><label for="property">property: </label></dt><dd><input name="property" type="text"></dd><dt><label for="resType">resType: </label></dt><dd><select name=resType><option>javax.sql.DataSource<br><option>javax.sql.XADataSource<br><option>javax.sql.ConnectionPoolDataSource<br><option>java.sql.Driver<br></select></dd><dt><label for="sqlTraceListeners">sqlTraceListeners: </label></dt><dd><input name="sqlTraceListeners" type="text"></dd><dt><label for="statementCacheSize">statementCacheSize: </label></dt><dd><input name="statementCacheSize" value ="0" type="text"></dd><dt><label for="statementLeakReclaim">statementLeakReclaim: </label></dt><dd><select name=statementLeakReclaim><option>true<br><option selected>false<br></select></dd><dt><label for="statementLeakTimeoutInSeconds">statementLeakTimeoutInSeconds: </label></dt><dd><input name="statementLeakTimeoutInSeconds" value ="0" type="text"></dd><dt><label for="statementTimeoutInSeconds">statementTimeoutInSeconds: </label></dt><dd><input name="statementTimeoutInSeconds" value ="-1" type="text"></dd><dt><label for="steadyPoolSize">steadyPoolSize: </label></dt><dd><input name="steadyPoolSize" value ="8" type="text"></dd><dt><label for="target">target: </label></dt><dd><input name="target" type="text"></dd><dt><label for="transactionIsolationLevel">transactionIsolationLevel: </label></dt><dd><input name="transactionIsolationLevel" type="text"></dd><dt><label for="validateAtmostOncePeriodInSeconds">validateAtmostOncePeriodInSeconds: </label></dt><dd><input name="validateAtmostOncePeriodInSeconds" value ="0" type="text"></dd><dt><label for="validationClassname">validationClassname: </label></dt><dd><input name="validationClassname" type="text"></dd><dt><label for="validationTableName">validationTableName: </label></dt><dd><input name="validationTableName" type="text"></dd><dt><label for="wrapJdbcObjects">wrapJdbcObjects: </label></dt><dd><select name=wrapJdbcObjects><option selected>true<br><option>false<br></select></dd><dd><input name="_remove_empty_entries" value="true" type="hidden"></dd><dt class="button"></dt><dd class="button"><input value="Create" type="submit"></dd></dl></form></div><hr class="separator"/><h2>Child Resources</h2><div><a href="http://localhost:4848/management/domain/resources/jdbc-connection-pool/DerbyPool">DerbyPool</a><br><a href="http://localhost:4848/management/domain/resources/jdbc-connection-pool/TimerPool">_TimerPool</a><br></div><br/><hr class="separator"/></div></body></html>

Request :
curl -X OPTIONS http://localhost:4848/management/domain/resources/jdbc-connection-pool

Response:
{"message":"","command":"jdbc-connection-pool","exit_code":"SUCCESS","extraProperties":{"commands":[],"methods":[

{"name":"GET"}

,{},{"name":"POST","messageParameters":{"allowNonComponentCallers":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"associateWithThread":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"connectionCreationRetryAttempts":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"0"}

,"connectionCreationRetryIntervalInSeconds":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"10"}

,"connectionLeakReclaim":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"connectionLeakTimeoutInSeconds":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"0"}

,"connectionValidationMethod":

{"acceptableValues":"auto-commit,meta-data,table,custom-validation","optional":"true","type":"string","defaultValue":"table"}

,"datasourceClassname":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"description":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"driverClassname":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"failAllConnections":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"idleTimeoutInSeconds":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"300"}

,"initSql":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"isConnectionValidationRequired":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"isIsolationLevelGuaranteed":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"true"}

,"lazyConnectionAssociation":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"lazyConnectionEnlistment":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"matchConnections":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"maxConnectionUsageCount":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"0"}

,"maxPoolSize":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"32"}

,"maxWaitTimeInMillis":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"60000"}

,"name":

{"acceptableValues":"","optional":"false","type":"string","defaultValue":""}

,"nonTransactionalConnections":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"ping":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"poolResizeQuantity":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"2"}

,"pooling":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"true"}

,"property":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"resType":

{"acceptableValues":"javax.sql.DataSource,javax.sql.XADataSource,javax.sql.ConnectionPoolDataSource,java.sql.Driver","optional":"true","type":"string","defaultValue":""}

,"sqlTraceListeners":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"statementCacheSize":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"0"}

,"statementLeakReclaim":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"false"}

,"statementLeakTimeoutInSeconds":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"0"}

,"statementTimeoutInSeconds":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"-1"}

,"steadyPoolSize":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"8"}

,"target":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"transactionIsolationLevel":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"validateAtmostOncePeriodInSeconds":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":"0"}

,"validationClassname":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"validationTableName":

{"acceptableValues":"","optional":"true","type":"string","defaultValue":""}

,"wrapJdbcObjects":

{"acceptableValues":"","optional":"true","type":"boolean","defaultValue":"true"}

}}],"childResources":

{"DerbyPool":"http:\/\/localhost:4848\/management\/domain\/resources\/jdbc-connection-pool\/DerbyPool","__TimerPool":"http:\/\/localhost:4848\/management\/domain\/resources\/jdbc-connection-pool\/__TimerPool"}

}}

Comment by Jakub Podlesak [ 23/Jun/15 ]

The only missing piece is the JSON body, here is what i am getting from the latest GF trunk version:

curl -i -X OPTIONS -H "Accept: application/json" http://localhost:4848/management/domain/resources/jdbc-connection-pool

HTTP/1.1 200 OK
Server: GlassFish Server Open Source Edition  4.1
X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition  4.1  Java/Oracle Corporation/1.8)
Allow: HEAD,POST,GET,OPTIONS
Content-Type: application/json;charset=UTF-8
Date: Tue, 23 Jun 2015 07:49:51 GMT
Content-Length: 0
Comment by Jakub Podlesak [ 23/Jun/15 ]

This is IMHO a GF bug. We need to separate out a raw Jersey based reproducer to see if it is a regression in Jersey or not, but the above demonstrated behaviour
is correct with regard to 200 status code and the ALLOW header content.

Comment by Michal Gajdos [ 23/Jun/15 ]

As Jakub mentioned - returning an entity for OPTIONS call seems to be a feature of GF management app (we didn't return an entity in this case even in 2.15). Please, evaluate this in GF first and if you find a bug in Jersey, provide a reproducible test case.

Comment by Arindam Bandyopadhyay [ 23/Jun/15 ]

After Jersey 2.16 integration (in Glassfish revision r63775, committed by Libor Kramolis) no response body is coming for OPTIONS request.For example,

curl -X OPTIONS -H "Accept: application/json" http://localhost:4848/management/domain/resources/jdbc-connection-pool

The above rest request is not producing any response body.
However in the Jersey 2.15 integration (upto Glassfish revision r63774) the above request successfully produces json response body.

Possible Fix :
I compare the GF source between r63775 and r63774 and found out that the following change breaks the functionality .

— nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/resources/TemplateListOfResource.java (revision 63774)
+++ nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/resources/TemplateListOfResource.java (revision 63775)

@OPTIONS

  • @Produces( {MediaType.APPLICATION_JSON, MediaType.TEXT_HTML, MediaType.APPLICATION_XML})
    + @Produces({MediaType.APPLICATION_JSON+";qs=0.5", MediaType.TEXT_HTML+";qs=0.5", MediaType.APPLICATION_XML+";qs=0.5"})
    public Response options() { return Response.ok().entity(buildActionReportResult()).build(); }

    If we revert back the above code change we are successfully getting the correct response for html verb OPTIONS.
    So the possible fix would be

    — nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/resources/TemplateListOfResource.java (revision 63867)
    +++ nucleus/admin/rest/rest-service/src/main/java/org/glassfish/admin/rest/resources/TemplateListOfResource.java (working copy)
    @@ -165,7 +165,7 @@
    }

    @OPTIONS
    - @Produces({MediaType.APPLICATION_JSON+";qs=0.5", MediaType.TEXT_HTML+";qs=0.5", MediaType.APPLICATION_XML+";qs=0.5"})
    + @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_HTML, MediaType.APPLICATION_XML}

    )
    public Response options()

    { return Response.ok().entity(buildActionReportResult()).build(); }

Please let us know whether the above code change will be acceptable ?

Comment by Jakub Podlesak [ 01/Jul/15 ]

Hi Arindam,

your suggested fix is perfectly acceptable. Please feel free to submit the change.
I am going to close this issue as invalid, as there is no issue in Jersey but in the GF admin code.

Thanks,

~Jakub

Comment by Jakub Podlesak [ 01/Jul/15 ]

Please see the latest comments. The issue is in fact in the GF admin interface source code. Fix suggested (and verified) by Arindam fixes it completely. No changes on Jersey side are required.





[JERSEY-2860] When setting a new baseUri in a prematching filter, Reponse.created() still uses old baseUri Created: 12/May/15  Updated: 18/May/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





[JERSEY-2859] NullPointerException when SecurityEntityFilteringFeature enabled Created: 12/May/15  Updated: 12/May/15

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

Type: Bug Priority: Major
Reporter: raphael_c Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: 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

<pre><code>
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; }

}
</code></pre>

How can I tell Jersey to execute this feature only if I return a 200






[JERSEY-2858] Adding support for queryParam check in PostReplaceFilter in jersey-server Created: 10/May/15  Updated: 03/Jul/15

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

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.





[JERSEY-2857] jersey-spring3 does not inject list of beans with interface Created: 08/May/15  Updated: 15/May/15  Resolved: 15/May/15

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

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

Windows 7 64bit
Java 1.7.0_79 64bit
Tomcat 8.0.21_64bit
Spring 4.0.1.RELEASE



 Description   

Jersey does not inject a list of beans with interface correctly.

RootController.java
@Component
@Path("/")
public class RootController {
    @Autowired
    List<Helper> helpers;

    @Context
    ApplicationContext applicationContext;

    @GET
    public String show() {
        System.out.println("helpers.class: " + helpers.getClass().getName());
        System.out.println("helpers.size: " + helpers.size());
        for (Helper helper : helpers) {
            System.out.println("helper.foo: " + helper.foo());
        }
        for (String name : applicationContext.getBeanDefinitionNames()) {
            System.out.println("bean: " + name);
        }
        return "RootController.show";
    }
}
Helper.java
public interface Helper {
    public abstract String foo();
}
Helper1.java
@Component
public class Helper1 implements Helper {
    @Override
    public String foo() {
        return "Helper1.foo";
    }
}
Helper2.java
@Component
public class Helper2 implements Helper {
    public String foo() {
        return "Helper2.foo";
    }
}

Output:

helpers.class: org.springframework.context.annotation.ConfigurationClassParser$ImportStack
helpers.size: 0
...
bean: helper1
bean: helper2
...

The beans are in the Spring application context. A single bean can be injected using this method.

The same injection works in a Spring application.

RootController.java
@Controller
public class RootController {
    @Autowired
    List<Helper> helpers;

    @Autowired
    ApplicationContext applicationContext;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    @ResponseBody
    public String show() {
        System.out.println("helpers.class: " + helpers.getClass().getName());
        System.out.println("helpers.size: " + helpers.size());
        for (Helper helper : helpers) {
            System.out.println("helper.foo: " + helper.foo());
        }
        for (String name : applicationContext.getBeanDefinitionNames()) {
            System.out.println("bean: " + name);
        }
        return "RootController.show";
    }
}

Output:

helpers.class: java.util.ArrayList
helpers.size: 2
helper.foo: Helper1.foo
helper.foo: Helper2.foo
...
bean: helper1
bean: helper2
...

The feature of Spring injection is described at the following link.

http://docs.spring.io/spring/docs/4.0.x/spring-framework-reference/html/beans.html#beans-autowired-annotation

It is also possible to provide all beans of a particular type from the ApplicationContext by adding the annotation to a field or method that expects an array of that type:

The same applies for typed collections:



 Comments   
Comment by hawleyal [ 08/May/15 ]

Apologies. The problem seems to be fixed in a newer version of jersey-spring3, version 2.14.

Comment by Adam Lindenthal [ 15/May/15 ]

Hi hewleyal,

thanks for such a detailed issue description anyway, that's how it should look like
So, I guess you are fine with the issue being closed now. Should you experience the problem again with the recent version, feel free to write a comment here and request re-opening.

Regards,
Adam





[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/May/15

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

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());
	}
}




[JERSEY-2855] HttpServletRequest problems in WLS Created: 06/May/15  Updated: 03/Jul/15  Resolved: 03/Jul/15

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

Type: Bug Priority: Major
Reporter: Santiago Pericas-Geertsen Assignee: Jakub Podlesak
Resolution: Fixed Votes: 0
Labels: 1221, cdi, httpservletrequest, weblogic
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: Zip Archive mvc-test.zip    
Tags: 1221, cdi, httpservletrequest, weblogic

 Description   

Injecting an HttpServletRequest via @Context in a CDI application causes problems when using a RequestDispatcher in WLS. The HttpServletRequest instance appears to be proxied and the WLS servlet container attempts to downcast the type resulting in an exception. See attached sample.



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

Hi Santiago,

thanks for reporting this. I will move the issue to backlog, so that we can take a look at it.

Thanks,
Adam

Comment by Jakub Podlesak [ 16/Jun/15 ]

This one is quite tricky. Even when injecting the HttpServletRequest via CDI, i get a dynamic proxy injected, which causes an exception as well.

java.lang.ClassCastException: org.jboss.weld.proxies.HttpServletRequest$1294025793$Proxy$_$$_WeldClientProxy cannot be cast to weblogic.servlet.internal.ServletRequestImpl
	at weblogic.servlet.internal.ServletRequestImpl.getOriginalRequest(ServletRequestImpl.java:1577)
	at weblogic.servlet.internal.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:116)
	at com.oracle.test.HelloResource.hello(HelloResource.java:83)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	Truncated. see log file for complete stacktrace




[JERSEY-2854] NPE during iteration in TimeWindowStatisticsImpl Created: 06/May/15  Updated: 20/May/15

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

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

Jersey 2.17, JRE 1.8.0_31-b13



 Description   

We are using Jersey's statistics capabilities to get application metrics by registering a MonitoringStatisticsListener and regularly saving statistics from the last MonitoringStatistics object received in the listener in a scheduled task.

We thought we had concurrency covered by working with a snapshot acquired by calling snapshot MonitoringStatistics::snapshot before processing the metrics.

However it seems there are concurrency issues with the statictics codebecause we have been encountering spurious NullPointerExceptions from an iteration in TimeWindowStatisticsImpl, hinting at a concurrent modification of the list being iterated (see stacktrace below).

Looking at MonitoringStatisticsImpl::snapshot shows that snapshotting has actually not been implemented, so it seems not to be thread-safe at all to work with a MonitoringStatistics instance.

NPE stacktrace

java.lang.NullPointerException
at java.util.LinkedList$ListItr.next(LinkedList.java:893)
at org.glassfish.jersey.server.internal.monitoring.TimeWindowStatisticsImpl$Builder.build(TimeWindowStatisticsImpl.java:287)
at org.glassfish.jersey.server.internal.monitoring.TimeWindowStatisticsImpl$Builder.build(TimeWindowStatisticsImpl.java:258)
at org.glassfish.jersey.server.internal.monitoring.ExecutionStatisticsImpl$Builder.build(ExecutionStatisticsImpl.java:110)
at org.glassfish.jersey.server.internal.monitoring.ResourceStatisticsImpl$Builder.build(ResourceStatisticsImpl.java:113)
at org.glassfish.jersey.server.internal.monitoring.MonitoringStatisticsImpl$Builder$1.apply(MonitoringStatisticsImpl.java:76)
at org.glassfish.jersey.server.internal.monitoring.MonitoringStatisticsImpl$Builder$1.apply(MonitoringStatisticsImpl.java:73)
at jersey.repackaged.com.google.common.collect.Maps$6.transformEntry(Maps.java:1562)
at jersey.repackaged.com.google.common.collect.Maps$TransformedEntriesMap$1$1$1.getValue(Maps.java:1850)
at java.util.Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry.getValue(Collections.java:1747)

The first call of the stacktrace originates from the last line in this snippet of code:

final MonitoringStatistics statisticsSnapshot = statistics.snapshot();
final Map<String, ResourceStatistics> uriStatistics = statisticsSnapshot.getUriStatistics();
for (Entry<String, ResourceStatistics> uriEntry : uriStatistics.entrySet()) {
    final Optional<TimeWindowStatistics> timeWindowStatistics = statsForDuration(uriEntry.getValue().getRequestExecutionStatistics());
 ....





[JERSEY-2853] OAuth1 client does not include non-POST 'application/x-www-form-urlencoded' form entity-body parameters in OAuth1 signature base string Created: 05/May/15  Updated: 15/May/15

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

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

Tags: oauth, oauth1, oauth1-client

 Description   

Pull request with a fix and detailed comments @: https://github.com/jersey/jersey/pull/160

Gist of the Jersey oauth1-client implementation is usage of very old oauth-core convention which effectively request entity body signatures and their validation for non-POST requests with 'application/x-www-form-urlencoded' request entity bodies (only query parameters included in the signature thing).



 Comments   
Comment by unserializable [ 05/May/15 ]

^^ /convention which effectively request entity body signatures/ ^^
upwards in bug description should have read:
/convention which effectively DISABLES request entity body signatures/

Comment by Adam Lindenthal [ 15/May/15 ]

Hi unserializable,

thanks for reporting and for the pull request. I will move the issue to backlog, as we are waiting for the OCA to be sent and processed and the patch to be reviewed and merged.

Thanks,
Adam





[JERSEY-2852] ApacheConnector: ClientResponse does not close ClosableHttpResponse Created: 03/May/15  Updated: 15/May/15

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

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


 Description   

According to http://hc.apache.org/httpcomponents-client-4.4.x/tutorial/html/fundamentals.html#d5e145 it needs to close ClosableHttpResponse when the entity input stream is not fully consumed by the client but wants to abort the connection.

"There can be situations, however, when only a small portion of the entire response content needs to be retrieved and the performance penalty for consuming the remaining content and making the connection reusable is too high, in which case one can terminate the content stream by closing the response."

This is not possible with the current ApacheConnector implementation as ClientResponse.close() in fact just closes the entity InputStream.

This is especially a problem with chunked responses where the connection is kept alive by the server infinitely. It leads to a hanging/blocking connection and exhausts a used connection pool if any.



 Comments   
Comment by mlinke [ 14/May/15 ]

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

Comment by Adam Lindenthal [ 15/May/15 ]

Hi, thanks for reporting and for the contribution. I'll move the issue to backlog for now, as we are waiting for things to happen on github...

Regards,
Adam





[JERSEY-2851] NPE Injecting HTTPServletRequest in ContainerRequestFilter Created: 30/Apr/15  Updated: 15/May/15  Resolved: 15/May/15

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

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


 Description   

I wrote this up in a StackOverflow, but I think this needs a Jersey Jira. The SO is here:

http://stackoverflow.com/questions/29974887/jersey-containerrequestfilter-does-not-get-context-servletrequest

To recap: I have a filter, and in that filter I am injecting the servlet request with

    @Context
    private HttpServletRequest servletRequest;

    @Override
    public void filter(ContainerRequestContext containerRequestContext) throws IOException {
        logger.info("ip address: " + servletRequest.getRemoteAddr());  // line 29
    }

As specified in

https://java.net/jira/browse/JERSEY-1960

However this creates an NPE:

javax.servlet.ServletException: java.lang.NullPointerException
	at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:397) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:800) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587) [example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221) [example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1125) [example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) [example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) [example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1059) [example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.server.Server.handle(Server.java:497) [example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:313) [example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:248) [example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540) [example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:626) [example-app-1.0.0-SNAPSHOT.jar:na]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:546) [example-app-1.0.0-SNAPSHOT.jar:na]
	at java.lang.Thread.run(Thread.java:745) [na:1.7.0_67]
Caused by: java.lang.NullPointerException: null
	at com.example.filters.ExampleFilter.filter(ExampleFilter.java:29) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:131) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.server.ContainerFilteringStage.apply(ContainerFilteringStage.java:67) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.process.internal.Stages.process(Stages.java:197) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:295) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.internal.Errors.process(Errors.java:315) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.internal.Errors.process(Errors.java:297) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.internal.Errors.process(Errors.java:267) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:316) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:286) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1073) ~[example-app-1.0.0-SNAPSHOT.jar:na]
	at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:377) ~[example-app-1.0.0-SNAPSHOT.jar:na]

This application is a Jetty + Jersey single jar application, created using the shade plugin. The pom looks like this:

    <properties>
        <jersey.version>2.15</jersey.version>
        <jetty.version>9.2.6.v20141205</jetty.version>
    </properties>

    <dependencies>
        
        <!-- Jersey -->
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-jackson</artifactId>
            <version>${jersey.version}</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey</groupId>
            <artifactId>jersey-bom</artifactId>
            <version>${jersey.version}</version>
            <type>pom</type>
            <scope>compile</scope>
        </dependency>
        
        <!-- Jetty -->
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>${jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>${jetty.version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlets</artifactId>
            <version>${jetty.version}</version>
        </dependency>
    </dependencies>

And the jetty starter looks like this:

public class JettyStarter {

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

    public static void main(String[] args) throws Exception {
        
        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        Server jettyServer = new Server(10005);
        jettyServer.setHandler(context);
        ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/*");
        jerseyServlet.setInitOrder(0);

        jerseyServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, ServletConstants.COMPONENT_SCAN_ROOT);
            
        try {
            System.out.println("Starting Jetty");
            jettyServer.start();
            System.out.println("Jetty Started");
            jettyServer.join();
        } catch (Exception e) {
            System.out.println("Could not start server");
            e.printStackTrace();
        } finally {
            jettyServer.destroy();
        }
    }

}

And the filter is added via a standard Provider annotated class:

@Provider
public class ExampleProvider implements DynamicFeature {
    
    @Override
    public void configure(ResourceInfo resourceInfo, FeatureContext featureContext) {
        ExampleFilter exampleFilter = new ExampleFilter();
        featureContext.register(exampleFilter);
    }
    
}

Just guessing about cause, I see warnings about overlapping classes, could that cause this issue, such as:

[WARNING] jsr305-3.0.0.jar, annotations-2.0.1.jar define 34 overlappping classes:
[WARNING]   - javax.annotation.Nonnegative
[WARNING]   - javax.annotation.CheckForSigned
[WARNING]   - javax.annotation.CheckForNull
[WARNING]   - javax.annotation.Tainted
[WARNING]   - javax.annotation.meta.TypeQualifierValidator
[WARNING]   - javax.annotation.meta.TypeQualifier
[WARNING]   - javax.annotation.Syntax
[WARNING]   - javax.annotation.Detainted
[WARNING]   - javax.annotation.Nonnull$Checker
[WARNING]   - javax.annotation.meta.TypeQualifierNickname
[WARNING]   - 24 more...

[WARNING] commons-beanutils-1.8.0.jar, commons-beanutils-core-1.8.0.jar, commons-collections-3.2.1.jar define 10 overlappping classes:
[WARNING]   - org.apache.commons.collections.FastHashMap$EntrySet
[WARNING]   - org.apache.commons.collections.ArrayStack
[WARNING]   - org.apache.commons.collections.FastHashMap$1
[WARNING]   - org.apache.commons.collections.FastHashMap$KeySet
[WARNING]   - org.apache.commons.collections.FastHashMap$CollectionView
[WARNING]   - org.apache.commons.collections.BufferUnderflowException
[WARNING]   - org.apache.commons.collections.Buffer
[WARNING]   - org.apache.commons.collections.FastHashMap$CollectionView$CollectionViewIterator
[WARNING]   - org.apache.commons.collections.FastHashMap$Values
[WARNING]   - org.apache.commons.collections.FastHashMap

[WARNING] commons-beanutils-1.8.0.jar, commons-beanutils-core-1.8.0.jar define 108 overlappping classes:
[WARNING]   - org.apache.commons.beanutils.locale.LocaleBeanUtilsBean
[WARNING]   - org.apache.commons.beanutils.LazyDynaList
[WARNING]   - org.apache.commons.beanutils.locale.converters.DoubleLocaleConverter
[WARNING]   - org.apache.commons.beanutils.locale.converters.DecimalLocaleConverter
[WARNING]   - org.apache.commons.beanutils.converters.ShortConverter
[WARNING]   - org.apache.commons.beanutils.locale.LocaleConvertUtilsBean
[WARNING]   - org.apache.commons.beanutils.BeanUtilsBean2
[WARNING]   - org.apache.commons.beanutils.LazyDynaClass
[WARNING]   - org.apache.commons.beanutils.locale.converters.DateLocaleConverter
[WARNING]   - org.apache.commons.beanutils.DynaProperty
[WARNING]   - 98 more...

Not knowing about how the @Context injection is happening, could this be related to overlapping classes? Is there some other obvious reason this is creating the NPE? Is there any other way I can get the client ip address in the Filter?



 Comments   
Comment by mobiusinversion2 [ 01/May/15 ]

Important Update: I can reproduce this with no overlapping classes. This appears to be only a Jersey / Embedded Jetty issue. Here is a Github with full reproduction of the issue

https://github.com/mobiusinversion/web-application

Comment by mobiusinversion2 [ 04/May/15 ]

Hi, please close this issue, I cannot find the place to.

Please document the correct behavior here

https://jersey.java.net/documentation/latest/filters-and-interceptors.html

It turns out that this needs to be done in the provider.

Comment by Adam Lindenthal [ 15/May/15 ]

Hi, thanks for creating the issue and sorry, that we didn't get to respond earlier.
Glad it resolved in the meantime. Closing now.

Regards,
Adam





[JERSEY-2850] GrizzlyHttpContainer throws exception if query string contains '\' Created: 30/Apr/15  Updated: 20/May/15  Resolved: 20/May/15

Status: Resolved
Project: jersey
Component/s: containers
Affects Version/s: 2.17
Fix Version/s: 2.18

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


 Description   

When using the Grizzly 2 HTTP container with Jersey if the query string of a request contains a '\' the request will fail attempting to construct the request URI.

<html>
    <head>
        <title>Grizzly 2.3.16</title>
        <style>
            <!--div.header {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#003300;font-size:22px;-moz-border-radius-topleft: 10px;border-top-left-radius: 10px;-moz-border-radius-topright: 10px;border-top-right-radius: 10px;padding-left: 5px}div.body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:#FFFFCC;font-size:16px;padding-top:10px;padding-bottom:10px;padding-left:10px}div.footer {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#666633;font-size:14px;-moz-border-radius-bottomleft: 10px;border-bottom-left-radius: 10px;-moz-border-radius-bottomright: 10px;border-bottom-right-radius: 10px;padding-left: 5px}BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;}B {font-family:Tahoma,Arial,sans-serif;color:black;}A {color : black;}HR {color : #999966;}-->
        </style>
    </head>
    <body>
        <div class="header">Internal Server Error</div>
        <div class="body">
            <b>Illegal character in query at index 46: /api/v1/configuration/outboundroutes?pageSize=\</b>
            <pre>     1: java.net.URI.create(URI.java:852)
     2: java.net.URI.resolve(URI.java:1036)
     3: org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.getRequestUri(GrizzlyHttpContainer.java:476)
     4: org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:365)
     5: org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:219)
     6: org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
     7: org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
     8: java.lang.Thread.run(Thread.java:745)
</pre>
            <b>Root Cause: java.net.URISyntaxException: Illegal character in query at index 46: /api/v1/configuration/outboundroutes?pageSize=\</b>
            <pre>     1: java.net.URI$Parser.fail(URI.java:2848)
     2: java.net.URI$Parser.checkChars(URI.java:3021)
     3: java.net.URI$Parser.parseHierarchical(URI.java:3111)
     4: java.net.URI$Parser.parse(URI.java:3063)
     5: java.net.URI.
                <init>(URI.java:588)
     6: java.net.URI.create(URI.java:850)
     7: java.net.URI.resolve(URI.java:1036)
     8: org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.getRequestUri(GrizzlyHttpContainer.java:476)
     9: org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:365)
    10: org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:219)
        ... 3 more
                </pre>Please see the log for more detail.
            </div>
            <div class="footer">Grizzly 2.3.16</div>
        </body>
    </html>


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

Hi, the fix was merged and will be available in the snapshot repository and later on with 2.18.

Thanks for reporting.





[JERSEY-2849] @BeanParam injection behavior changed with 2.17 Created: 30/Apr/15  Updated: 03/Jul/15

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

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

Jersey 2.17, JDK 1.7.0_55-b13 64 bit, Tomcat 7.0.21, Windows 7


Attachments: Zip Archive test.zip    
Issue Links:
Related
is related to JERSEY-2890 CLONE - Tomcat memory leak on undeploy 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?





[JERSEY-2848] Time Window Statistics don't reset correctly after period of inactivity. Created: 23/Apr/15  Updated: 20/May/15

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

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


 Description   

In class org.glassfish.jersey.server.internal.monitoring.TimeWindowStatisticsImpl$Builder

totalCount and totalDuration are not being zero'd out when resetQueue() is called.

Lets say for example we are interested in the 15-second stats.
Then this can be observed by:
1. send 5 requests to some resource
2. immediately check the 15-second time-window stats for that resource. it will say 5
3. wait more than 15-seconds
4. send one more request to the same resource
5. check the 15-second time-window stats for that resource again. it will incorrectly say 6, instead of 1

The stats work correctly if you continuously send in requests, but if there is a gap of time greater than the time-window, then it breaks. What happens is the last count before the gap, becomes the new baseline, and future stats are added to that value, it never goes back to zero. this can happen over and over again, with the stats becoming very large and never resetting to zero.

FIXED CODE:

private void resetQueue(final long requestTime) {
this.unitQueue.clear();
lastUnitEnd = requestTime + unit;
resetLastUnit();

// RayB: suggested BUGFIX next 2-lines
totalCount = 0;
totalDuration = 0;

// fill with empty unit to keep result consistent
for (int i = 0; i < unitsPerInterval; i++)

{ unitQueue.add(Unit.EMPTY_UNIT); }

}






[JERSEY-2847] AcceptableMediaType overrides toString incorrectly. Created: 22/Apr/15  Updated: 28/Apr/15

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

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


 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)




[JERSEY-2846] When throwing an Exception in a Multipart File upload resource, the tmp file is not deleted Created: 22/Apr/15  Updated: 24/Jun/15  Resolved: 24/Jun/15

Status: Resolved
Project: jersey
Component/s: extensions
Affects Version/s: 2.17
Fix Version/s: 2.19

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


 Description   

Hi,

Our Jersey project contains several endpoints which consume MULTIPART_FORM_DATA. When throwing exceptions like a ForbiddenException, the TMP file is not removed and I can see the following line in the console output:

Apr 22, 2015 9:10:13 AM org.jvnet.mimepull.WeakDataFile close
INFO: File /var/folders/q5/shl3jm197bdbqbdh29p77vnc0000gn/T/MIME315571222858718349.tmp was not deleted

Code:

 @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public PictureDto upload(
            @FormDataParam("file") final File file,
            @FormDataParam("info") final PictureDto horsePictureDto) {
//
 throw new ForbiddenException();
//
}


 Comments   
Comment by Pepster [ 22/Apr/15 ]

Hmmm, please fix the markup of my issue description as I can't :/





[JERSEY-2845] @POST methods require @Consumes("application/x-www-form-urlencoded") now Created: 22/Apr/15  Updated: 22/Apr/15

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

Type: Bug Priority: Major
Reporter: Jonas Thedering Assignee: Unassigned
Resolution: Unresolved 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.






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

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

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


 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()));
     }
   }




[JERSEY-2843] InboundMessageContext.hasEntity() fails to catch IllegalStateException even though it tries to. Created: 17/Apr/15  Updated: 05/Jun/15  Resolved: 05/Jun/15

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

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


 Description   

InboundMessageContext.hasEntity() fails to catch IllegalStateException even though it tries to.

Example:

if (response.hasEntity())

{ Object object = response.readEntity(....) .... do stuff }

If the response stream has been closed then the response.hasEntity() will throw an exception due to an extra entityContent.ensureNotClosed() check inside hasEntity(), skipping the try catch that follows, and never return false. Under such conditions there is no safe way to check whether an entity exists.

The fix and updated unit test is included in:
https://github.com/jersey/jersey/pull/138



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

Pull request was merged, thanks for contributing!





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

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

Type: Improvement Priority: Major
Reporter: sebadiaz Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: incomplete, pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

all



 Description   

need to return the response in sending the actual response.

java.lang.IllegalArgumentException: setContentLength(0) when already written 159
at org.eclipse.jetty.server.Response.setContentLength(Response.java:990)
at org.glassfish.jersey.servlet.internal.ResponseWriter.writeResponseStatusAndHeaders(ResponseWriter.java:142)
at org.glassfish.jersey.server.ServerRuntime$Responder$1.getOutputStream(ServerRuntime.java:611)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:200)
at org.glassfish.jersey.message.internal.CommittingOutputStream.flushBuffer(CommittingOutputStream.java:305)
at org.glassfish.jersey.message.internal.CommittingOutputStream.commit(CommittingOutputStream.java:261)
at org.glassfish.jersey.message.internal.CommittingOutputStream.close(CommittingOutputStream.java:276)
at org.glassfish.jersey.message.internal.OutboundMessageContext.close(OutboundMessageContext.java:834)
at org.glassfish.jersey.server.ContainerResponse.close(ContainerResponse.java:411)
at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:691)



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

Hi sebediaz,

could you please provide something more than an exception? A reproducer test case with certain behaviour and describing what you would improve on the behaviour would be nice.

Thanks,
Adam

Comment by Adam Lindenthal [ 03/Jul/15 ]

Hi sebediaz,

just a kindly reminder. Could you please elaborate on the description a bit more?

Thanks,
Adam





[JERSEY-2841] @NameBinding is not working on method Created: 16/Apr/15  Updated: 16/Apr/15

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

Type: Bug Priority: Major
Reporter: zeckson Assignee: Unassigned
Resolution: Unresolved 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






[JERSEY-2840] jersey-apache-connector.jar missing OSGI properties Created: 10/Apr/15  Updated: 10/Apr/15

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

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.






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

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

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





[JERSEY-2838] Response.created(URI) does not convert relative URI to absolute Created: 08/Apr/15  Updated: 18/May/15

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

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

Issue Links:
Related
is related to JERSEY-1910 Response.created(URI) does not conver... Resolved
is related to JERSEY-2860 When setting a new baseUri in a prema... Open

 Description   

Returning a Response based upon a relative URI under Jersey 2.17 does not convert the URI to an absolute path relative to the request URI as defined by the jax-rs Response class declares:

Response Javadoc

If a relative URI is supplied it will be converted into an absolute URI by resolving it relative to the request URI

Modifying the provided HelloWorldResource as follows:

@Path("helloworld")
public class HelloWorldResource {
    @POST
    @Produces(MediaType.TEXT_PLAIN)
    public Response post() throws Exception {
        return Response.created(new URI("relative")).build();
    }
}

POST to http://localhost:8080/helloworld-webapp/helloworld:
Expected Location header: http://localhost:8080/helloworld-webapp/helloworld/relative
Actual Location header: http://localhost:8080/helloworld-webapp/relative

This works correctly in Jersey 1.x and appears to be a regression in 2.x.



 Comments   
Comment by briehman [ 08/Apr/15 ]

This is potentially a duplicate of https://java.net/jira/browse/JERSEY-1910 but I cannot link it.

Comment by Adam Lindenthal [ 15/May/15 ]

Hi, thanks for reporting.
IIRC, we are absolutizing the relative URI based on the base URI of the request, which might not be correct.

I will move the issue to backlog, so that we can take a look at it, compare it with the spec and make it work as specified.

Regards,
Adam

Comment by wouterdanes [ 15/May/15 ]

"IIRC, we are absolutizing the relative URI based on the base URI of the request, which might not be correct."

Not quite, it calls URI#resolve() on the base uri, which means that:

  • if the path has no leading slash, it's resolved relative to the base uri
  • if the path has a leading slash, it's resolves relative to the authority, so any base path is removed.

I think the latter is wrong, because the resource only knows about itself. Any path with a leading slash should be resolved relative to the base URI of the container it runs in.

For example:

I run a resource /self in a microservice that's served under /customer in tomcat. The base uri of every request will be /customer. If I create a link from the microservice to /some-one-else then this should resolve to /customer/some-one-else.

So IMO when you pass an URI to created which is not fully qualified (including scheme & host), then:

  • if it starts with a leading slash, it should be resolved as a relative path from the base uri (UriBuilder.from(baseUri).path(theUri))
  • if it doesn't start with a leading slash, it should be resolved as a relative path from the request uri (UriBuilder.from(requestUri).path(theUri).)

I wonder if the latter is possible though, because the involved method interfaces don't really pass on the right information.

Comment by Adam Lindenthal [ 18/May/15 ]

Thanks for your input.





[JERSEY-2837] GrizzlyConnector can cause Jersey to return premature end stream Created: 08/Apr/15  Updated: 17/Apr/15  Resolved: 17/Apr/15

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

Type: Bug Priority: Critical
Reporter: luengnat Assignee: Marek Potociar
Resolution: Fixed Votes: 0
Labels: pull-request
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

There is a bug in handling byte stream that contains 0xFF byte. When it does, it will treat the byte as EOF marker instead. This is due to mishandling of negative byte values



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

@luengnat May you provide us more information about the issue? Where the bug is and how to reproduce it. May you prepare reproducible test case? Thanks.

Comment by luengnat [ 08/Apr/15 ]

The test case is already there in the patch.
https://github.com/jersey/jersey/pull/155

Comment by luengnat [ 08/Apr/15 ]

It's a duplicate of JERSEY-2817, JERSEY-2498

Comment by luengnat [ 16/Apr/15 ]

Code is ready to be merged
https://github.com/jersey/jersey/pull/155





[JERSEY-2836] Use of private class in httpsclientservergrizzly example Created: 08/Apr/15  Updated: 18/May/15

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

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


 Description   

The httpsclientservergrizzly example in version 2.17 uses an internal private class org.glassfish.jersey.internal.util.Base64 and a jersey specific class org.glassfish.jersey.server.ContainerRequest.
The problem is that programmers - in my team but, I believe also elsewhere - will copy paste that code into production software causing a dependence on Jersey and worse, on an internal class of Jersey.

Luckily there's an easy fix to the use of both these classes.
A patch is here: https://gist.github.com/ophers/1a810a6ca90b1448c1e6

This should be an easy fix. And it is important.

Thanks.



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

Hi Opher,

thanks for noticing and creating the issue.

Honestly, I don't think there's anything really wrong with using ContainerRequest in general, as this class is a part of Jersey's public API. Or, from a wider field of view, there's nothing wrong with using Jersey specific API, if it brings you something - you don't change your JAX-RS provider every day, right? But in that case, I agree with you, as there's seems to be no reason for typecast to ContainerRequest, as the code does not use any specific code.
And, of course, we shouldn't use classes from the internal package in the examples - those are not a "safe" public API and might be changed anytime.

Wouldn't you prefer to create a pull-request, considering you've already created the gist anyway? Especially in case you should plan to contribute more than once (there's a bit of 'paperwork' with he first PR).

https://jersey.java.net/scm.html#/Submitting_Patches_and_Contribute_Code

Please, let us know...

Regards,
Adam

Comment by Opher Shachar [ 15/May/15 ]

So,
I've signed and emailed the OCA, and created a pull request https://github.com/jersey/jersey/pull/166

Comment by Adam Lindenthal [ 18/May/15 ]

Sweet, thank you!

It will take a while until the OCA and PR itself is processed, so in the meantime, I let the issue take a rest in the backlog.

Regards,
Adam





[JERSEY-2835] Add new ApacheClientProperties.DISABLE_AUTOMATIC_RETRIES flag Created: 07/Apr/15  Updated: 07/Apr/15

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

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


 Description   

Add new ApacheClientProperties.DISABLE_AUTOMATIC_RETRIES flag
Calling HttpClientBuilder#disableAutomaticRetries






[JERSEY-2834] Jersey async API can't handle no result case Created: 07/Apr/15  Updated: 03/Jul/15  Resolved: 03/Jul/15

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

Type: Bug Priority: Critical
Reporter: hongxingli Assignee: Unassigned
Resolution: Works as designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

any



 Description   

for the case below, after logout, no result need to return, but if I assign null, then Jersey will throw an exception

    @POST
    @Path("logout")
    @ManagedAsync
    public void logout(@Suspended final AsyncResponse asyncResponse) {
      .......  
      asyncResponse.resume(null);
    }


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

I think you should return something. I guess you would like to return 2xx response code. What about returning 204 No Content:

asyncResponse.resume(Response.noContent().build());
Comment by Adam Lindenthal [ 03/Jul/15 ]

Hi hongxingli, I agree with Libor and as you did not respond for some while, I am closing the issue. Please contact us if you can provide the reason for this issue to remain open.

Regards,
Adam





[JERSEY-2833] JS client disconnect leaves SSE connections in CLOSE_WAIT Created: 05/Apr/15  Updated: 25/May/15

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

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

Production



 Description   

There seems to be a problem with Jersey SSE closing the underlying connections of ChunkedOutput. On client disconnect, the connections stay in CLOSE_WAIT till the tomcat server that is running the webapp is restarted.

Steps to replicate the issue

Create a singleton instance of a subclass of SseBroadcaster, constructor must call super(SseBroadcaster.class); Override onClose and onException methods.
Add a resource that uses this custom broadcaster and provide method to subscribe to SSE

Build a JS client that subscribes to SSE events as mentioned here
https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events

Try closing the eventSource from the browser, the connection immediately goes into the CLOSE_WAIT state.

Problem

onClose of the custom broadcaster never gets invoked, so the ChunkedOutput is never closed, and since the ChunkedOutput corresponds to a connection it lingers around bleeding the server of connections till it chokes and cannot accept any more connections.



 Comments   
Comment by Michal Gajdos [ 20/May/15 ]

Can you provide a reproducible test-case. I am not sure I can reproduce it. Thanks.

When SSE connection is closed on the client then the ChunkedOutput representing that connection on the server is closed during the broadcasting of the next message (to other connected clients). Jersey finds out that this connection is no longer alive and released resources.

Comment by jvxr [ 25/May/15 ]

Thanks for looking into it. I spent the weekend troubleshooting this issue. What was happening is that the eventSource on the client side (js) never got into readyState '1' unless we did a broadcast as soon as a new subscription was added. Even in this state the client could receive data pushed from the server. Adding call to do a broadcast a simple "OK" message helped kicking the eventSource into readyState 1.

On closing the connection, just closing the eventSource on the client side doesn't help. Taking a cue from your previous post, another call to do a broadcast with an "OK" message helped to pre-emptively clear the connection left in CLOSE_WAIT state. This obviously involved making an ajax call to force the server to do a broadcast. I can confirm that doing this fixes the CLOSE_WAIT connections.





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

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

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


 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





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

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

Type: Task Priority: Major
Reporter: puntogil Assignee: Unassigned
Resolution: Unresolved 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





[JERSEY-2830] Memory leak when of response.readEntity when using JAX-RS Client API Created: 27/Mar/15  Updated: 05/Jun/15

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

Type: Bug Priority: Critical
Reporter: nogyara Assignee: Unassigned
Resolution: Unresolved 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?





[JERSEY-2829] javax.ws.rs.core.Response#readEntity sometimes returns an empty string, if hasEntity() is called first Created: 26/Mar/15  Updated: 22/Jun/15

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

Type: Bug Priority: Major
Reporter: eiden Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: None
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.





[JERSEY-2828] "Jersey bean validation" does not validate @PathParam on sub resource location Created: 20/Mar/15  Updated: 12/May/15

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

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


 Description   

Thare is no validation on sub resource location.

For example:

@Path("{resourceId}/action")
public ActionResource actionController(@PathParam("resourceId") @PathId @Pattern(regexp = "\\d{1,10}") String resourceId) {
        ....
}

parameter "resourceId" will not be validated






[JERSEY-2827] Filter priority - negative numbers Created: 20/Mar/15  Updated: 20/May/15

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

Type: Bug Priority: Minor
Reporter: walec51 Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: 1221, incomplete
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

The LoggingFilter has priority set to @Priority(Integer.MIN_VALUE)
However we noticed that it is actually executed after our own filter which had @Priority(100).
When we extended the LoggingFilter and gave it @Priority(0) the it started to execute before the filter with @Priority(100).

So there is either a problem with the ordering mechanism or the LoggingFilter should have @Priority(0).



 Comments   
Comment by Michal Gajdos [ 23/Mar/15 ]

Hi,

where is this happening (client/server)? Which version of Jersey do you use?

thanks,
Michal

Comment by Libor Kramolis [ 08/Apr/15 ]

@walec51 May you complete the report please.

Comment by abhirockzz [ 21/Apr/15 ]

I confirmed that the issue occurs on the server side with Jersey 2.10.4 (GlassFish 4.1.0). Seems as if negative Priority values are not being taken into account. I do not see anything in the JAX-RS specification as well w.r.t usage of negative values in @Priority. All that's stated is that the server side filters will be invoked in ascending order of @Priority





[JERSEY-2826] Jersey EntityFilteringFeature doesn't work correctly with abstract classes Created: 20/Mar/15  Updated: 08/Apr/15

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

Type: Bug Priority: Major
Reporter: satyavrat_prabhune Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: entity-filtering
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Windows 7, JDK 1.7



 Description   

I want to use Jersey's EntityFilteringFeature with my abstract super class. When EntityFilteringFeature is NOT registered, I get correct representation of concrete child class, but the moment I register EntityFilteringFeature, child class field is not marshalled. Appears to be a Jersey bug.

I am using MOXy provider.

Please see all details at http://stackoverflow.com/questions/29140367/jersey-entityfilteringfeature-doesnt-work-correctly-with-abstract-classes






[JERSEY-2825] MOXyJsonProvider cannot unmarshall JSON arrays into custom collection types Created: 16/Mar/15  Updated: 16/Mar/15

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

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


 Description   

Note: This is a problem in MOXy 2.6. It's filed against Jersey just to track the progress and the issue should be closed when new MOXy is integrated into Jersey.

Consider you have this JSON:

[{"jaxbBean":{"value":"one"}},{"jaxbBean":{"value":"two"}},{"jaxbBean":{"value":"three"}}]

Resource Method like:

@POST
@Path("custom")
public MyArrayList<JaxbBean> postCustom(final MyArrayList<JaxbBean> l) {
    return l;
}

Where MyArrayList looks like:

public class MyArrayList<T> extends ArrayList<T> {

    public MyArrayList() {
    }

    public MyArrayList(final Collection<T> a) {
        super(a);
    }

}

The JSON is unmarshalled as list of lists (MyArrayList of MyArrayLists) but JaxbBeans are not in unmarshalled object.






[JERSEY-2824] ObjectGraphImpl throwing NullPointerException when role entity has an abstract method implementation returning a custom object Created: 15/Mar/15  Updated: 24/Mar/15  Resolved: 24/Mar/15

Status: Resolved
Project: jersey
Component/s: extensions, security
Affects Version/s: 2.16
Fix Version/s: 2.18

Type: Bug Priority: Major
Reporter: rehan.shaukat Assignee: Michal Gajdos
Resolution: Fixed Votes: 0
Labels: entity-filtering
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Mac OS X 10.10.2 (14C1510)
Java 1.7.0_60



 Description   

I am trying the new feature in *Jersey 2.16* that supports *role-based entity filtering via Jackson*.

`NullPointerException` is thrown:

    java.lang.NullPointerException
	at org.glassfish.jersey.message.filtering.ObjectGraphImpl.getSubgraphs(ObjectGraphImpl.java:109)
	at org.glassfish.jersey.jackson.internal.JacksonObjectProvider.createSubfilters(JacksonObjectProvider.java:89)
	at org.glassfish.jersey.jackson.internal.JacksonObjectProvider.transform(JacksonObjectProvider.java:74)
	at org.glassfish.jersey.jackson.internal.JacksonObjectProvider.transform(JacksonObjectProvider.java:67)
	at org.glassfish.jersey.message.filtering.spi.AbstractObjectProvider.createFilteringObject(AbstractObjectProvider.java:138)
	at org.glassfish.jersey.message.filtering.spi.AbstractObjectProvider.getFilteringObject(AbstractObjectProvider.java:100)
	at org.glassfish.jersey.message.filtering.spi.AbstractObjectProvider.getFilteringObject(AbstractObjectProvider.java:83)
	at org.glassfish.jersey.jackson.internal.FilteringJacksonJaxbJsonProvider.writeTo(FilteringJacksonJaxbJsonProvider.java:130)
	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.spi.ContentEncoder.aroundWriteTo(ContentEncoder.java:138)
	at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
	at org.glassfish.jersey.spi.ContentEncoder.aroundWriteTo(ContentEncoder.java:138)
	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:1118)
	at org.glassfish.jersey.server.ServerRuntime$Responder.writeResponse(ServerRuntime.java:662)
	at org.glassfish.jersey.server.ServerRuntime$Responder.processResponse(ServerRuntime.java:418)
	at org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:408)
	at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:306)
	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:286)
	at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1072)
	at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:399)
	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.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)

if I use a Jackson entity inherited from an abstract class, having an abstract method that returs another object of some custom class.

`JacksonFeature` and `SecurityEntityFilteringFeature` is registered and resource method looks like:

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @RolesAllowed(ACTUAL_ROLE)
    public User getTestData() {
      return new User("name", "address");
    }

where User is defined as:

    public class User extends SuperUser {
      
      private String name;
      private String address;
      
      public User(String name, String address){
        this.name = name;
        this.address = address;
      }
    
      public String getName() {
        return name;
      }
      
      public String getAddress() {
        return address;
      }
    
      @Override
      public MoreData getMoreData() {
        return null;
      }
    }
    
    abstract class SuperUser {
        public abstract MoreData getMoreData();
    }
    
    class MoreData {
    }

Everything works fine If `getMoreData()` returns a non-custom objection for instance `String`.



 Comments   
Comment by rehan.shaukat [ 15/Mar/15 ]

don't see any edit option to make formatting better

Comment by Michal Gajdos [ 18/Mar/15 ]

Moving to backlog for now (plan to look into it very soon).





[JERSEY-2823] Jersey does not handle PUT with Content-Type="" Created: 12/Mar/15  Updated: 19/Mar/15  Resolved: 17/Mar/15

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

Type: Bug Priority: Major
Reporter: timuralp Assignee: Jakub Podlesak
Resolution: Invalid Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Linux



 Description   

If a client submits a PUT request with Content-Type set to "" (empty string), Jersey returns error 400.

I could not find anything in the HTTP specification prohibiting a client from sending such requests (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html), but maybe I did not read it carefully. If this behavior is permitted, then Jersey does not process these requests at all – it is impossible to register any handler for it.

If such requests are prohibited, please point me to the documentation and mark this as invalid (I'll look into fixing the client).



 Comments   
Comment by Jakub Podlesak [ 17/Mar/15 ]

http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7

Here is a quote from part 14.17 of the very same doc you have referred originally:

The Content-Type entity-header field indicates the media type of the entity-body sent to the recipient or, in the case of the HEAD method, the media type that would have been sent had the request been a GET.

Content-Type = "Content-Type" ":" media-type
Media types are defined in section 3.7. An example of the field is

Content-Type: text/html; charset=ISO-8859-4

Comment by timuralp [ 18/Mar/15 ]

At the same time, if one looks at the media types, the following stands out: "Use of non-registered media types is discouraged."

An empty string could be called an "unregistered" media type, which is not explicitly prohibited, but only "discouraged". Could you point to where it is explicitly required to be set?

Comment by Jakub Podlesak [ 18/Mar/15 ]

What about this one:

media-type = type "/" subtype *( ";" parameter )
type = token
subtype = token

How does it match your "emptie"? Where is the slash character there? Any more ideas?

Comment by timuralp [ 19/Mar/15 ]

This came up as the python-swiftclient submits such requests (the command line tool the openstack project ships). I verified that such requests do succeed against Rackspace CloudFiles (a swift provider) and docker-swift (docker container with swift). I filed a bug against the openstack project about this.

Anyway, thanks for looking into this. I'm not sure what warranted the response above, however.





[JERSEY-2822] Impossible to send 204 (No-Content) with Content-Length and Content-Type set Created: 12/Mar/15  Updated: 22/Jun/15  Resolved: 18/Mar/15

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

Type: Bug Priority: Major
Reporter: timuralp Assignee: Jakub Podlesak
Resolution: Works as designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Linux



 Description   

I am attempting to implement an OpenStack Swift server. While implementing the API for the Containers (http://developer.openstack.org/api-ref-objectstorage-v1.html) I found that it is impossible to implement HEAD according to that specification with Jersey. Specifically, when handling a HEAD request for an object, I cannot send back a No-Content response with Content-Length and Content-Type set to the object's size and type. When I explicitly set the headers, they are stripped off.

What is the reason that headers that are set explicitly by calling <ResponseBuilder>.header() removed in subsequent response processing?



 Comments   
Comment by Michael Osipov [ 13/Mar/15 ]

This is partially by design in Jersey. Read: http://stackoverflow.com/a/24574405/696632

Comment by Jakub Podlesak [ 18/Mar/15 ]

Please see the stack-overflow discussion linked above for possible solution (container response filter).

Comment by khc [ 25/May/15 ]

The solution in stackoverflow does not appear to work. Jersey appears to log Content-Type in the response:

INFO: 46 * Server responded with a response on thread grizzly-http-server-6
46 < 204
46 < Accept-Ranges: bytes
46 < Content-Length: 0
46 < Content-Type: text/plain
...

But the client does not see it:
HTTP/1.1 204 No Content
X-Container-Object-Count: 0
X-Container-Bytes-Used: 0
X-Versions-Location:
X-Timestamp: -1
X-Trans-Id: -1
Accept-Ranges: bytes
Date: Mon, 25 May 2015 23:33:46 GMT

Comment by Michael Osipov [ 26/May/15 ]

Where is the point having content type and length sent if you have 204? I see none. You should rather use 200.

Comment by timuralp [ 26/May/15 ]

The OpenStack Swift API has a few places where 204 with Content-Length: 0 is expected.
For example:
Create container metadata:

curl -i $publicURL/marktwain -X POST -H "X-Auth-Token: $token" -H "X-Container-Meta-Author: MarkTwain" -H "X-Container-Meta-Web-Directory-Type: text/directory" -H "X-Container-Meta-Century: Nineteenth"

HTTP/1.1 204 No Content
Content-Length: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx05dbd434c651429193139-0052d82635
Date: Thu, 16 Jan 2014 18:34:29 GMT

Or
Update container metadata:

curl -i $publicURL/marktwain -X POST -H "X-Auth-Token: $token" -H "X-Container-Meta-Author: SamuelClemens"

HTTP/1.1 204 No Content
Content-Length: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: txe60c7314bf614bb39dfe4-0052d82653
Date: Thu, 16 Jan 2014 18:34:59 GMT

Or
Delete container metadata:

curl -i $publicURL/marktwain -X POST -H "X-Auth-Token: $token" -H "X-Remove-Container-Meta-Century: x"

HTTP/1.1 204 No Content
Content-Length: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx7997e18da2a34a9e84ceb-0052d826d0
Date: Thu, 16 Jan 2014 18:37:04 GMT

You can find the whole API documentation here: http://developer.openstack.org/api-ref-objectstorage-v1.html. This comes up in a number of places.

Comment by khc [ 22/Jun/15 ]

The problem actually lies in grizzly and I've filed an issue at https://java.net/jira/browse/GRIZZLY-1784





[JERSEY-2821] Inconsistent getParameters and toString in AcceptableMediaType Created: 12/Mar/15  Updated: 23/Mar/15  Resolved: 23/Mar/15

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

Type: Bug Priority: Minor
Reporter: Thomas_Schulz Assignee: Jakub Podlesak
Resolution: Works as designed Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

When an org.glassfish.jersey.message.internal.AcceptableMediaType is created via the following constructor:

public AcceptableMediaType(String type, String subtype) {             
    super(type, subtype); // no need to add default quality parameter.
    q = Quality.DEFAULT;                                              
}

, the toString-Method will return something like this:

{application/hal+json, q=1000}

, whereas getParameters (which is not overridden), whill return an empty array.
This inconsistency causes problems even in code in the same package, because the method stripQualityParams in org.glassfish.jersey.message.internal.MediaTypes will return the original AcceptableMediaType intance instead of creating a new MediaType instance without quality parameters.

It should be sufficient to change the aforementioned constructor to look like this:

public AcceptableMediaType(String type, String subtype) {             
    super(type, subtype, Quality.enhanceWithQualityParameter(parameters, Quality.QUALITY_PARAMETER_NAME, Quality.DEFAULT));
    q = Quality.DEFAULT;                                              
}

Disclaimer: I did not test that; I just reverted back to Jersey 2.15.

As a side note: I don't understand why q would be an int when according to RFC 7231 the quality value is supposed to be "a real number in the range 0 through 1". Accordingly I would expect Quality.MAXIMUM (and therefore Quality.DEFAULT) to have the value 1.0 instead of 1000.



 Comments   
Comment by Jakub Podlesak [ 23/Mar/15 ]

Thomas, could you please elaborate a bit? Why should MediaTypes.stripQualityParams create any new instance?

You are reporting a bug against internal Jersey classes without providing a reproducible test that would show
Jersey breaks any valid use case.

On the "why 1000" side note: Jersey uses this only internally.

Comment by Jakub Podlesak [ 23/Mar/15 ]

I am resolving this as "works as designed". Please see my comments above for some more details.

Fee free to re-open based on a concrete test case proving the internal Jersey code wrong.





[JERSEY-2820] Cannot inject HttpServletRequest in ContainerRequestFilter via @Context when running unit test extends JerseyTest in Jersey 2.0 Jetty Test Framework Container Created: 11/Mar/15  Updated: 19/Mar/15

Status: Open
Project: jersey
Component/s: test-framework
Affects Version/s: 2.16
Fix Version/s: backlog

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

WINDOWS 7 64bit
JDK 7
jersey 2.16
spring 3.2.3
aspectj 1.8.0



 Description   

This issue is like https://java.net/jira/browse/JERSEY-2462,
the different is that it happens in Jersey UnitTest.

public class RemoteFilter implements ContainerRequestFilter {
    //auto inject HttpServletRequest
    @Context
    private HttpServletRequest request;

    @Override
    public void filter(ContainerRequestContext ctx) throws IOException {
        //request is null when running unit test extends JersyTest
        String remoteAddr = request.getRemoteAddr();
    }
}


 Comments   
Comment by Adam Lindenthal [ 11/Mar/15 ]

Hi Bglmmz,

could you please specify what container you are using and how are you configuring it?
I'm sure you know that, but you have to really be on a servlet environment in order to have Servlet related objects injected and JerseyTest uses GrizzlyHttpContainer (non-servlet) as its default.
Would you be able to provide the full runable reproducing testcase?

Thank you,
Adam

Comment by bglmmz [ 12/Mar/15 ]

<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<version>$

{jersey.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-grizzly2</artifactId>
<version>${jersey.version}

</version>
<scope>test</scope>
</dependency>

Comment by bglmmz [ 12/Mar/15 ]

the same issue if use jetty..
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-jetty</artifactId>
<version>$

{jersey.version}

</version>
</dependency

Comment by Jakub Podlesak [ 19/Mar/15 ]

Grizzly HTP container is not based on Servlet, so it does not make any sense to ask the HttpServletRequest injected there.

Regarding the Jetty container, this feature is indeed missing.

As a workaround, you should be able to use the external test container (https://jersey.java.net/documentation/latest/test-framework.html#d0e17242)
to test your use case.





[JERSEY-2819] ServletContainer hangs on startup - infinite loop Created: 10/Mar/15  Updated: 29/May/15  Resolved: 29/May/15

Status: Resolved
Project: jersey
Component/s: core, osgi
Affects Version/s: 2.16
Fix Version/s: 2.18

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

Jetty 9.2.9.v20150224 running inside Apache Felix 4.4.2 OSGI container


Attachments: Zip Archive jersey-startup-freeze.zip    
Tags: osgi

 Description   

I'm trying to deploy simple web app to Jetty runnin inside OSGI container. What I am experiencing in that ServletContainer hangs on startup and never loads.
My web.xml:

 <servlet>
        <servlet-name>Jersey Web Application</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.vektorsoft.demux.web.resource</param-value>
        </init-param>
        
        <load-on-startup>10</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Web Application</servlet-name>
        <url-pattern>/webresources/*</url-pattern>
    </servlet-mapping>

I managed to isolate infinite loop happenning in org.glassfish.jersey.server.ResourceConfig, lines 887-905. The reason is that _org.glassfish.server.internal.scanning.BundleSchemeResourceFinderFactory.next() method does not advance iteration, but always returns the same item. Advance happens only in open() method in that class.

So, when you specify package which contains subpacakges as jersey.config.server.provider.packages property, infinite loop will happen. The reason is tha package name is never accepted in ResourceConfig:890, so open() is never called in _BundleSchemeResourceFInderFactory and iteration does not advance, returning the same object over and voer again.

If you specify package that does not contain subpackages as jersey.config.server.provider.packages, everything works fine.



 Comments   
Comment by Adam Lindenthal [ 11/Mar/15 ]

Hi Vdjurovic,

thanks for reporting and for investigation you've made.

Could you please make it easier for us to reproduce by providing a minimal test case (the configuration you've provided + e.g. one resource) and most importantly some steps to do? We do not run jetty inside osgi on our tests. Is this achievable within maven using some plugins (pax exam, etc)? It would be also useful for creating some integration test after its fixed.

It would be very helpful if you could write down some steps like "start the felix shell", "write [whatever command] to load [such and such] bundle", etc.

Many thanks,
Adam

Comment by Adam Lindenthal [ 11/Mar/15 ]

In the meantime, I will move this issue to backlog for further planning.

Comment by vdjurovic [ 11/Mar/15 ]

Hi, Adam

I've just started working on this project yesterday (and hit this bump immediatelly ), so I can not really provide streamlined test case. I have created Maven project with 3 modules:

  • server - Jetty server running inside Apace Felix
  • simple-bundle - OSGI bundle containing JAX-RS resources
  • jersey-startup-freeze-war - web application which starts ServletContainer

I can't attach files, so here is the download link:http://vektorsoft.com/files/jersey-startup-freeze.zip

How to run:

  1. extract the contents and change to jersey-startup-freeze dir
  2. run mvn install
  3. cd to server dir
  4. run
    java -Djetty.home=jettyhome/ -jar bin/felix.jar
  5. web app should start few seconds after server startup and freeze immediatelly. It also causes entire server to freeze
  6. in web.xml, if you change jersey.config.server.provider.packages value to package without subpackages, app starts normally

To run server in debug mode, use this command:

ava -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=<port_number> -Djetty.home=jettyhome/ -jar bin/felix.jar

Then attach debugger. If you set breakpoint to the line I've specified in bug descritpion, you can see infinite loop is created.

I'm not sure about running integration tests, Pax Exam is probably good choice. I don't have much free time right now, but I can try to set something up later when I'm not too busy.
Let me know if you need any more info from me.

Comment by Adam Lindenthal [ 11/Mar/15 ]

Thanks a lot, I guess that will be very helpful for reproducing. I've attached your zip here for the one of us who will be working on it.

Regards,
Adam

Comment by Stepan Vavra [ 29/May/15 ]

It should be fixed now!





[JERSEY-2818] RolesAllowedDynamicFeature can return 401 or 403 errors. Created: 10/Mar/15  Updated: 15/Apr/15  Resolved: 19/Mar/15

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

Type: Improvement Priority: Major
Reporter: krotscheck Assignee: Michal Gajdos
Resolution: Fixed Votes: 4
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently, the RolesAllowedRequestFilter will always return HTTP 403 Forbidden. This is accurate in all cases where the security context is aware of the principal (securityContext.getUserPrincipal() is not null), however it is not strictly accurate in the case where a user has not been authenticated. In that case, returning HTTP 401 Unauthorized is more accurate, as the user has not provided the correct credentials.

The following code should suffice, if inserted before the role check loop.

if(requestContext.getSecurityContext().getUserPrincipal() == null && rolesAllowed.length > 0)

{ throw new NotAuthorizedException(); }

 Comments   
Comment by Adam Lindenthal [ 11/Mar/15 ]

Hi krotscheck,

thanks for reporting the improvement suggestion.
I will put it to backlog, so that someone can look at it in one of the future sprints.

Regards,
Adam

Comment by brunosimioni [ 18/Mar/15 ]

Guys,

Same problem over here. Since my API with RolesAllowedDynamicFeature is returning 403 instead of 401, Actually, I'm stucked in the same step and I'm currently integrating with others systems with this API. Returning then with forbidden 403 to a non-authenticated user just makes no sense.

Would you guys priorize this issue, or do you have a release date, or even can I make the fix and make a pull request under github repositories?

Best!

Comment by brunosimioni [ 19/Mar/15 ]

Guys,

I've forked the Jersey's github repository, patched up with krotscheck's fix and made a pull request to merge with master branch. Hope you guys accept it as soon as possible, since there is a scheduled build on April.

Please check this out: https://github.com/jersey/jersey/pull/150

Comment by Michal Gajdos [ 19/Mar/15 ]

I'll deliver fix for this internally - it'd be faster.

Comment by brunosimioni [ 19/Mar/15 ]

Thanks Michal!

Would it be available at April 8th?

I'll sign out the OCA too, for future collaborations.

Thank you very much.

Comment by Michal Gajdos [ 19/Mar/15 ]

It'll be in 2.18 (April 8th is approximate but 2.18 should be out that week).

Comment by Michal Gajdos [ 19/Mar/15 ]

Merged into master branch.

Comment by brunosimioni [ 19/Mar/15 ]

Michal, I've just saw you merge. Thank you for that!

Just a question: shouldn't NotAuthorizedException preceeds the ForbiddenException? Authorization should be evaluted before Permission rights, do you agree? Because to check wether the user can or cannot access the resource, it must be known.

In my patch (thanks to krotscheck) I've checked Authorization before DenyAll condition, but in your implementation, you did the inverse.

Best

Comment by andrewzimmer [ 15/Apr/15 ]

Glad to hear that this is going to be taken care of!





[JERSEY-2817] ByteBufferInputStream has bad casts for byte reads Created: 06/Mar/15  Updated: 06/Mar/15  Resolved: 06/Mar/15

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

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

Issue Links:
Duplicate
duplicates JERSEY-2498 ByteBufferInputStream violates InputS... Reopened

 Description   

ByteBufferInputStream has bad casts for byte reads - allowing a byte of '255' to be cast to '-1' as an int - which would indicate EOF on a read. The mask will push this back to the unsigned value.

A pull request #147 exists to fix the issue.






[JERSEY-2816] Error closing message content input stream. Created: 06/Mar/15  Updated: 23/Mar/15  Resolved: 23/Mar/15

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

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


 Description   
javax.ws.rs.ProcessingException: Error closing message content input stream.
	at org.glassfish.jersey.message.internal.EntityInputStream.close(EntityInputStream.java:159)
	at sun.nio.cs.StreamDecoder.implClose(StreamDecoder.java:358)
	at sun.nio.cs.StreamDecoder.close(StreamDecoder.java:173)
	at java.io.InputStreamReader.close(InputStreamReader.java:182)
	at org.eclipse.persistence.internal.libraries.antlr.runtime.ANTLRReaderStream.load(ANTLRReaderStream.java:92)
	at org.eclipse.persistence.internal.libraries.antlr.runtime.ANTLRInputStream.<init>(ANTLRInputStream.java:68)
	at org.eclipse.persistence.internal.libraries.antlr.runtime.ANTLRInputStream.<init>(ANTLRInputStream.java:52)
	at org.eclipse.persistence.internal.libraries.antlr.runtime.ANTLRInputStream.<init>(ANTLRInputStream.java:48)
	at org.eclipse.persistence.internal.libraries.antlr.runtime.ANTLRInputStream.<init>(ANTLRInputStream.java:40)
	at org.eclipse.persistence.internal.oxm.record.json.JSONReader.parse(JSONReader.java:105)
	at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:972)
	at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:425)
	at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:375)
	at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:705)
	at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:655)
	at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:301)
	at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.readFrom(MOXyJsonProvider.java:580)
	at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:239)
	at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:211)
	at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:139)
	at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1109)
	at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:853)
	at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:785)
	at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:267)
	at org.glassfish.jersey.client.InboundJaxrsResponse$1.call(InboundJaxrsResponse.java:111)
	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:397)
	at org.glassfish.jersey.client.InboundJaxrsResponse.readEntity(InboundJaxrsResponse.java:108)
	at com.xxxxx.GalaxyFDSClient.listObjects(GalaxyFDSClient.java:334)
	at com.xxxxx.TestFDSJavaSdk.deleteOneBucket(TestFDSJavaSdk.java:172)
	at com.xxxxx.TestFDSJavaSdk.testListBuckets(TestFDSJavaSdk.java:401)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.FailOnTimeout$StatementThread.run(FailOnTimeout.java:74)
Caused by: java.io.IOException: Stream closed.
	at java.net.PlainSocketImpl.available(PlainSocketImpl.java:452)
	at java.net.SocketInputStream.available(SocketInputStream.java:217)
	at java.io.BufferedInputStream.available(BufferedInputStream.java:381)
	at sun.net.www.MeteredStream.available(MeteredStream.java:152)
	at sun.net.www.http.KeepAliveStream.close(KeepAliveStream.java:72)
	at java.io.FilterInputStream.close(FilterInputStream.java:155)
	at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.close(HttpURLConnection.java:2739)
	at org.glassfish.jersey.client.HttpUrlConnector$1.close(HttpUrlConnector.java:151)
	at org.glassfish.jersey.message.internal.EntityInputStream.close(EntityInputStream.java:157)
	... 41 more


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

Hi wuzesheng,

could you please be a bit more specific on circumstances when this occurs? Is it always repeatable/reproducible? Ideally I would ask you to extract some minimal reproducing test case (e.g. one resource, custom providers if relevant + client code that shows the issue).

Also, which version are you using?

Regards,
Adam

Comment by wuzesheng [ 06/Mar/15 ]

Hi Adam,

Thanks for your replying.
I'm using Jersey 2.5.1, this case was occurred occasionally in my environment, sometime for GET, sometime for DELETE, etc.
I haven't used any custom providers.

Comment by Adam Lindenthal [ 06/Mar/15 ]

Thanks, I've filled in the "Affected versions" field.
Honestly, I am not sure how to solve this, unless there are some reasonable steps to reproduce.
Would you be able to provide a test case, that at lease "sometimes" shows this issue, along with the instructions how to reproduce? I don't mind sending a request 20 times before the error occurs...

Thanks,
Adam

Comment by wuzesheng [ 06/Mar/15 ]

OK, I'll try to construct a test case and will post it here later.

Comment by Adam Lindenthal [ 06/Mar/15 ]

Thanks, that will be very helpful.

Comment by wuzesheng [ 11/Mar/15 ]

Sorry for later response.
I tried to construct such a case, but it's not that easy.
I can offer one more message, perhaps related:
When I run the jersey application on openstack virtual machine, this exception occurs occasionally, but when I run the same application on a standalone machine, it never occurs.
Does this help?

Comment by Adam Lindenthal [ 11/Mar/15 ]

Honestly, I would love to say "yes", but it does not . But thanks for taking your time to investigate anyway.
We have to narrow it down somehow. For the start, have you tried some more recent Jersey version or is it not an option?
Are you somehow configuring the container and connector that you are using, or do you stick with defaults? Any special server side or client side configuration?

Comment by wuzesheng [ 12/Mar/15 ]

We have to narrow it down somehow. For the start, have you tried some more recent Jersey version or is it not an option?

OK, I will have a try.

Are you somehow configuring the container and connector that you are using, or do you stick with defaults? Any special server side or client side configuration?

I configured the 'jersey-grizzly-connector' connector, and the container is default.

Comment by Jakub Podlesak [ 23/Mar/15 ]

Even if the reproducible test case would fail only in say 1 out of 20 cases it would help us to diagnose the issue.
I am going to resolve this as invalid, but please ask for re-opening once you have the reproducer ready.
Thanks for understanding.

Comment by Jakub Podlesak [ 23/Mar/15 ]

Please see above for details.
Once a test case is provided, we are going to re-open this.





[JERSEY-2815] Add support for Optional from Java 8 into Jersey Created: 04/Mar/15  Updated: 04/Mar/15

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

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


 Description   

We're currently able to support some of the types from Java 8 in Jersey (extension module). Create infrastructure for this extension module and add support for Optional (entity, param).






[JERSEY-2814] Imporve JDK container to take custom SSLContext Created: 03/Mar/15  Updated: 05/Mar/15  Resolved: 05/Mar/15

Status: Resolved
Project: jersey
Component/s: containers
Affects Version/s: 2.16
Fix Version/s: 2.17

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


 Description   

Originally reported internally by Luk Ho.

The JDK Container currently does not allow user to set custom SSLContext, like Grizzly2 and Simple severs do.
E.g. GrizzlyHttpServerFactory.createHttpServer(..., SSLEngineConfigurator)
Please improve JDK Container so that all the containers supported by Jersey provides the same functionality.



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

Fixed in 2.17.

JdkHttpServerFactory was enhanced with some new overloaded createHttpServer methods that accept SSLContext or HttpsConfigurator.





[JERSEY-2813] The RxObservableInvoker swallows errors such as 404 NotFound Created: 03/Mar/15  Updated: 09/Mar/15  Resolved: 09/Mar/15

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

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


 Description   

The RxObservableInvoker (jersey-rx-client-rxjava-2.16) swallows errors such as 404 NotFound. See example below

RxClient<RxObservableInvoker> restClient = Rx.newClient(RxObservableInvoker.class);       

restClient.target("http://localhost:8089/DoesNotExitAndReturnsA404Error")
          .request()                 
          .rx()
          .get(byte[].class)
          .onErrorReturn(error -> new byte[] { 12, 34, 45, 65 })
          .forEach(data -> System.out.println("data size " + data.length));
	     
 > data size 0

In contrast the RxCompletionStageInvoker (jersey-rx-client-java8-2.16 ) will not ignore the error

RxClient<RxCompletionStageInvoker> restClientCompletable = Rx.newClient(RxCompletionStageInvoker.class);

restClientCompletable.target("http://localhost:8089/DoesNotExitAndReturnsA404Error")
                     .request()                 
                     .rx()
                     .get(byte[].class)                              
                     .exceptionally(error -> new byte[] { 12, 34, 45, 65 })
                     .whenComplete((data, error) -> System.out.println("data size " + data.length));
        
>  data size 4


 Comments   
Comment by grro [ 04/Mar/15 ]

the corresponding HTTP response of the example is

HTTP/1.1 404 Not Found
Server: Apache-Coyote/1.1
Content-Length: 0
Date: Wed, 04 Mar 2015 04:15:43 GMT




[JERSEY-2812] Thread not released when Jersey configured as a filter Created: 03/Mar/15  Updated: 29/May/15  Resolved: 29/May/15

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

Type: Bug Priority: Major
Reporter: fpoliquin Assignee: Stepan Vavra
Resolution: Fixed Votes: 0
Labels: 1221, containers
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: Zip Archive jersey2812-master.zip    

 Description   

Using the following code:

@GET
@Path("/wait")
public void waitForRessource(@Suspended final AsyncResponse asyncResponse) {
    ...
}

The following configuration works as expected:

    <servlet>
        <servlet-name>jersey</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>xxx</param-value>
        </init-param>
        <async-supported>true</async-supported>
    </servlet>

But if I configure Jersey using the following configuration:

    <filter>
        <filter-name>jersey</filter-name>
        <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
        <async-supported>true</async-supported>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>xxx</param-value>
        </init-param>
        <init-param>
            <param-name>jersey.config.servlet.filter.forwardOn404</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

The thread executing the request is never returned to the container. The thread is stuck with this stack:

Daemon Thread [http-bio-60000-exec-10] (Suspended)
owns: Object (id=9746)
owns: SocketWrapper (id=9731)
Unsafe.park(boolean, long) line: not available [native method]
LockSupport.park(Object) line: not available
AbstractFuture$Sync(AbstractQueuedSynchronizer).parkAndCheckInterrupt() line: not available
AbstractFuture$Sync(AbstractQueuedSynchronizer).doAcquireSharedInterruptibly(int) line: not available
AbstractFuture$Sync(AbstractQueuedSynchronizer).acquireSharedInterruptibly(int) line: not available
AbstractFuture$Sync.get() line: 292
SettableFuture(AbstractFuture).get() line: 116
ResponseWriter.getResponseContext() line: 273
ResponseWriter.getResponseStatus() line: 268
WebComponent$6.get() line: 404
WebComponent$6.get() line: 401
Values$LazyValueImpl.get() line: 340
ServletContainer.doFilter(HttpServletRequest, HttpServletResponse, FilterChain, String, String, String) line: 534
ServletContainer.doFilter(HttpServletRequest, HttpServletResponse, FilterChain) line: 482
ServletContainer.doFilter(ServletRequest, ServletResponse, FilterChain) line: 419
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 241
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 208
FiltreContexteApplicationWeb.doFilter(ServletRequest, ServletResponse, FilterChain) line: 54
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 241
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 208
RestRecorderFilter.doFilter(ServletRequest, ServletResponse, FilterChain) line: 83
ApplicationFilterChain.internalDoFilter(ServletRequest, ServletResponse) line: 241
ApplicationFilterChain.doFilter(ServletRequest, ServletResponse) line: 208
StandardWrapperValve.invoke(Request, Response) line: 220
StandardContextValve.invoke(Request, Response) line: 122
StandardHostValve.invoke(Request, Response) line: 170
ErrorReportValve.invoke(Request, Response) line: 103
AccessLogValve.invoke(Request, Response) line: 950
StandardEngineValve.invoke(Request, Response) line: 116
CoyoteAdapter.service(Request, Response) line: 421
Http11Processor(AbstractHttp11Processor).process(SocketWrapper<S>) line: 1070
Http11Protocol$Http11ConnectionHandler(AbstractProtocol$AbstractConnectionHandler).process(SocketWrapper<S>, SocketStatus) line: 611
JIoEndpoint$SocketProcessor.run() line: 316
ThreadPoolExecutor(ThreadPoolExecutor).runWorker(ThreadPoolExecutor$Worker) line: not available
ThreadPoolExecutor$Worker.run() line: not available
TaskThread$WrappingRunnable.run() line: 61
TaskThread(Thread).run() line: not available

This behavior makes the @Suspended annotation basically useless as the whole point of using it is to release the thread.

I'm using Tomcat 7.0.56 with the native Windows binaries.



 Comments   
Comment by Adam Lindenthal [ 03/Mar/15 ]

Hi fpoliquin,

thanks for reporting this issue.
Just to rule out other influences, have you tried to reproduce this on some other container (Jetty, Glassfish, etc)?

The thing is, on the first quick look into the code, the destroy() method in the ServletContainer comes from both servlet and filter classes and should be invoked in both cases.

Could you share a complete minimal example (ideally maven based servlet app with a test narrowed down as much as possible).

Many thanks,
Adam

Comment by fpoliquin [ 03/Mar/15 ]

I did a test case but I don't have the rights to upload the file in JIRA. Is there another place where I can put it?

Comment by Adam Lindenthal [ 03/Mar/15 ]

Hi, that's great.

Unfortunately, we cannot assign you the permission in JIRA, so we usually use other ways to do that. If you have a github account, please upload it there and paste a link here, if not, feel free to send me a zip with soruces via email. In both cases, I will attach it here for you, if you don't mind.

Regards,
Adam

Comment by fpoliquin [ 04/Mar/15 ]

I uploaded my test case to this URL: https://github.com/fpoliquin/jersey2812

Basically, there are 4 URLs:
1. /jersey2812/test/wait This uses the filter configuration and triggers an AsyncResponse
2. /jersey2812/test/broadcast This is used to free all waiting connections
3. /jersey2812/servlet/test/wait Same as above but with a servlet configuration
4. /jersey2812/servlet/test/broadcast Same as above but with a servlet configuration

If you look in the console, you will see that the first URL never releases the thread whereas the third one does it correctly.

Thanks.

Comment by Adam Lindenthal [ 04/Mar/15 ]

Great, thanks for the test case, I have just attached it here.

Comment by Adam Lindenthal [ 05/Mar/15 ]

Hi fpoliquin,

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

Regards,
Adam

Comment by Stepan Vavra [ 29/May/15 ]

Thanks @fpoliquin!
It should be fixed now.





[JERSEY-2811] Minor grammatical issue on home page Created: 02/Mar/15  Updated: 02/Mar/15  Resolved: 02/Mar/15

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

Type: Improvement Priority: Trivial
Reporter: mcandre Assignee: Jakub Podlesak
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

"Jersey provides it’s own API" should be

"Jersey provides its own API"






[JERSEY-2810] InMemory JerseyTest ignore contextPath parameter Created: 02/Mar/15  Updated: 06/Mar/15

Status: Open
Project: jersey
Component/s: test-framework
Affects Version/s: 1.18.1
Fix Version/s: 1.x-backlog

Type: Bug Priority: Major
Reporter: nfalco79 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-2809 ClientConfig is ignored by InMemoryTe... Open

 Description   

The context path configured in the WebAppDescriptor.Builder() is ignored by test framework.
With a configured path "test" I expect that for a resource @Path("resources") annotated at class level, requests that matches resource methods start with monospaced

{schema}

://

{host}

:

{port}

/test/resources/...monospaced



 Comments   
Comment by nfalco79 [ 02/Mar/15 ]

:\ issue can not be edited.
The URLs expected are in form:
http://<host>:<port>/test/resources/...

Follow a JUnit

ContextPathTest.java
public class ContextPathTest extends JerseyTest {

	@Path("api/resources")
	public static class ContextPathResource {
		@POST
		@Consumes(MediaType.APPLICATION_JSON)
		@Path("")
		public Response create(Resource resource) {
			return Response.created(null).build();
		}
	}

	@XmlRootElement
	public static class Resource {
		private String name;

		public String getName() {
			return name;
		}

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

	}

	@Override
	protected AppDescriptor configure() {
		return new WebAppDescriptor.Builder(this.getClass().getPackage().getName())
				.contextPath("test")
				.build();
	}

	@Test
	public void context_path() {
		Resource res = new Resource();
		res.setName("my resource");

		URI uri = UriBuilder.fromUri(getBaseURI()).path("test").path(ContextPathResource.class, "create").build();

		ClientResponse response = client()
				.resource(uri)
				.post(ClientResponse.class, res);

		Assert.assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
	}
}
Comment by Michal Gajdos [ 02/Mar/15 ]

I guess the expected URL should be rather `http://<host>:<port>/test/api/resources/...` but I see your point. I'll check whether the problem is in 2.x as well and if this is the case then the problem would be fixed there (and hopefully migrated into 1.x).

Comment by nfalco79 [ 02/Mar/15 ]

The expected URL refers to the issue context description.
The JUnit was writing after the issue opened and an "api" in the root resource path was introduced.
I'm sorry for the mismatch.

Comment by nfalco79 [ 03/Mar/15 ]

I think the context path should be part of JerseyTest.getBaseURI(). I would expect the same in the ContextRequest.getBaseUri() received in my ContainerRequestFilter test implementation as happen in a real call.

ContextPathTest.java
public class ContextPathTest extends JerseyTest {

	@Path("api/resources")
	public static class ContextPathResource {
		@GET
		@Consumes(MediaType.APPLICATION_JSON)
		@Path("")
		public Response get() {
			return Response.ok().build();
		}
	}

	public static class FilterFactory implements ResourceFilterFactory {
		class InternalFilter implements ResourceFilter, ContainerRequestFilter {

			@Override
			public ContainerRequestFilter getRequestFilter() {
				return this;
			}

			@Override
			public ContainerResponseFilter getResponseFilter() {
				return null;
			}

			@Override
			public ContainerRequest filter(ContainerRequest request) {
				Assert.assertEquals("/test", request.getBaseUri().getPath());
				return request;
			}

		}

		@Override
		public List<com.sun.jersey.spi.container.ResourceFilter> create(AbstractMethod am) {
			return Collections.<ResourceFilter> singletonList(new InternalFilter());
		}

	}

	@Override
	protected AppDescriptor configure() {
		return new WebAppDescriptor.Builder(ContextPathResource.class.getPackage().getName())
			.contextPath("test")
			.initParam("com.sun.jersey.spi.container.ResourceFilters", FilterFactory.class.getName())
			.build();
	}

	@Test
	public void context_path_resource_filter() {
		URI uri = UriBuilder.fromUri(getBaseURI())/*.path("test")*/.path(ContextPathResource.class).build();

		ClientResponse response = client()
				.resource(uri)
				.type(MediaType.APPLICATION_JSON_TYPE)
				.get(ClientResponse.class);

		Assert.assertEquals(Status.OK.getStatusCode(), response.getStatus());
	}
}
Comment by Adam Lindenthal [ 05/Mar/15 ]

Hi nfalco,

moving this issue to backlog, so that we can plan the work on it for one of the future sprints).

Regards,
Adam





[JERSEY-2809] ClientConfig is ignored by InMemoryTestContainerFactory Created: 02/Mar/15  Updated: 06/Mar/15

Status: Open
Project: jersey
Component/s: test-framework
Affects Version/s: 1.18.1
Fix Version/s: 1.x-backlog

Type: Bug Priority: Major
Reporter: nfalco79 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-2810 InMemory JerseyTest ignore contextPat... Open

 Description   

Using InMemory jersey test framework the ClientConfig passed in configure method to the

WebAppDescriptor.Builder().clientConfig(cc)

is not used to configure the client that

JerseyTest.client()

returns.
I'm not be able to configure POJO feature so an exception was thrown by client.

com.sun.jersey.api.client.ClientHandlerException: A message body writer for Java class com.example.MyBean, and Java type class com.example.MyBean, and MIME media type application/json was not found


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

Hi, thanks for reporting.
I will put this to backlog,right next to the other issue you created
I linked them together, even though technically it is a different problem, but in the same code, so I guess those two could be fixed at once.

Regards,
Adam





[JERSEY-2808] Nested objected not marshaled when enabled EntityFilteringFeature Created: 27/Feb/15  Updated: 10/Mar/15

Status: Reopened
Project: jersey
Component/s: extensions, media
Affects Version/s: 2.10, 2.16
Fix Version/s: backlog

Type: Bug Priority: Major
Reporter: rkorn Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: entity-filtering
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Glassfish 4.1, Jersey 2.10.4 (and 2.16.0)


Attachments: Zip Archive 2808-entity-filtering.zip     Zip Archive jerseyEntityFilteringNestingIssue-master.zip    

 Description   

I guest, I've hit a bug with my question on StackOverflow - http://stackoverflow.com/questions/28762909/marshall-nested-objects-with-jersey-using-entityfilter-feature

I have deep nested objects in my domain model (> Level 2) and after enabling EntityFilteringFeature the nested objects dont get marshaled in my json reponse (no matter if using Jackson or Moxy).
Extending the examples at https://github.com/jersey/jersey/tree/master/examples/entity-filtering to contain some deep nested objects should show the issue.



 Comments   
Comment by Adam Lindenthal [ 09/Mar/15 ]

Hi rkorn,

I tried to adjust the entity filtering example as you suggested, but do not see any unexpected behaviour.
Everything seems to be correctly marshalled and sent to the output as it should be.

Please find the attached file which contains the changed and added files to the mentioned entity filtering example and try the /users and /users?detailed=true URIs.

I will close the issue as invalid for now. If you can adjust the example, so that it reproduces the issue, please feel free to ask for reopening. In that case a standalone minimal reproducer test case would be very appreciated.

Regards,
Adam

Comment by PJC23 [ 10/Mar/15 ]

Hello I am actually experiencing this same issue with my domain model. I have edited the example to show the issue, as it is it has entity filtering disabled and will nest objects 4 levels deep. Once you uncomment the feature and turn it on you will lose the last child and the json will only be marshaled for 3 of the 4 levels. It does not appear that I have rights to add an attachment to this issue, if you give me rights I will attach the file.

Comment by Adam Lindenthal [ 10/Mar/15 ]

Hi, thanks for providing an additional info.
Unfortunately I cannot assign you the upload permission, that's a global java.net jira set-up out of our scope.
Thera are basically two ways - send it to me via email or put on github and paste a link.

Thanks,
Adam

Comment by PJC23 [ 10/Mar/15 ]

Here is the link to the modified example on GitHub, https://github.com/pjcahill/jerseyEntityFilteringNestingIssue

Comment by Adam Lindenthal [ 10/Mar/15 ]

Thanks, attached as jerseyEntityFilteringNestingIssue-master.zip. I will delete my originally attached file, so that it does not confuse anybody.
Reopening the issue and moving to backlog, so that work on it can be planned into some of the future sprints.

Regards,
Adam





[JERSEY-2807] Glassfish / Jersey throws NPE on startup of versioned app Created: 26/Feb/15  Updated: 27/Feb/15  Resolved: 27/Feb/15

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

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

GlassFish


Issue Links:
Duplicate
duplicates JERSEY-2626 Glassfish / Jersey throws NPE on star... Resolved
Tags: version

 Description   

Any GlassFish versioned applications fail on startup.

Here is the original (and seems-to-have forgotten) JIRA issue

https://java.net/jira/browse/JERSEY-2626



 Comments   
Comment by Adam Lindenthal [ 27/Feb/15 ]

Hi Iprimak,

the other issue you opened is still in backlog. Backlog does not mean the issue is closed and won't be revisited, basically every issue ends up there for some time. It is a pool from where we plan the future work based on various priorities.
As far as I understand, this is a 100% duplicate of the other issue.

If you want to remind or ask status, please use the original one.
This one is going to be closed now.

Regards,
Adam





[JERSEY-2806] Jackson serialization exception is sent in response Created: 26/Feb/15  Updated: 02/Mar/15  Resolved: 02/Mar/15

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

Type: Bug Priority: Major
Reporter: jstrom Assignee: Michal Gajdos
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

I have a WriterInterceptor which wraps all my JSON responses in a "base response container". During development of this feature I had an issue with Jackson throwing a JsonMappingException. For some reason, this was written to the output stream.

Feb 26, 2015 9:39:20 AM org.glassfish.jersey.test.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer <init>
INFO: Creating InMemoryTestContainer configured at the base URI /api/
Feb 26, 2015 9:39:20 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 1 * Sending client request on thread main
1 > GET /api/test/jsonGenericList

Feb 26, 2015 9:39:20 AM org.glassfish.jersey.filter.LoggingFilter log
INFO: 2 * Client response received on thread main
2 < 400
2 < Content-Length: 208
2 < Content-Type: text/plain
Incompatible types: declared root type ([collection type; class java.util.List, contains [simple type, class com.example.jersey.test.api.TestResource$Pojo]]) vs com.example.jersey.server.api.ApiResponseRoot

Similar response was observed in regular Jersey container.

The actual exception was due to my resource method returning a value which used generics, and my interceptor did not call ctx.setGenericType(), which caused the above exception. Note that this is not what this issue is about.

The issue is rather that the error goes out to the client, and with status 400 instead of 500. In this case, it doesn't tell too much, but in other cases the information leakage may be worse. IMO a 500 with empty response, and the exception logged, would be more appropriate.

This particular error is thrown in com.fasterxml.jackson.databind.SerializerProvider.java. While googling the error, I noticed similar problems in older Jersey versions: JERSEY-2325. However, here it seems to be a stack trace and not sent as response?

I do not have a complete test case, but here are the important parts:

Response interceptor
@Priority(JerseyPriorities.POST_ENTITY_CODER)
public class ApiResponseInterceptor implements WriterInterceptor {
	@Override
	public void aroundWriteTo(WriterInterceptorContext ctx) throws IOException, WebApplicationException {

		MediaType mt = ctx.getMediaType();
		if(mt.equals(MediaType.APPLICATION_JSON_TYPE)) {
			Object entity = ctx.getEntity();
			ApiResponseRoot root = new ApiResponseRoot(entity);
			ctx.setEntity(root);
			// uncomment this removes the "exception"
			//ctx.setGenericType(ApiResponseRoot.class);
		}
		ctx.proceed();
	}
}
Simplified response wrapper
public final class ApiResponseRoot {
	@JsonInclude(value = JsonInclude.Include.NON_NULL)
	public final Object result;
	public ApiResponseRoot(Object result) {
		this.result = result;
	}
}
Resource which returns a Generics-type
@Path("test")
public class TestResource {
	public static class Pojo {
		public long id = 1;
		public String name = "Test";
	}

	@GET
	@Path("jsonGenericList")
	@Produces("application/json")
	public List<Pojo> jsonGenericList(){
		return Arrays.asList(new Pojo(), new Pojo());
	}
}


 Comments   
Comment by jstrom [ 26/Feb/15 ]

The JacksonFeature installs these:

            // add the default Jackson exception mappers
            context.register(JsonParseExceptionMapper.class);
            context.register(JsonMappingExceptionMapper.class);

Those are the ones responsible for the rendered exception.

Based on their javadocs, I would say they are more made for handling JSON data coming on the request-side, rather than response:

Implementation of ExceptionMapper to send down a "400 Bad Request" in the event unparsable JSON is received.

It makes sense when incoming JSON cannot be mapped, but when outgoing JSON fails to render, I would say it's 500 Internal Server Error, rather than 400 Bad request.

Comment by Michal Gajdos [ 02/Mar/15 ]

Interesting problem and I agree it should be 500. However I don't think this is a problem in Jersey (or any other JAX-RS implementation for that matter). I think this should be fixed in Jackson (so all JAX-RS implementations can profit from that). And the fix in Jackson would require to update the JsonMappingException so that the mapper can definitely decide whether the response should be 400 or 500. Now even if we decided to not register that handler and write our own for JsonMappingException we couldn't do it because of the fact that the exception is not specific enough about the response we should throw.

Comment by Michal Gajdos [ 02/Mar/15 ]

I am going to close this issue (won't fix) but feel free to comment (I'll watch it) or reopen it if you still think it's a problem in Jersey.

Comment by Michal Gajdos [ 02/Mar/15 ]

There is a workaround. If you don't want those mappers don't register JacksonFeature from Jersey but register JacksonJaxbJsonProvider from Jackson directly.





[JERSEY-2805] Allow JerseyTest to create client with non-default ClientBuilder Created: 26/Feb/15  Updated: 18/Mar/15  Resolved: 18/Mar/15

Status: Resolved
Project: jersey
Component/s: test-framework
Affects Version/s: None
Fix Version/s: 2.18

Type: Improvement Priority: Major
Reporter: raybirk Assignee: Jakub Podlesak
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Currently, private Client getClient(ClientConfig) always use the default ClientBuilder to create new client. Although we get some flexibility by passing in a clientConfig, not everything can be done through it. For example, it is easier to use HTTPS by using a ClientBuilder with its SslContext customized. Therefore, it would be great to have a way to specify a ClientBuilder to use.



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

Hi Raybirk,

so if I understand it correctly, all you basically need is the getClient(ClientConfig) method to be proctected, so that you can extend JerseyTest, make your own test base using your customized ClientBuilder?

But could you please describe the use case a bit more? Do you need to create new clients from your custom builder?
Couldn't you just create one configured client and use multiple {{WebTarget}}s of it?

Regards,
Adam

Comment by raybirk [ 05/Mar/15 ]

Hi Adam,

Yes, making getClient(ClientConfig) protected would work. My use case is to test against a server with HTTPS with external container wrapper. I would do this to get the client:

client = ClientBuilder.newBuilder().sslContext(sslContext).hostnameVerifier(hostnameVerifier).build();

I think we cannot change WebTarget to use HTTPS but I may be wrong.

Thanks,
RayBirk

Comment by Adam Lindenthal [ 06/Mar/15 ]

Hi Ray,
thanks for clarification.
Sure, you are right, that you cannot define ssl context on a WebTarget instance. But if you have the client defined as in your previous comment, does something prevent you from calling client.target() repeatedly (for more requests)? If you have configured the ClientBuilder, you should get the Client and all the targets configured correctly for https. Or am I missing some part of your use case that I didn't consider?
Sorry for asking so much, but I just want to be sure there is a real need that would justify changing the access level to methods that have been private for quite a while.

Regards,
Adam

Comment by raybirk [ 06/Mar/15 ]

Hi Adam,

It seems to be fine to call client.target() repeatedly, as long as the SSL context is still valid.

Can you elaborate on configuring ClientBuilder? A simple example would be appreciated.

Thanks,
RayBirk

Comment by Jakub Podlesak [ 17/Mar/15 ]

Agreed. Both setter and getter should be available for overriding. Unfortunately, I do not see any reasonable workaround for your use-case at the moment.

Comment by raybirk [ 18/Mar/15 ]

That's okay. I hope some others would benefit from the change.

Comment by Jakub Podlesak [ 18/Mar/15 ]

Fixed in the master branch. Should be available in 2.18 snapshot soonish.





[JERSEY-2804] Deadlock in Apache HTTP client for basic non-preemptive authentication Created: 25/Feb/15  Updated: 24/Mar/15

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

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

Linux ubuntu 13.10, tomcat 7.0.57, jdk 1.7.0_71 64 bit


Attachments: Zip Archive jersey-non-preemptive-auth.zip    

 Description