Java 11 Migration

This post is about my small findings on issues while migrating from Java 8 to Java 11.
The project I am working is based on maven and use apache httpcomponents v4.5 for getting the HttpClient class.

So, in order to migrate to Java 11:

1. First and foremost thing is to check your maven for the dependencies latest version and it is better to upgrade these dependencies. I tried this in maven to automatically update the existing dependencies present in your maven repo:
       
          mvn versions:display-dependency-updates
       


2. Update the maven compiler version to 3.8.0 or higher
       

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                    <release>11</release>
                </configuration>
            </plugin>

       


3. If your project's pom file is creating multiple jar files then, you will have manifest files. So for each manifest file, the classpath mentioned should be given in multiple lines, else it will throw error because of the constraint added that each line should be not more than 72 bytes.

4. Proceeding from above point 3, each jars should be differentiated with classifiers.
       
         <classifier>client</classifier>
       

5. Java 11 comes with its own java.net.http.HttpClient and you have to change the existing way of creating HttpClient.
Example to create HttpClient  in Java 11 with SSL certificate which allows connection over  TLSv1.2 only:
       
        import javax.net.ssl.KeyManagerFactory;
        import javax.net.ssl.SSLContext;
        import javax.net.ssl.TrustManagerFactory;
        import java.io.FileInputStream;
        import java.io.IOException;
        import java.net.http.HttpClient;
        import java.security.*;
        import java.security.cert.Certificate;
        import java.security.cert.CertificateException;
        import java.security.cert.CertificateFactory;
        import java.util.Collection;

        public static HttpClient getHttpClient() {
        try {
            String sslCertPath = "certificates.crt";

            KeyStore kstrust = KeyStore.getInstance("JKS");
            kstrust.load( null, "password".toCharArray());

            Collection col_crt1 = CertificateFactory.getInstance("X509")
                    .generateCertificates(new FileInputStream(sslCertPath));

            Certificate crt1 = (Certificate) col_crt1.iterator().next();

            kstrust.setCertificateEntry("cert1", crt1);
            KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");
            kmf.init(kstrust, "password".toCharArray());

            TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
            tmf.init(kstrust);
// Enable the comment if you want to accept all certificates
//            TrustManager[] trustAllCerts = new TrustManager[]{
//                    new X509TrustManager() {
//                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
//                            return null;
//                        }
//                        public void checkClientTrusted(
//                                java.security.cert.X509Certificate[] certs, String authType) {
//                        }
//                        public void checkServerTrusted(
//                                java.security.cert.X509Certificate[] certs, String authType) {
//                        }
//                    }
//            };



            System.getProperties().setProperty("jdk.internal.httpclient.disableHostnameVerification", Boolean.TRUE.toString());

            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
            sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
            HttpClient client1 = java.net.http.HttpClient.newBuilder().sslContext(sslContext).build();
            return client1;
        } catch (KeyStoreException | IOException | NoSuchAlgorithmException | 
                           CertificateException | KeyManagementException | UnrecoverableKeyException kex) {
            kex.printStackTrace();
        }
        return null;
    }

       
One more thing here is, if you want to make your application compatible with Java 8 and Java11, then better to use third party library. I am using apache.httpcomponents v5.0. 
v5.0 is important, because earlier versions are not compatible with Java11. 
v5.0 is a complete revamp from previous versions.

6. The casting to URLClassLoader will give error if you are using System.getClassLoader(). To overcome the error you can follow below code
       
  URLClassLoader loader = new URLClassLoader(new URL[]{url})
       
There are other changes too in Java 11, but resolving these does the job for me and I was able to migrate to Java 11.

Hope this will help you. Also, please comment down your suggestions.

Comments