6

Have recently updated application from Oracle Java 9 to AdoptJDk 11.0.6 and I am now seeing errors of the form this code:

 public static String convertWikidataUrl(String wikidataUrl)
    {
        String qPage  = wikidataUrl.substring(wikidataUrl.lastIndexOf('/') + 1);
        String apiUrl = WIKIDATA_IMAGE_API_URL + qPage;
        try
        {
            URL url = new URL(apiUrl);
            HttpURLConnection uc = (HttpURLConnection) url.openConnection();
            int responseCode = uc.getResponseCode();
            if (responseCode != HttpURLConnection.HTTP_OK)
            {
                MainWindow.logger.severe(":ResponseCode:"+responseCode);

            }

            //Everything ok so continue
            BufferedInputStream bis = new BufferedInputStream(uc.getInputStream());
            JAXBContext jc = getWikidataInitialContext();
            Unmarshaller um = jc.createUnmarshaller();
            Api api = (Api) um.unmarshal(bis);
            if(api.getClaims()!=null
                    && api.getClaims().getProperty()!=null
                    && api.getClaims().getProperty().getClaim()!=null
                    && api.getClaims().getProperty().getClaim().getMainsnak()!=null
                    && api.getClaims().getProperty().getClaim().getMainsnak().getDatavalue()!=null)
            {
                return api.getClaims().getProperty().getClaim().getMainsnak().getDatavalue().getValue();
            }
            else
            {
                return null;
            }
        }
        catch (JAXBException e)
        {
            MainWindow.logger.log(Level.SEVERE, e.getMessage(), e);
        }
        catch (MalformedURLException mue)
        {
            MainWindow.logger.log(Level.SEVERE, mue.getMessage(), mue);
        }
        catch (Exception ex)
        {
            MainWindow.logger.log(Level.SEVERE, ex.getMessage(), ex);
        }
        return null;
    }

fails with:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:131)
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:307)
    at java.base/sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:291)
    at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:180)
    at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:164)
    at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1151)
    at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1062)
    at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:402)
    at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:567)
    at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1515)
    at java.base/java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:527)
    at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:334)
    at com.jthink.songkong.analyse.musicbrainz.WikipediaImage.convertWikipediaUrl(WikipediaImage.java:49)
    at com.jthink.songkong.analyse.musicbrainz.ArtistArtwork.findArtistImageLink(ArtistArtwork.java:54)
    at com.jthink.songkong.analyse.musicbrainz.ArtistArtworkOnlineLookup.call(ArtistArtworkOnlineLookup.java:63)
    at com.jthink.songkong.analyse.musicbrainz.ArtistArtworkOnlineLookup.call(ArtistArtworkOnlineLookup.java:26)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)

The problem has been seen on Windows but may occur on other platforms as well

The error is definitently due to changing JRE but I don't know if the issue is moving from Java 9 to 11, or moving from Oracle to AdoptJdk, how can I resolve this ?

Update

  1. The problem does not occur on MacOS using 11.0.6
  2. On Windows Updating from 11.0.6 to 11.0.7 had no effect
  3. On Windows adding -Dhttps.protocols=TLSv1.1,TLSv1.2 (to disabled TLS1.3 support) fixes the issue.
  4. Possibly version of this bug https://bugs.openjdk.java.net/browse/JDK-8206923
Paul Taylor
  • 13,411
  • 42
  • 184
  • 351
  • Why have you listed the code for method `convertWikidataUrl()` when the stack trace is showing the error is in method `WikipediaImage.convertWikipediaUrl()`? – skomisa May 02 '20 at 05:16
  • @skomisa oversight on my part, but the code is essentially the same. – Paul Taylor May 03 '20 at 08:17
  • I am just trying to find out what is the bug introduced in Java11 that has caused this problem. – Paul Taylor May 03 '20 at 08:17
  • 1
    Since JDK-8235249 is shown as a duplicate of the bug you cite (JDK-8206923), and that bug is fixed in JDK-15, you could try a beta version of JDK 15 to see if your issue is resolved. I realize that may not be a feasible or acceptable approach... it's just a suggestion. – skomisa May 03 '20 at 17:28
  • I've written an answer explaining the issue and what to do. The bugs you linked are about client-authentication failing in TLS1.3, because TLS1.3 is changing how client certificate authentication works compared to TLS1.2. You should specify if you use client authentication? I guess not from the question. – user5994461 May 06 '20 at 17:06
  • Im just looking up a https page in wikipedia, no authentication – Paul Taylor May 07 '20 at 09:57

1 Answers1

10

The client can't open a connection to the server because they likely don't support the same TLS versions or settings.

Try to start the application with:

  • -Dhttps.protocols=TLSv1.2 (default in Java 8)
  • -Dhttps.protocols=TLSv1.3 (default in Java 11)
  • -Dhttps.protocols=TLSv1.0

TLSv1.2 (2008) is the currently supported version of TLS that is deployed everywhere and supported by everything. That's the safe default and what to force for things to just work.

TLSv1.3 (2018) is the upcoming version. It's being rolled across everywhere slowly (web servers, applications, load balancers, CDN, etc...). The transition should be seamless but it's not quite. Of course no software can be perfect on the first try and there are some bugs and incompatibilities coming up. The JDK 11 introduces TLSv1.3 and tries to use it by default, which didn't go well given the error, the workaround is to force using TLSv1.2 instead. (update for 2021: TLS 1.3 has been adopted by browsers and major middleware over the past year or two, it's quite likely to come up when you upgrade software/infrastructure)

There are tricky edge cases if you rely on TLS for client certificate authentication, often used in enterprise systems dealing with highly sensitive information, like banking APIs. TLS 1.3 changed the way client authentication happens, so both client and server software may need a fix to be able to operate under the newer version. HTTP/2 breaks client authentication by design, a RFC is pending to agree on a solution, in the meantime use HTTP/1.1.

TLSv1.0 (1999) is an obsolete version that is prohibited from usage and removed in latest library versions (OpenSSL 1.1.x, JDK 11, etc...). It's still possible to encounter it as of 2020 if you work around legacy enterprise java apps that ain't been maintained for years (anything involving Java 6 or 7 is a red flag). These really need to be upgraded.

user5994461
  • 5,301
  • 1
  • 36
  • 57
  • Thanks for the detail, helpful. So code is connecting to wikipedia so it seems wikipedia does support v1.3, Java thinks it does but is buggy. If I disable v1.3 when I start java then it works implying that Java now tries to use 1.2 instead which wikipedia also support so it works. I suppose it could be that the v1.3 is buggy on wikipedia rather than Java but seems less likely. – Paul Taylor May 07 '20 at 09:55
  • I've had to apply this fix for other SSL issues as well. You can specify more than one version, like this: `-Djdk.tls.client.protocols=TLSv1.1,TLSv1.2,TLSv1.3` – mrcrag Feb 22 '23 at 19:40
  • I run latest Jenkins server on Ubuntu22.04 with jdk11 Added JAVA_ARGS="-Dhttps.protocols=TLSv1.2" in /etc/default/jenkins and restart server. Still get the same error. – Mike Aug 31 '23 at 00:31