1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  * @test
  26  * @library ../../lib
  27  * @modules java.base/jdk.internal.module
  28  *          jdk.jlink/jdk.tools.jmod
  29  * @build ModuleReaderTest CompilerUtils JarUtils
  30  * @run testng ModuleReaderTest
  31  * @summary Basic tests for java.lang.module.ModuleReader
  32  */
  33 
  34 import java.io.File;
  35 import java.io.IOException;
  36 import java.io.InputStream;
  37 import java.lang.module.ModuleFinder;
  38 import java.lang.module.ModuleReader;
  39 import java.lang.module.ModuleReference;
  40 import java.net.URI;
  41 import java.net.URL;
  42 import java.net.URLConnection;
  43 import java.nio.ByteBuffer;
  44 import java.nio.file.Files;
  45 import java.nio.file.Path;
  46 import java.nio.file.Paths;
  47 import java.util.Arrays;
  48 import java.util.Optional;
  49 
  50 import jdk.internal.module.ConfigurableModuleFinder;
  51 import jdk.internal.module.ConfigurableModuleFinder.Phase;
  52 
  53 import org.testng.annotations.BeforeTest;
  54 import org.testng.annotations.Test;
  55 import static org.testng.Assert.*;
  56 
  57 @Test
  58 public class ModuleReaderTest {
  59 
  60     private static final String TEST_SRC = System.getProperty("test.src");
  61 
  62     private static final Path USER_DIR   = Paths.get(System.getProperty("user.dir"));
  63     private static final Path SRC_DIR    = Paths.get(TEST_SRC, "src");
  64     private static final Path MODS_DIR   = Paths.get("mods");
  65 
  66     // the module name of the test module
  67     private static final String TEST_MODULE = "m";
  68 
  69     // resources in test module (can't use module-info.class as a test
  70     // resource as it will be modified by the jmod tool)
  71     private static final String[] RESOURCES = {
  72         "p/Main.class"
  73     };
  74 
  75     // a resource that is not in the test module
  76     private static final String NOT_A_RESOURCE = "NotAResource";
  77 
  78 
  79     @BeforeTest
  80     public void compileTestModule() throws Exception {
  81 
  82         // javac -d mods/$TESTMODULE src/$TESTMODULE/**
  83         boolean compiled
  84             = CompilerUtils.compile(SRC_DIR.resolve(TEST_MODULE),
  85                                     MODS_DIR.resolve(TEST_MODULE));
  86         assertTrue(compiled, "test module did not compile");
  87     }
  88 
  89 
  90     /**
  91      * Test exploded module
  92      */
  93     public void testExplodedModule() throws Exception {
  94         test(MODS_DIR);
  95     }
  96 
  97 
  98     /**
  99      * Test modular JAR
 100      */
 101     public void testModularJar() throws Exception {
 102         Path dir = Files.createTempDirectory(USER_DIR, "mlib");
 103 
 104         // jar cf mlib/${TESTMODULE}.jar -C mods .
 105         JarUtils.createJarFile(dir.resolve("m.jar"),
 106                                MODS_DIR.resolve(TEST_MODULE));
 107 
 108         test(dir);
 109     }
 110 
 111 
 112     /**
 113      * Test JMOD
 114      */
 115     public void testJMod() throws Exception {
 116         Path dir = Files.createTempDirectory(USER_DIR, "mlib");
 117 
 118         // jmod --create --class-path mods/${TESTMODULE}  mlib/${TESTMODULE}.jmod
 119         String cp = MODS_DIR.resolve(TEST_MODULE).toString();
 120         String jmod = dir.resolve("m.jmod").toString();
 121         String[] args = { "--create", "--class-path", cp, jmod };
 122         jdk.tools.jmod.JmodTask task = new jdk.tools.jmod.JmodTask();
 123         assertEquals(task.run(args), 0);
 124 
 125         test(dir);
 126     }
 127 
 128 
 129     /**
 130      * The test module is found on the given module path. Open a ModuleReader
 131      * to the test module and test the reader.
 132      */
 133     void test(Path mp) throws Exception {
 134 
 135         ModuleFinder finder = ModuleFinder.of(mp);
 136         if (finder instanceof ConfigurableModuleFinder) {
 137             // need ModuleFinder to be in the phase to find JMOD files
 138             ((ConfigurableModuleFinder)finder).configurePhase(Phase.LINK_TIME);
 139         }
 140 
 141         ModuleReference mref = finder.find(TEST_MODULE).get();
 142         ModuleReader reader = mref.open();
 143 
 144         try (reader) {
 145 
 146             // test each of the known resources in the module
 147             for (String name : RESOURCES) {
 148                 byte[] expectedBytes
 149                     = Files.readAllBytes(MODS_DIR
 150                         .resolve(TEST_MODULE)
 151                         .resolve(name.replace('/', File.separatorChar)));
 152 
 153                 testFind(reader, name, expectedBytes);
 154                 testOpen(reader, name, expectedBytes);
 155                 testRead(reader, name, expectedBytes);
 156             }
 157 
 158             // test "not found"
 159             assertFalse(reader.open(NOT_A_RESOURCE).isPresent());
 160             assertFalse(reader.read(NOT_A_RESOURCE).isPresent());
 161 
 162             // test nulls
 163             try {
 164                 reader.find(null);
 165                 assertTrue(false);
 166             } catch (NullPointerException expected) { }
 167 
 168             try {
 169                 reader.open(null);
 170                 assertTrue(false);
 171             } catch (NullPointerException expected) { }
 172 
 173             try {
 174                 reader.read(null);
 175                 assertTrue(false);
 176             } catch (NullPointerException expected) { }
 177 
 178             // should release(null) throw NPE?
 179 
 180         }
 181 
 182         // test closed ModuleReader
 183         try {
 184             reader.open(RESOURCES[0]);
 185             assertTrue(false);
 186         } catch (IOException expected) { }
 187 
 188 
 189         try {
 190             reader.read(RESOURCES[0]);
 191             assertTrue(false);
 192         } catch (IOException expected) { }
 193     }
 194 
 195     /**
 196      * Test ModuleReader#find
 197      */
 198     void testFind(ModuleReader reader, String name, byte[] expectedBytes)
 199         throws Exception
 200     {
 201         Optional<URI> ouri = reader.find(name);
 202         assertTrue(ouri.isPresent());
 203 
 204         URL url = ouri.get().toURL();
 205         if (!url.getProtocol().equalsIgnoreCase("jmod")) {
 206             URLConnection uc = url.openConnection();
 207             uc.setUseCaches(false);
 208             try (InputStream in = uc.getInputStream()) {
 209                 byte[] bytes = in.readAllBytes();
 210                 assertTrue(Arrays.equals(bytes, expectedBytes));
 211             }
 212         }
 213     }
 214 
 215     /**
 216      * Test ModuleReader#open
 217      */
 218     void testOpen(ModuleReader reader, String name, byte[] expectedBytes)
 219         throws Exception
 220     {
 221         Optional<InputStream> oin = reader.open(name);
 222         assertTrue(oin.isPresent());
 223 
 224         InputStream in = oin.get();
 225         try (in) {
 226             byte[] bytes = in.readAllBytes();
 227             assertTrue(Arrays.equals(bytes, expectedBytes));
 228         }
 229     }
 230 
 231     /**
 232      * Test ModuleReader#read
 233      */
 234     void testRead(ModuleReader reader, String name, byte[] expectedBytes)
 235         throws Exception
 236     {
 237         Optional<ByteBuffer> obb = reader.read(name);
 238         assertTrue(obb.isPresent());
 239 
 240         ByteBuffer bb = obb.get();
 241         try {
 242             int rem = bb.remaining();
 243             assertTrue(rem == expectedBytes.length);
 244             byte[] bytes = new byte[rem];
 245             bb.get(bytes);
 246             assertTrue(Arrays.equals(bytes, expectedBytes));
 247         } finally {
 248             reader.release(bb);
 249         }
 250     }
 251 
 252 }