2017-09-27 43 views
8

JRE-9/lib目錄(至少在Windows上),有一個名爲modules的新文件,其大小約爲107 MB。是否有可能提取該文件或可能列出其中的Java模塊?如何提取文件jre-9/lib/modules?

我可以看到一個新的工具,稱爲jmod可在jdk-9/bin/jmod.exe,但這是用於讀取位於jdk-9/jmods.jmod文件,它無法讀取該文件modules

回答

6

modules文件是一個容器文件。它在JDK內部,格式沒有記錄(可能隨時更改)。出於故障排除的目的,bin目錄中的jimage工具可用於列出或提取內容。

+1

「jimage」的任何鏈接以及如何使用它都很有用。 – nullpointer

+4

jimage沒有文檔頁面,但'jimage --help'應該有足夠的空間。請注意,該工具包含在故障排除/支持用途中,這不是大多數開發人員所需要的。 –

+0

爲我工作。只是做了'$ jimage提取$ JAVA_HOME/lib/modules'和poof! – 0xbe5077ed

3

modules文件意味着是單個文件(並不意味着任何地方提取的)列出模塊,其包含在一個undocument格式的所有存在於JDK模塊的二進制表示這可能會發生變化。您可以使用java --list-modules列出它包含的模塊。

最初modules文件將包含每一個模塊,基本上翻倍的JDK自身的一面,但一旦你使用jlink工具「再壓縮」你的JDK,在modules文件將變得更小(假設你的程序中包含一個子集隨JDK一起提供的模塊)。欲瞭解更多有關jlink的信息,請參閱:http://openjdk.java.net/jeps/282

3

運行時資源以向後兼容的方式處理。例如。當你過去那樣

URL url = Object.class.getResource("Object.class"); 
System.out.println(url); 

,你通常得到的東西像

jar:file:/path-to-jre/lib/rt.jar!/java/lang/Object.class 

的Java 9下運行相同會給你

jrt:/java.base/java/lang/Object.class 

代替。無論哪種情況,您都可以打開一個FileSystem來檢查其他可用資源(自Java 7以來)。雖然ZipFileSystem必須通過FileSystems.newFileSystem第一,爪哇9的文件系統創建甚至已經開放使用:

private static void readMyOwnJRE() throws IOException { 
    try { 
     Path p = Paths.get(URI.create("jrt:/modules")); 
     System.out.println("My own JRE's modules:"); 
     Files.list(p).forEach(System.out::println); 
     System.out.println(); 
    } catch(FileSystemNotFoundException ex) { 
     System.out.println("Could not read my modules (perhaps not Java 9?)."); 
    } 
} 

如果您在不同的JRE不是要檢查一個運行時,你必須加載相應的文件系統實現手動第一,但這個開放,甚至從Java 8 JRE檢查一個Java 9的安裝可能性:

public static void readOtherJRE(Path pathToJRE) throws IOException { 
    Path p = pathToJRE.resolve("lib").resolve("jrt-fs.jar"); 
    if(Files.exists(p)) { 
     try(URLClassLoader loader = new URLClassLoader(new URL[]{ p.toUri().toURL() }); 
      FileSystem fs = FileSystems.newFileSystem(URI.create("jrt:/"), 
                 Collections.emptyMap(), 
                 loader)) { 
      System.out.println("Modules of "+pathToJRE); 
      Files.list(fs.getPath("/modules")).forEach(System.out::println); 
      System.out.println(); 
     } 
    } 
} 

一旦你有一個文件系統(或Path進去),Y您可以使用所有標準功能,例如Files檢查或提取/複製數據,雖然正確的術語是「將等同的類文件」存儲在不同的文件系統中,因爲運行時映像的表示根本不必是類文件。

0

您可以使用jdk.internal.jimage.ImageReader來讀取此文件。