• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 6805
  • Last Modified:

java.io.IOException: HTTPS hostname wrong: should be <blah blah>

Hi There,
I Have a url which i run in IE and its returns results as expected.  However, when i try and open a connection via my java class running over the command line it returns the following error:

java.io.IOException: HTTPS hostname wrong:  should be <blah blah>
I believe it may be related to certificates, how can i fix this error?

For reference here's my code thus far:

package peewee;

import java.io.InputStream;
import java.net.URL;
import java.lang.StringBuffer;

public class Test {

      public static void main(String[] args) {
            
            
            final String HOST       = "https://blah";
            final String SUFFIX       = "blah";
                        
            try {
                   URL url = new URL(HOST + SUFFIX);
                   javax.net.ssl.HttpsURLConnection conn = null;
                             conn = (javax.net.ssl.HttpsURLConnection) url.openConnection();
                             conn.setRequestMethod("GET");

              InputStream input             = conn.getInputStream();
                StringBuffer buff             = new StringBuffer();
                  
                  int c;
                  while ( ( c = input.read() ) != -1 ) {
                        buff.append((char) c);
                  }
                  System.out.println("total " + buff.toString() );
                  
            }
            catch ( Exception e ) {
                  System.out.println("error:" + e.toString());
                  
            }
            
      }
}

0
Peewee
Asked:
Peewee
  • 4
  • 4
  • 4
  • +2
1 Solution
 
TimYatesCommented:
>> java.io.IOException: HTTPS hostname wrong:  should be <blah blah>

what is the actual error?  I assume it doesn't actually say "blah blah"

Does the host do a dynamic redirection to the actual host machine?

What line throws the exception?
0
 
bloodredsunCommented:
From a quick dig around I found this as a solution:

This happens if the hostname in the URL does not match the hostname in the certificate. There is an easy workaround to this: you have to define your own hostname verifier and configure the HttpsURLConnection with it:

HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
    public boolean verify(String urlHostname, String certHostname) {
        return true;
    }
});

0
 
neonlinesCommented:
I think u r getting java.io.IOException in the following line only
>> InputStream input           = conn.getInputStream();

Just copy ur HOST + SUFFIX and put a browser and check it's a correct URL or not

If it is correct URL, then u ll not get IO Exception

But, any way change the line

>>  URL url = new URL(HOST + SUFFIX);

as

com.sun.net.ssl.internal.ssl.Provider.install();
java.security.Security.insertProviderAt(new com.sun.net.ssl.internal.ssl.Provider(), 1);

URL url = new URL(null, HOST + SUFFIX, new com.sun.net.ssl.internal.www.protocol.https.Handler());


0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
neonlinesCommented:
Change the line

>>  conn.setRequestMethod("GET");

as

conn.setRequestMethod("POST");
0
 
neonlinesCommented:
I Changed ur Test program and check this

I hope, u added ur certificate in cacerts already

import java.io.InputStream;
import java.net.URL;
import java.lang.StringBuffer;

public class Test {

