2

I've been trying to perform a POST from a jersey client but continue to run into the following exception:

Caused by: java.lang.IllegalStateException: Already connected at sun.net.www.protocol.http.HttpURLConnection.setRequestProperty(HttpURLConnection.java:3071) at sun.net.www.protocol.https.HttpsURLConnectionImpl.setRequestProperty(HttpsURLConnectionImpl.java:325) at org.glassfish.jersey.client.internal.HttpUrlConnector.setOutboundHeaders(HttpUrlConnector.java:424) at org.glassfish.jersey.client.internal.HttpUrlConnector.lambda$_apply$0(HttpUrlConnector.java:381) at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:195) at org.glassfish.jersey.message.internal.CommittingOutputStream.commitStream(CommittingOutputStream.java:189) at org.glassfish.jersey.message.internal.CommittingOutputStream.commit(CommittingOutputStream.java:257) at org.glassfish.jersey.message.internal.OutboundMessageContext.commitStream(OutboundMessageContext.java:825) at org.glassfish.jersey.client.ClientRequest.doWriteEntity(ClientRequest.java:553) at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:498) at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:384) at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:282) at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:278) ... 63 more

I've tried a ton of answers and solutions in SO with no luck.

Going crazy here, please help!

public class JerseyWithSSL {

    public static javax.ws.rs.client.Client getRESTClient() {

        try {
            TrustManager[] trustMgr = new TrustManager[]{new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted1(X509Certificate[] certs,
                        String authType) {
                }

                public void checkServerTrusted1(X509Certificate[] certs,
                        String authType) {
                }

                @Override
                public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                        throws CertificateException {
                    // TODO Auto-generated method stub

                }

                @Override
                public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                        throws CertificateException {
                    // TODO Auto-generated method stub

                }
            }};

            SSLContext context = SSLContext.getInstance("SSL");
            context.init(null, trustMgr, null);

            javax.ws.rs.client.Client client = ClientBuilder.newBuilder().sslContext(context)
                    .hostnameVerifier(new HostnameVerifier() {

                        @Override
                        public boolean verify(String arg0, SSLSession arg1) {
                            // TODO Auto-generated method stub
                            return true;
                        }
                    }).build();

            return client;
        } catch (NoSuchAlgorithmException | KeyManagementException ex) {
            Logger.getLogger(JerseyWithSSL.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }
}

Code which uses the above class (exception thrown here):

    // send notification to all subscriptors for event: attendee.create
    if (!subscriptions.isEmpty()) {

        try {
            Client client = JerseyWithSSL.getRESTClient();

            for (Subscription sub : subscriptions) {

                System.out.println("Subscription: \n" + sub.getEventName() + "\n" + sub.getTargetUrl());

                Response resp = client.target(sub.getTargetUrl())
                        .request(MediaType.APPLICATION_JSON)
                        .post(Entity.entity(newAttdee, MediaType.APPLICATION_JSON));

                System.out.println("Status: " + resp.getStatus());
                System.out.println(resp.getEntity().toString());

                resp.close();
            }
        } catch (Exception ex) {
            Logger.getLogger(AttendeeResource.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

Adding pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>ON24Hooks</groupId>
    <artifactId>ON24_Zapier_Hooks</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>ON24_Zapier_Hooks</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.20</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.5</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.connectors</groupId>
            <artifactId>jersey-apache-connector</artifactId>
            <version>2.16</version>
            <type>jar</type>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>7.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>
Esteban Rincon
  • 2,040
  • 3
  • 27
  • 44

3 Answers3

1

The IllegalStateException: Already connected is probably masking a SSLHandshakeException, as described in the issue #3000 (previously referenced as JERSEY-2728).

According to the release notes, it was fixed in Jersey 2.23. I would upgrade Jersey to the most recent version though.

cassiomolin
  • 124,154
  • 35
  • 280
  • 359
0

I spent some time to figure it out how it is been done in Jersey 2.x. Thanks to Jersey Migration Guide to help me out. Below is code snippet for how client is build in Jersey 2.x for HTTPS call

 public Client getRESTClient() {

      TrustManager[] trustMgr= new TrustManager[] { new X509TrustManager() {
       public X509Certificate[] getAcceptedIssuers() {
        return null;
       }

       public void checkClientTrusted1(X509Certificate[] certs,
         String authType) {
       }

       public void checkServerTrusted1(X509Certificate[] certs,
         String authType) {
       }

       @Override
       public void checkClientTrusted(X509Certificate[] arg0, String arg1)
         throws CertificateException {
        // TODO Auto-generated method stub

       }

       @Override
       public void checkServerTrusted(X509Certificate[] arg0, String arg1)
         throws CertificateException {
        // TODO Auto-generated method stub

       }
      } };

      SSLContext context = SSLContext.getInstance("TLS");
      context.init(null, trustMgr, null);


      Client client = ClientBuilder.newBuilder().sslContext(context)
        .hostnameVerifier(new HostnameVerifier() {

         @Override
         public boolean verify(String arg0, SSLSession arg1) {
          // TODO Auto-generated method stub
          return true;
         }
        }).build();

      return client;

     }

Just exception can be occur at any point while it may be SSL certificate validation also which can also current socket layer connection to validate SSLContext.Please debug out try catch block thoroughly also make the execution of your http request with other client also as well from Java Url URLCONNECTION

this_is_om_vm
  • 608
  • 5
  • 23
0

The IllegalStateException: Already connected is probably masking a SSLHandshakeException. The way to verify/debug this is to use the following JVM flags:

-Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack

This will cause the JVM to print out a whole bunch of debug information regarding SSL and will show the SSL exception if there is one.

mbluke
  • 115
  • 1
  • 9