Path: blob/master/test/hotspot/jtreg/runtime/HiddenClasses/HiddenGetModule.java
40942 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @summary Test that a hidden class has the same module as its lookup class.26* @library /test/lib27* @modules jdk.compiler28* @compile pkg/HasNamedModule.java29* @run main/othervm HiddenGetModule30*/3132import java.io.ByteArrayOutputStream;33import java.io.File;34import java.io.FileInputStream;35import java.lang.invoke.MethodType;36import java.lang.invoke.MethodHandles;37import java.lang.invoke.MethodHandles.Lookup;38import static java.lang.invoke.MethodHandles.Lookup.ClassOption.*;39import java.io.IOException;40import java.lang.ModuleLayer;41import java.lang.module.Configuration;42import java.lang.module.ModuleDescriptor;43import java.lang.module.ModuleFinder;44import java.lang.module.ModuleReader;45import java.lang.module.ModuleReference;46import java.lang.reflect.Method;47import java.net.URI;48import java.nio.ByteBuffer;49import java.nio.channels.FileChannel;50import java.util.HashMap;51import java.util.HashSet;52import java.util.Map;53import java.util.Objects;54import java.util.Optional;55import java.util.Set;5657import jdk.test.lib.compiler.InMemoryJavaCompiler;5859public class HiddenGetModule {6061static byte unnamedKlassbuf[] = InMemoryJavaCompiler.compile("TestClass",62"public class TestClass { " +63" public static void concat(String one, String two) throws Throwable { " +64" System.out.println(one + two);" +65" } } ");6667public static ModuleFinder finderOf(ModuleDescriptor... descriptors) {6869// Create a ModuleReference for each module70Map<String, ModuleReference> namesToReference = new HashMap<>();7172for (ModuleDescriptor descriptor : descriptors) {73String name = descriptor.name();7475URI uri = URI.create("module:/" + name);7677ModuleReference mref = new ModuleReference(descriptor, uri) {78@Override79public ModuleReader open() {80throw new UnsupportedOperationException();81}82};8384namesToReference.put(name, mref);85}8687return new ModuleFinder() {88@Override89public Optional<ModuleReference> find(String name) {90Objects.requireNonNull(name);91return Optional.ofNullable(namesToReference.get(name));92}93@Override94public Set<ModuleReference> findAll() {95return new HashSet<>(namesToReference.values());96}97};98}99100public static void main(String[] args) throws Throwable {101102// Test unnamed module.103Lookup lookup = MethodHandles.lookup();104Class<?> cl = lookup.defineHiddenClass(unnamedKlassbuf, false, NESTMATE).lookupClass();105if (cl.getModule() != HiddenGetModule.class.getModule()) {106throw new RuntimeException("hidden class and lookup class have different unnamed modules");107}108109// Test named module.110MyClassLoader myClassLoader = new MyClassLoader();111112// Define a module named HiddenModule containing package pkg.113ModuleDescriptor descriptor = ModuleDescriptor.newModule("HiddenModule")114.requires("java.base")115.exports("pkg")116.build();117118// Set up a ModuleFinder containing the module for this layer.119ModuleFinder finder = finderOf(descriptor);120121// Resolves "HiddenModule"122Configuration cf = ModuleLayer.boot()123.configuration()124.resolve(finder, ModuleFinder.of(), Set.of("HiddenModule"));125126// map module to class loader127Map<String, ClassLoader> map = new HashMap<>();128map.put("HiddenModule", myClassLoader);129130// Create layer that contains HiddenModule131ModuleLayer layer = ModuleLayer.boot().defineModules(cf, map::get);132133byte klassbuf[] = InMemoryJavaCompiler.compile("pkg.TestClass",134"package pkg; " +135"public class TestClass { " +136" public static void concat(String one, String two) throws Throwable { " +137" System.out.println(one + two);" +138" } } ");139140// Load the class and call the method that defines a hidden class and compares modules.141Class<?>c = Class.forName("pkg.HasNamedModule", true, myClassLoader);142if (c.getClassLoader() != myClassLoader) {143throw new RuntimeException("pkg.HasNamedModule defined by wrong classloader: " + c.getClassLoader());144}145Method m = c.getDeclaredMethod("compareModules", byte[].class);146m.invoke(null, klassbuf);147}148149150public static class MyClassLoader extends ClassLoader {151152public static final String CLASS_NAME = "HasNamedModule";153154static ByteBuffer readClassFile(String name) {155File f = new File(System.getProperty("test.classes", "."), name);156try (FileInputStream fin = new FileInputStream(f);157FileChannel fc = fin.getChannel()) {158return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());159} catch (IOException e) {160throw new RuntimeException("Can't open file: " + name + ", " + e.toString());161}162}163164protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {165Class<?> c;166if (!name.contains(CLASS_NAME)) {167c = super.loadClass(name, resolve);168} else {169// should not delegate to the system class loader170c = findClass(name);171if (resolve) {172resolveClass(c);173}174}175return c;176}177178protected Class<?> findClass(String name) throws ClassNotFoundException {179if (!name.contains(CLASS_NAME)) {180throw new ClassNotFoundException("Unexpected class: " + name);181}182return defineClass(name, readClassFile(name.replace(".", File.separator) + ".class"), null);183}184} /* MyClassLoader */185186}187188189