     public static void main(String[] args) {
         
         
          final String HOST       = "https://blah";
          final String SUFFIX      = "blah";
                   
          try {
            com.sun.net.ssl.internal.ssl.Provider.install();
            java.security.Security.insertProviderAt(new com.sun.net.ssl.internal.ssl.Provider(), 1);

            URL url = new URL(null, HOST + SUFFIX, new com.sun.net.ssl.internal.www.protocol.https.Handler());
                 javax.net.ssl.HttpsURLConnection conn = null;
                 conn = (javax.net.ssl.HttpsURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setFollowRedirects(true);

            
             BufferedReader in           = new BufferedReader(new  InputStreamReader(conn.getInputStream()));
               StringBuffer buff           = new StringBuffer();
               
            String inputLine = null;
            while ((inputLine = in.readLine()) != null)
            {
                  System.out.println(inputLine);
            }
               
          }
          catch ( Exception e ) {
               System.out.println("error:" + e.toString());
               
          }
         
     }
}

0
 
aozarovCommented:
Peewee,
Your program worked fine for me as is (replacing https://blahblah with www.google.com)
BTW, did mean to have SUFFIX   as "/blah" ? do you want https://blah/blah or https://blahblah ?
Older JVM have some certificates in their certificate tree expired (So you might want to upgrade it or your JVM)
If you are accessing a site that self signed or uses a certificate which is not part of your certificate tree then you
will see exception similar to:
error:javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.sec
urity.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
0
 
PeeweeAuthor Commented:
Hi neon lines,
i thought i'd respond to you first as you've put the most detail and effort into your posting.  Thanks for your code, I've tried to use it, but ecplise reports the following error:

java.lang.ClassCastException: com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOldImpl

I've ammended it slightly to:
import java.net.URL;
import java.lang.StringBuffer;
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class EETest {

     public static void main(String[] args) {
         
         
          final String HOST       = "http://www.google.com";
          final String SUFFIX     = "";
                   
          try {
          com.sun.net.ssl.internal.ssl.Provider.install();
          java.security.Security.insertProviderAt(new com.sun.net.ssl.internal.ssl.Provider(), 1);

          URL url = new URL(null, HOST + SUFFIX, new com.sun.net.ssl.internal.www.protocol.https.Handler());
                 javax.net.ssl.HttpsURLConnection conn = null;
                 conn = (javax.net.ssl.HttpsURLConnection) url.openConnection();
          conn.setDoInput(true);
          conn.setDoOutput(true);
          conn.setUseCaches(false);
          conn.setRequestMethod("POST");
          conn.setFollowRedirects(true);

         
          BufferedReader in           = new BufferedReader(new  InputStreamReader(conn.getInputStream()));
          StringBuffer buff           = new StringBuffer();
               
          String inputLine = null;
          while ((inputLine = in.readLine()) != null)
          {
               System.out.println(inputLine);
          }
               
          }
          catch ( Exception e ) {
               System.out.println("error:" + e.toString());
               
          }
         
     }
}

 
0
 
PeeweeAuthor Commented:
Hi bloodredsun,
thanks for your comment, i've seen postings on the web talking about your approach, however i'm unable to get the code to successfully integrate into mine, can you ammend my code with your insert..

thanks pg
0
 
aozarovCommented:
I think this is what bloodredsun meant:

// add after conn = (javax.net.ssl.HttpsURLConnection) url.openConnection();

conn.setDefaultHostnameVerifier(new javax.net.ssl.HostnameVerifier() {
    public boolean verify(String urlHostname, String certHostname) {
        return true;
    }

    public boolean verify(String urlHostname, javax.net.ssl.SSLSession session) {
        return true;
    }
});
..

But I don't think it should help in your case
0
 
neonlinesCommented:
>> but ecplise reports the following error:

>> java.lang.ClassCastException:

Yes, I used javax.net.ssl.HttpsURLConnection (which is Java own package) and ur ecplise needs a class as
com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnection

Change the corresponding Object usage with respect to ecplise

I think u ll face some more problem bcaz of ecplise. Bcaz ecplise also having it's own defined class for HTTPS and Java also having it's and I think u included both in ur classpath

U remove either ecplise packages or Java include packages and try

I think u have to do a lot




0
 
PeeweeAuthor Commented:
bloodredsun & aozarov,
i have added the code you suggested but i am still getting the same error.

any thoughts
0
 
aozarovCommented:
What is the error you are getting?
0
 
PeeweeAuthor Commented:
hi aozarov,
its the same error:

java.io.IOException: HTTPS hostname wrong:  should be <blah blah>
0
 
aozarovCommented:
You can try the solution provided in this thread (the last one): http://forum.java.sun.com/thread.jspa?threadID=521779&tstart=75
which also adds its own TrustManager
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 4
  • 4
  • 4
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now