< prev index next >

test/jdk/java/lang/module/ModuleReader/ModuleReaderTest.java

Print this page
*** 1,7 ***
  /*
!  * Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.
--- 1,7 ---
  /*
!  * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.

*** 19,11 ***
   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   */
  
! /**
   * @test
   * @bug 8142968 8300228
   * @library /test/lib
   * @modules java.base/jdk.internal.module
   *          jdk.compiler
--- 19,11 ---
   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   */
  
! /*
   * @test
   * @bug 8142968 8300228
   * @library /test/lib
   * @modules java.base/jdk.internal.module
   *          jdk.compiler

*** 43,10 ***
--- 43,11 ---
  import java.lang.module.ModuleReference;
  import java.net.URI;
  import java.net.URL;
  import java.net.URLConnection;
  import java.nio.ByteBuffer;
+ import java.nio.charset.StandardCharsets;
  import java.nio.file.Files;
  import java.nio.file.Path;
  import java.nio.file.Paths;
  import java.util.HashSet;
  import java.util.List;

*** 54,10 ***
--- 55,11 ---
  import java.util.Set;
  import java.util.spi.ToolProvider;
  import java.util.stream.Stream;
  
  import jdk.internal.module.ModulePath;
+ import jdk.test.lib.Utils;
  import jdk.test.lib.compiler.CompilerUtils;
  import jdk.test.lib.util.JarUtils;
  import org.junit.jupiter.api.BeforeAll;
  import org.junit.jupiter.api.Test;
  

*** 66,15 ***
  import static org.junit.jupiter.api.Assertions.assertFalse;
  import static org.junit.jupiter.api.Assertions.assertThrows;
  import static org.junit.jupiter.api.Assertions.assertTrue;
  
  public class ModuleReaderTest {
!     private static final String TEST_SRC = System.getProperty("test.src");
- 
-     private static final Path USER_DIR   = Paths.get(System.getProperty("user.dir"));
-     private static final Path SRC_DIR    = Paths.get(TEST_SRC, "src");
-     private static final Path MODS_DIR   = Paths.get("mods");
  
      // the module name of the base module
      private static final String BASE_MODULE = "java.base";
  
      // the module name of the test module
--- 68,11 ---
  import static org.junit.jupiter.api.Assertions.assertFalse;
  import static org.junit.jupiter.api.Assertions.assertThrows;
  import static org.junit.jupiter.api.Assertions.assertTrue;
  
  public class ModuleReaderTest {
!     private static final Path MODS_DIR = Paths.get("mods");
  
      // the module name of the base module
      private static final String BASE_MODULE = "java.base";
  
      // the module name of the test module

*** 117,14 ***
          "C:java",
          "C:\\java",
          "java\\lang\\Object.class"
      };
  
!     // resources in test module (can't use module-info.class as a test
      // resource as it will be modified by the jmod tool)
      private static final String[] TEST_RESOURCES = {
!         "p/Main.class"
      };
  
      // (directory) resources that may be in the test module
      private static final String[] MAYBE_TEST_RESOURCES = {
          "p",
--- 115,15 ---
          "C:java",
          "C:\\java",
          "java\\lang\\Object.class"
      };
  
!     // Resources in test module (can't use module-info.class as a test
      // resource as it will be modified by the jmod tool)
      private static final String[] TEST_RESOURCES = {
!             "p/Main.class",
+             "p/test.txt"
      };
  
      // (directory) resources that may be in the test module
      private static final String[] MAYBE_TEST_RESOURCES = {
          "p",

*** 151,15 ***
          "C:\\p",
          "p\\Main.class"
      };
  
      @BeforeAll
!     public static void compileTestModule() throws Exception {
!         // javac -d mods/$TESTMODULE src/$TESTMODULE/**
!         boolean compiled = CompilerUtils.compile(SRC_DIR.resolve(TEST_MODULE),
!                                                  MODS_DIR.resolve(TEST_MODULE));
          assertTrue(compiled, "test module did not compile");
      }
  
      /**
       * Test ModuleReader with module in runtime image.
       */
--- 150,38 ---
          "C:\\p",
          "p\\Main.class"
      };
  
      @BeforeAll
!     public static void compileTestModules() throws Exception {
!         // Write simplest module-info class.
!         Path srcDir = Path.of("src", TEST_MODULE);
!         Files.createDirectories(srcDir);
+         Files.writeString(srcDir.resolve("module-info.java"), "module " + TEST_MODULE + " {}");
+ 
+         // Write and compile test class "p.Main".
+         Path pkgPath = Path.of("p");
+         Path javaSrc = srcDir.resolve(pkgPath).resolve("Main.java");
+         Files.createDirectories(javaSrc.getParent());
+         Files.writeString(javaSrc,
+                 """
+                 package p;
+                 public class Main {
+                     public static void main(String[] args) { }
+                 }
+                 """);
+ 
+         // javac -d <outDir> <srcDir>/**
+         Path outDir = MODS_DIR.resolve(TEST_MODULE);
+         boolean compiled = CompilerUtils.compile(srcDir, outDir);
          assertTrue(compiled, "test module did not compile");
+ 
+         // Add two versions of a resource for preview mode testing.
+         Files.writeString(outDir.resolve(pkgPath).resolve("test.txt"), "Normal Version");
+         Path previewDir = outDir.resolve("META-INF", "preview").resolve(pkgPath);
+         Files.createDirectories(previewDir);
+         Files.writeString(previewDir.resolve("test.txt"), "Preview Version");
      }
  
      /**
       * Test ModuleReader with module in runtime image.
       */

