zoukankan      html  css  js  c++  java
  • Java9系列第三篇-同一个Jar支持多JDK版本运行

    我计划在后续的一段时间内,写一系列关于java 9的文章,虽然java 9 不像Java 8或者Java 11那样的核心java版本,但是还是有很多的特性值得关注。期待您能关注我,我将把java 9 写成一系列的文章,大概十篇左右。

    本文内容:在Java 9增强了JAR多版本字节码文件格式的支持,同一个Jar包可以包含多个Java版本的class文件。使用这个功能,我们可以将应用程序/库升级到新的Java版本,而不必强迫用户升级到相同的Java版本。

    一、基本使用方法

    多版本的字节码发行jar包,需要在其MANIFEST.MF中做以下的声明:

    Multi-Release: true
    

    在jar包的META-INF/versions文件目录里面可以包含多个版本的class文件,编译结果目录结构如下:

    jar root
      - A.class
      - B.class
      - META-INF
         - versions
            - 9
               - A.class
    

    假设上文中的根目录是使用java 8 或之前版本编译的字节码文件A.calss。META-INF/versions/9/ 是使用java 9 编写的java代码的编译结果A.class。

    • 如果jar包是在JDK 8的运行时环境下运行,将使用根目录下面的class文件进行程序运行。
    • 如果jar包是在JDK 9的运行时环境下运行,将使用META-INF/versions/9/ 下面的class文件进行程序运行。

    假设未来这个项目升级JDK 10,决定在A.java中使用Java 10的一些新特性,可以单独针对A.class进行语法升级,并将编译结果a.class放置在META-INF/versions/10/ 下面

    jar root
      - A.class
      - B.class
      - META-INF
         - versions
            - 9
               - A.class
            - 10
               - A.class
    

    现在,上面的jar包含了可以以三种Java版本运行的字节码文件,A.class兼容JDK 8、9、10。

    二、真实的例子

    java 8代码

    下面的类文件代码我们让它运行在Java 8的环境下

    package com.example;
    
    public class IOUtil {
      public static String convertToString(InputStream inputStream) throws IOException {
          System.out.println("IOUtil 使用java 8 版本");
          Scanner scanner = new Scanner(inputStream, "UTF-8");
          String str = scanner.useDelimiter("\A").next();
          scanner.close();
          return str;
      }
    }
    

    增加一个Main.java的应用程序入口文件,调用IOUtil.convertToString方法将InputStream转换成String。

    package com.example;
    
    public class Main {
      public static void main(String[] args) throws IOException {
              InputStream inputStream = new ByteArrayInputStream("测试字符串".getBytes());
              String result = IOUtil.convertToString(inputStream);
              System.out.println(result);
          }
    }
    

    Java 9代码

    在Java 9 发布之后,我们决定使用Java 9 的新的语法重写IOUtil.convertToString方法。

    package com.example;
    
    public class IOUtil {
      public static String convertToString(InputStream inputStream) throws IOException {
          System.out.println("IOUtil 使用java 9 版本");
          try (inputStream) {  //Java9版本的增强try-with-resources
              String str = new String(inputStream.readAllBytes());
              return str;
          }
      }
    }
    

    如上的代码所示,我们使用了Java 9的两个新特性带有inputStream引用的try-with-resource块和新的InputStream.readAllBytes()方法。

    编译

    将Java8 、Java9的IOUtil.java代码分别在JDK8、JDK9的版本下分别编译成class字节码文件,并将class文件按照如下的目录结构打成保存,并打jar包。(先按java8版本打成jar包,然后修改MANIFEST.MF文件,添加java 9字节码class文件即可)

    D:multi-release-jar-examplemy-lib-jar>tree /A /F
    +---com
    |   ---example
    |           IOUtil.class
    |           Main.class
    |           
    ---META-INF
        |   MANIFEST.MF
        |   
        ---versions
            ---9
                ---com
                    ---example
                            IOUtil.class
                            
    
    

    运行 Main class

    在JDK 9的环境下运行这个jar包

    D:multi-release-jar-example>java -cp my-lib.jar com.example.Main
    IOUtil 使用java 9 版本
    测试字符串
    

    在JDK 8的环境下运行这个jar包

    D:multi-release-jar-example>C:jdk1.8.0_151injava -cp my-lib.jar com.example.Main
    IOUtil 使用java 8 版本
    测试字符串
    

    欢迎关注我的博客,里面有很多精品合集

    • 本文转载注明出处(必须带连接,不能只转文字):字母哥博客

    觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。

  • 相关阅读:
    java web项目打包.war格式
    version 1.4.2-04 of the jvm is not suitable for thi
    Sugarcrm Email Integration
    sharepoint 2010 masterpage中必须的Content PlaceHolder
    微信开放平台
    Plan for caching and performance in SharePoint Server 2013
    使用自定义任务审批字段创建 SharePoint 顺序工作流
    Technical diagrams for SharePoint 2013
    To get TaskID's Integer ID value from the GUID in SharePoint workflow
    how to get sharepoint lookup value
  • 原文地址:https://www.cnblogs.com/zimug/p/13824215.html
Copyright © 2011-2022 走看看