Dans le répertoire JRE-9/lib
(au moins sous Windows), il existe un nouveau fichier appelé modules
dont la taille est d’environ 107 Mo. Est-il possible d'extraire ce fichier ou peut-être de lister les modules Java qu'il contient?
Je peux voir qu'un nouvel outil appelé jmod
est disponible à jdk-9/bin/jmod.exe
, mais c'est pour lire les fichiers .jmod
qui se trouvent à jdk-9/jmods
et il ne peut pas lire le fichier modules
.
Le fichier modules
est un fichier conteneur. C'est interne au JDK et le format n'est pas documenté (il peut changer à tout moment). À des fins de dépannage, l'outil jimage
du répertoire bin peut être utilisé pour répertorier ou extraire le contenu.
Les ressources d'exécution sont gérées de manière rétro-compatible. Par exemple. quand tu as fait
URL url = Object.class.getResource("Object.class");
System.out.println(url);
dans le passé, on obtenait généralement quelque chose comme
jar:file:/path-to-jre/lib/rt.jar!/Java/lang/Object.class
Exécuter la même chose sous Java 9 vous donnera
jrt:/Java.base/Java/lang/Object.class
au lieu. Dans les deux cas, vous pouvez ouvrir une FileSystem
pour inspecter les autres ressources disponibles (depuis Java 7). Alors que la ZipFileSystem
devait d'abord être créée via FileSystems.newFileSystem
, le système de fichiers de Java 9 est même déjà ouvert à l'utilisation:
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?).");
}
}
Si vous utilisez un JRE différent de celui que vous souhaitez inspecter, vous devez d'abord charger manuellement l'implémentation du système de fichiers appropriée, mais cela ouvre la possibilité d'inspecter une installation Java 9, même à partir d'un JRE Java 8:
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();
}
}
}
Une fois que vous avez un système de fichiers (ou une Path
dans celui-ci), vous pouvez utiliser toutes les fonctions standard de, par exemple. Files
pour inspecter ou extraire/copier les données, bien que le terme approprié soit «stocker un fichier de classe équivalent» dans un système de fichiers différent, car la représentation de l'image d'exécution ne doit pas nécessairement être un fichier de classe. .
Le fichier modules
est censé être un fichier unique (non destiné à être extrait nulle part) qui contient une représentation binaire de tous les modules présents dans le JDK dans un format non documenté, susceptible de modification. Vous pouvez lister les modules qu’il contient avec Java --list-modules
.
Initialement, le fichier modules
contient chaque module et double le côté du JDK, mais une fois que vous "réduisez" votre JDK à l'aide de l'utilitaire jlink
, le fichier modules
devient plus petit (en supposant que votre programme contienne un sous-ensemble des modules fournis. avec le JDK). Pour plus d'informations sur jlink
, voir ici: http://openjdk.Java.net/jeps/282
Vous pouvez lister les modules via Java --list-modules
Vous pouvez utiliser libjimage pour lire ce fichier.