*** 220,35 ***
      @Test
      public void testExplodedModule() throws IOException {
          test(MODS_DIR);
      }
  
      /**
       * Test ModuleReader with module in modular JAR.
       */
      @Test
      public void testModularJar() throws IOException {
!         Path dir = Files.createTempDirectory(USER_DIR, "mlib");
  
          // jar cf mlib/${TESTMODULE}.jar -C mods .
!         JarUtils.createJarFile(dir.resolve("m.jar"),
!                                MODS_DIR.resolve(TEST_MODULE));
  
          test(dir);
      }
  
      /**
       * Test ModuleReader with module in a JMOD file.
       */
      @Test
      public void testJMod() throws IOException {
!         Path dir = Files.createTempDirectory(USER_DIR, "mlib");
  
          // jmod create --class-path mods/${TESTMODULE}  mlib/${TESTMODULE}.jmod
          String cp = MODS_DIR.resolve(TEST_MODULE).toString();
!         String jmod = dir.resolve("m.jmod").toString();
!         String[] args = { "create", "--class-path", cp, jmod };
          ToolProvider jmodTool = ToolProvider.findFirst("jmod")
                  .orElseThrow(() ->
                          new RuntimeException("jmod tool not found")
                  );
          assertEquals(0, jmodTool.run(System.out, System.out, args), "jmod tool failed");
--- 242,79 ---
      @Test
      public void testExplodedModule() throws IOException {
          test(MODS_DIR);
      }
  
+     /**
+      * Test equivalent of the system ModuleReader with preview mode. This differs
+      * in behavior to other "exploded modules" because it supports preview mode.
+      * It also hides preview resources when preview mode is enabled.
+      *
+      * <p>Note: When preview mode is not enabled, preview resources are visible
+      * via their un-mapped path. This is not the same behavior as things like
+      * the JRT filesystem or non-exploded module readers, in which preview paths
+      * are always hidden.
+      */
+     @Test
+     public void testExplodedSystemModule() throws IOException {
+         ModuleFinder normalFinder = ModulePath.of(/* modulePatcher */ null, /* previewMode */ false, MODS_DIR);
+         try (ModuleReader reader = normalFinder.find(TEST_MODULE).get().open()) {
+             assertEquals("Normal Version", assertUtf8Resource(reader, "p/test.txt"));
+             // This file is not visible in an exploded image when using JRT filesystem.
+             assertEquals("Preview Version", assertUtf8Resource(reader, "META-INF/preview/p/test.txt"));
+         }
+         ModuleFinder previewFinder = ModulePath.of(/* modulePatcher */ null, /* previewMode */ true, MODS_DIR);
+         try (ModuleReader reader = previewFinder.find(TEST_MODULE).get().open()) {
+             assertEquals("Preview Version", assertUtf8Resource(reader, "p/test.txt"));
+             assertFalse(reader.find("META-INF/preview/p/test.txt").isPresent(), "unexpected preview resource");
+         }
+     }
+ 
+     private static String assertUtf8Resource(ModuleReader reader, String name) throws IOException {
+         // Check the resource can be found with the expected URI.
+         Optional<URI> uri = reader.find(name);
+         assertTrue(uri.isPresent(), "resource not found: " + name);
+         assertTrue(uri.get().getPath().endsWith(name), "unexpected path: " + uri.get());
+ 
+         // Open and read all resource bytes.
+         Optional<InputStream> is = reader.open(name);
+         assertTrue(is.isPresent(), "resource cannot be opened: " + name);
+         byte[] bytes = is.get().readAllBytes();
+ 
+         // Cross-check that read() returns the same bytes as open().
+         Optional<ByteBuffer> buffer = reader.read(name);
+         assertTrue(buffer.isPresent(), "resource cannot be read: " + name);
+         assertArrayEquals(buffer.get().array(), bytes, "resource bytes differ: " + name);
+         // Return the string of the UTF-8 bytes for checking the actual content.
+         return new String(bytes, StandardCharsets.UTF_8);
+     }
+ 
      /**
       * Test ModuleReader with module in modular JAR.
       */
      @Test
      public void testModularJar() throws IOException {
!         Path dir = Utils.createTempDirectory("mlib");
  
          // jar cf mlib/${TESTMODULE}.jar -C mods .
!         JarUtils.createJarFile(dir.resolve(TEST_MODULE + ".jar"),
!                 MODS_DIR.resolve(TEST_MODULE));
  
          test(dir);
      }
  
      /**
       * Test ModuleReader with module in a JMOD file.
       */
      @Test
      public void testJMod() throws IOException {
!         Path dir = Utils.createTempDirectory("mlib");
  
          // jmod create --class-path mods/${TESTMODULE}  mlib/${TESTMODULE}.jmod
          String cp = MODS_DIR.resolve(TEST_MODULE).toString();
!         String jmod = dir.resolve(TEST_MODULE + ".jmod").toString();
!         String[] args = {"create", "--class-path", cp, jmod};
          ToolProvider jmodTool = ToolProvider.findFirst("jmod")
                  .orElseThrow(() ->
                          new RuntimeException("jmod tool not found")
                  );
          assertEquals(0, jmodTool.run(System.out, System.out, args), "jmod tool failed");
< prev index next >