public static Module ModuleObject(String name, ClassLoader loader, String[] pkgs) throws Throwable { Set<String> pkg_set = new HashSet<>(); if (pkgs != null) { for (String pkg: pkgs) { pkg_set.add(pkg.replace('/', '.')); } } else { pkg_set = Collections.emptySet(); } ModuleDescriptor descriptor = new ModuleDescriptor.Builder(name).conceals(pkg_set).build(); URI uri = URI.create("module:/" + name); return java.lang.reflect.ModuleHelper.newModule(loader, descriptor); }
public static void main(String[] args) { System.out.println(Test.class + " ..."); for (String arg: args) { System.out.println(arg); } ClassLoader scl = ClassLoader.getSystemClassLoader(); ClassLoader cl1 = Test.class.getClassLoader(); Module testModule = Test.class.getModule(); ClassLoader cl2 = Layer.boot().findLoader(testModule.getName()); if (cl1 != scl) throw new RuntimeException("Not loaded by system class loader"); if (cl2 != scl) throw new RuntimeException("Not associated with system class loader"); }
@Override public Logger getLogger(String name, Module caller) { // We should check the permission to obey the API contract, but // what happens if we don't? // This is the main difference compared with what we test in // java/lang/System/LoggerFinder/BaseLoggerFinderTest SecurityManager sm = System.getSecurityManager(); if (sm != null && doChecks) { sm.checkPermission(SimplePolicy.LOGGERFINDER_PERMISSION); } final boolean before = allowAll.get().getAndSet(true); final ClassLoader callerLoader; try { callerLoader = caller.getClassLoader(); } finally { allowAll.get().set(before); } if (callerLoader == null) { return system.computeIfAbsent(name, (n) -> new LoggerImpl(n)); } else { return user.computeIfAbsent(name, (n) -> new LoggerImpl(n)); } }
public byte[] transform( Module module, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { // The transform testing is triggered by redefine, ignore others if (classBeingRedefined != null) checkInTransformer(MyClassFileTransformer.this); return super.transform( module, className, classBeingRedefined, protectionDomain, classfileBuffer); }
private NamedPackage getNamedPackage(String pn, Module m) { NamedPackage p = packages.get(pn); if (p == null) { p = new NamedPackage(pn, m); NamedPackage value = packages.putIfAbsent(pn, p); if (value != null) { // Package object already be defined for the named package p = value; // if definePackage is called by this class loader to define // a package in a named module, this will return Package // object of the same name. Package object may contain // unexpected information but it does not impact the runtime. // this assertion may be helpful for troubleshooting assert value.module() == m; } } return p; }
public static boolean test(Class<?> c, boolean addExports) { Module self = FieldSetAccessibleTest.class.getModule(); Module target = c.getModule(); String pn = c.getPackage().getName(); boolean exported = self.canRead(target) && target.isExported(pn, self); if (addExports && !exported) { Modules.addExports(target, pn, self); exported = true; } boolean expectException = !exported; classCount.incrementAndGet(); // Call getDeclaredFields() and try to set their accessible flag. testSetFieldsAccessible(c, expectException); // add more tests here... return c == Class.class; }
/** * Finds the module at the given location defined to the boot loader. * The module is either in runtime image or exploded image. * Otherwise this method returns null. */ private static Module findModule(String location) { String mn = null; if (location.startsWith("jrt:/")) { // named module in runtime image ("jrt:/".length() == 5) mn = location.substring(5, location.length()); } else if (location.startsWith("file:/")) { // named module in exploded image Path path = Paths.get(URI.create(location)); Path modulesDir = Paths.get(JAVA_HOME, "modules"); if (path.startsWith(modulesDir)) { mn = path.getFileName().toString(); } } if (mn != null) { // named module from runtime image or exploded module Optional<Module> om = Layer.boot().findModule(mn); if (!om.isPresent()) throw new InternalError(mn + " not in boot layer"); return om.get(); } return null; }
static void testSetFieldsAccessible(Class<?> c, boolean expectException) { for (Field f : c.getDeclaredFields()) { fieldCount.incrementAndGet(); boolean expect = expectException; if ((c == Module.class || c == AccessibleObject.class) && !Modifier.isPublic(f.getModifiers())) { expect = true; } try { f.setAccessible(false); f.setAccessible(true); if (expect) { throw new RuntimeException( String.format("Expected InaccessibleObjectException is not thrown " + "for field %s in class %s%n", f.getName(), c.getName())); } } catch (InaccessibleObjectException expected) { if (!expect) { throw new RuntimeException(expected); } } } }
@Override protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException { checkPackageAccess(name); if (name.startsWith(NASHORN_PKG_PREFIX)) { final StructureLoader sharedCl = context.getSharedLoader(); final Class<?> cl = sharedCl.loadClass(name); if (! structureAccessAdded) { if (cl.getClassLoader() == sharedCl) { structureAccessAdded = true; final Module structModule = sharedCl.getModule(); addModuleExports(structModule, SCRIPTS_PKG, scriptModule); addReadsModule(scriptModule, structModule); } } return cl; } return super.loadClass(name, resolve); }
public static void main(String[] args) { // local resource ResourceBundle.getBundle(TEST_RESOURCE_BUNDLE_NAME, Main.class.getModule()); // resource in another module Module m1 = p1.Bundle.class.getModule(); ResourceBundle rb1 = Bundle.getBundle(M1_RESOURCE_BUNDLE_NAME); ResourceBundle rb2 = ResourceBundle.getBundle(M1_RESOURCE_BUNDLE_NAME, m1); if (rb1 != rb2) { throw new RuntimeException("unexpected resource bundle"); } System.setSecurityManager(new SecurityManager()); // no permission needed for local resource ResourceBundle.getBundle(TEST_RESOURCE_BUNDLE_NAME, Main.class.getModule()); // resource bundle through m1's exported API Bundle.getBundle(M1_RESOURCE_BUNDLE_NAME); try { // fail to get resource bundle in another module ResourceBundle.getBundle(M1_RESOURCE_BUNDLE_NAME, m1); throw new RuntimeException("should deny access"); } catch (SecurityException e) {} }
static Data[] proxiesForExportedTypes() { ClassLoader ld = Main.class.getClassLoader(); Module unnamed = ld.getUnnamedModule(); ClassLoader ld2 = new URLClassLoader(new URL[0], ld); Module unnamed2 = ld2.getUnnamedModule(); return new Data[] { new Data(unnamed, ld, Runnable.class), new Data(unnamed, ld, p.one.I.class), new Data(unnamed, ld, p.one.I.class, p.two.A.class), new Data(unnamed, ld, p.one.I.class, unnamedModuleClass), new Data(unnamed2, ld2, Runnable.class), new Data(unnamed2, ld2, p.one.I.class), new Data(unnamed2, ld2, p.one.I.class, p.two.A.class), new Data(unnamed2, ld2, p.one.I.class, unnamedModuleClass), new Data(unnamed, m1.getClassLoader(), p.one.I.class), new Data(unnamed, m2.getClassLoader(), p.two.A.class), new Data(unnamed, m3.getClassLoader(), p.three.P.class), }; }
@Override public Logger getLogger(String name, Module caller) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(LOGGERFINDER_PERMISSION); } PrivilegedAction<ClassLoader> pa = () -> caller.getClassLoader(); ClassLoader callerLoader = AccessController.doPrivileged(pa); if (callerLoader == null) { return system.computeIfAbsent(name, (n) -> new LoggerImpl(n)); } else { return user.computeIfAbsent(name, (n) -> new LoggerImpl(n)); } }
private boolean generateConstructors(final Constructor<?> ctor) { for (final Class<?> pt : ctor.getParameterTypes()) { if (pt.isPrimitive()) continue; final Module ptMod = pt.getModule(); if (ptMod != null) { accessedModules.add(ptMod); } } if(classOverride) { // Generate a constructor that just delegates to ctor. This is used with class-level overrides, when we want // to create instances without further per-instance overrides. generateDelegatingConstructor(ctor); return false; } // Generate a constructor that delegates to ctor, but takes an additional ScriptObject parameter at the // beginning of its parameter list. generateOverridingConstructor(ctor, false); if (samName == null) { return false; } // If all our abstract methods have a single name, generate an additional constructor, one that takes a // ScriptFunction as its first parameter and assigns it as the implementation for all abstract methods. generateOverridingConstructor(ctor, true); // If the original type only has a single abstract method name, as well as a default ctor, then it can // be automatically converted from JS function. return ctor.getParameterTypes().length == 0; }
@Override public java.lang.System.Logger getLogger(String name, Module caller) { ClassLoader callerLoader = caller.getClassLoader(); if (callerLoader == null) { systemLoggers.putIfAbsent(name, new CustomLogger(name)); return systemLoggers.get(name); } else { applicationLoggers.putIfAbsent(name, new CustomLogger(name)); return applicationLoggers.get(name); } }
private void addExports(String moduleName, String... packageNames) { for (String packageName : packageNames) { try { Layer layer = Layer.boot(); Optional<Module> m = layer.findModule(moduleName); if (!m.isPresent()) throw new Error("module not found: " + moduleName); m.get().addExports(packageName, getClass().getModule()); } catch (Exception e) { throw new Error("failed to add exports for " + moduleName + "/" + packageName); } } }
/** * Get the set of keys from the javac resource bundles. */ Set<String> getResourceKeys() { Module jdk_compiler = Layer.boot().findModule("jdk.compiler").get(); Set<String> results = new TreeSet<String>(); for (String name : new String[]{"javac", "compiler"}) { ResourceBundle b = ResourceBundle.getBundle("com.sun.tools.javac.resources." + name, jdk_compiler); results.addAll(b.keySet()); } return results; }
private static Class<?> loadLoggingClass(String className) { return AccessController.doPrivileged(new PrivilegedAction<>() { @Override public Class<?> run() { Optional<Module> logging = java.lang.reflect.Layer.boot() .findModule("java.logging"); if (logging.isPresent()) { return Class.forName(logging.get(), className); } return null; } }); }
/** * Defines a Package of the given name and module * * This method does not throw IllegalArgumentException. * * @param name package name * @param m module */ Package definePackage(String name, Module m) { if (name.isEmpty() && m.isNamed()) { throw new InternalError("unnamed package in " + m); } // check if Package object is already defined NamedPackage pkg = packages.get(name); if (pkg instanceof Package) return (Package)pkg; return (Package)packages.compute(name, (n, p) -> toPackage(n, p, m)); }
NamedPackage(String pn, Module module) { if (pn.isEmpty() && module.isNamed()) { throw new InternalError("unnamed package in " + module); } this.name = pn.intern(); this.module = module; }
private byte[] transform( ClassLoader loader, Module module, String classname, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer, boolean isRetransformer) { TransformerManager mgr = isRetransformer? mRetransfomableTransformerManager : mTransformerManager; // module is null when not a class load or when loading a class in an // unnamed module and this is the first type to be loaded in the package. if (module == null) { if (classBeingRedefined != null) { module = classBeingRedefined.getModule(); } else { module = (loader == null) ? jdk.internal.loader.BootLoader.getUnnamedModule() : loader.getUnnamedModule(); } } if (mgr == null) { return null; // no manager, no transform } else { return mgr.transform( module, classname, classBeingRedefined, protectionDomain, classfileBuffer); } }
CacheKey(String baseName, Locale locale, ClassLoader loader, Module module) { Objects.requireNonNull(module); this.name = baseName; this.locale = locale; if (loader == null) { this.loaderRef = null; } else { this.loaderRef = new KeyElementReference<>(loader, referenceQueue, this); } this.moduleRef = new KeyElementReference<>(module, referenceQueue, this); this.providers = getServiceLoader(module, baseName); calculateHashCode(); }
@Test public void testDesktopModule() { Module desktop = java.awt.Component.class.getModule(); Module base = Object.class.getModule(); Module xml = javax.xml.XMLConstants.class.getModule(); Module thisModule = BasicModuleTest.class.getModule(); // name assertTrue(desktop.getName().equals("java.desktop")); // descriptor assertTrue(desktop.getDescriptor().exports().stream() .anyMatch(doesExport("java.awt"))); // getClassLoader assertTrue(desktop.getClassLoader() == null); // getLayer assertTrue(desktop.getLayer() == Layer.boot()); // toString assertEquals(desktop.toString(), "module java.desktop"); // getPackages assertTrue(contains(desktop.getPackages(), "java.awt")); assertTrue(contains(desktop.getPackages(), "sun.awt")); // canRead assertTrue(desktop.canRead(base)); assertTrue(desktop.canRead(xml)); // isExported assertTrue(desktop.isExported("java.awt")); assertTrue(desktop.isExported("java.awt", thisModule)); assertFalse(desktop.isExported("java.wombat")); assertFalse(desktop.isExported("java.wombat", thisModule)); }
private void calculateHashCode() { hashCodeCache = name.hashCode() << 3; hashCodeCache ^= locale.hashCode(); ClassLoader loader = getLoader(); if (loader != null) { hashCodeCache ^= loader.hashCode(); } Module module = getModule(); if (module != null) { hashCodeCache ^= module.hashCode(); } }
/** * Create a module layer that contains the given system module. */ static Module loadModuleInChildLayer(String mn) { Optional<ModuleReference> omref = ModuleFinder.ofSystem().find(mn); assertTrue("module " + mn + " not a system module", omref.isPresent()); // create a ModuleFinder that only finds this module ModuleReference mref = omref.get(); ModuleFinder finder = new ModuleFinder() { @Override public Optional<ModuleReference> find(String name) { if (name.equals(mn)) return Optional.of(mref); else return Optional.empty(); } @Override public Set<ModuleReference> findAll() { return Collections.singleton(mref); } }; // create a child configuration and layer with this module Layer bootLayer = Layer.boot(); Configuration cf = bootLayer .configuration() .resolveRequires(finder, ModuleFinder.of(), Set.of(ANOTHER_MODULE)); Layer layer = bootLayer.defineModulesWithOneLoader(cf, null); Optional<Module> om = layer.findModule(mn); assertTrue("module " + mn + " not in child layer", om.isPresent()); return om.get(); }
/** * Creates a java.util.logging.Logger for the given module. * @param name the logger name. * @param module the module for which the logger should be created. * @return a Logger suitable for use in the given module. */ private static java.util.logging.Logger demandJULLoggerFor(final String name, Module module) { final LogManager manager = LogManager.getLogManager(); final SecurityManager sm = System.getSecurityManager(); if (sm == null) { return logManagerAccess.demandLoggerFor(manager, name, module); } else { final PrivilegedAction<java.util.logging.Logger> pa = () -> logManagerAccess.demandLoggerFor(manager, name, module); return AccessController.doPrivileged(pa, null, LOGGING_CONTROL_PERMISSION); } }
/** * Initializes a new instance of this class for locating service providers * via a class loader. * * @throws ServiceConfigurationError * If {@code svc} is not accessible to {@code caller} or that the * caller's module does not declare that it uses the service type. */ private ServiceLoader(Module callerModule, Class<S> svc, ClassLoader cl) { if (VM.isBooted()) { checkModule(callerModule, svc); if (cl == null) { cl = ClassLoader.getSystemClassLoader(); } } else { // if we get here then it means that ServiceLoader is being used // before the VM initialization has completed. At this point then // only code in the java.base should be executing. Module base = Object.class.getModule(); Module svcModule = svc.getModule(); if (callerModule != base || svcModule != base) { fail(svc, "not accessible to " + callerModule + " during VM init"); } // restricted to boot loader during startup cl = null; } this.service = svc; this.layer = null; this.loader = cl; this.acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null; reload(); }
/** * Tests that the given module reads all modules in the boot Layer. */ private void testReadsAllBootModules(Module m) { Layer bootLayer = Layer.boot(); bootLayer.configuration() .modules() .stream() .map(ResolvedModule::name) .map(bootLayer::findModule) .forEach(target -> assertTrue(m.canRead(target.get()))); }
@Override public void setLevel(Logger logger, Level level, Module caller) { PrivilegedAction<Void> pa = () -> { setLevel(logger, PlatformLogger.toPlatformLevel(level), caller); return null; }; AccessController.doPrivileged(pa); }
/** * Exercise Layer.boot() */ public void testBoot() { Layer bootLayer = Layer.boot(); // configuration Configuration cf = bootLayer.configuration(); assertTrue(cf.findModule("java.base").get() .reference() .descriptor() .exports() .stream().anyMatch(e -> (e.source().equals("java.lang") && !e.isQualified()))); // modules Set<Module> modules = bootLayer.modules(); assertTrue(modules.contains(Object.class.getModule())); int count = (int) modules.stream().map(Module::getName).count(); assertEquals(count, modules.size()); // module names are unique // findModule Module base = Object.class.getModule(); assertTrue(bootLayer.findModule("java.base").get() == base); assertTrue(base.getLayer() == bootLayer); // findLoader assertTrue(bootLayer.findLoader("java.base") == null); // parent assertTrue(bootLayer.parent().get() == Layer.empty()); }
static void verifySetup() { Module m = ResourceBundleTest.class.getModule(); System.out.println("Module Name for ResourceBundleTest : " + m.getName()); assertTrue(!m.isNamed()); m = ModuleLoggerAccess.class.getModule(); System.out.println("Module Name for ModuleLoggerAccess : " + m.getName()); assertTrue(m.isNamed()); }
Logger demandSystemLogger(String name, String resourceBundleName, Module module) { // Add a system logger in the system context's namespace final Logger sysLogger = getSystemContext() .demandLogger(name, resourceBundleName, module); // Add the system logger to the LogManager's namespace if not exist // so that there is only one single logger of the given name. // System loggers are visible to applications unless a logger of // the same name has been added. Logger logger; do { // First attempt to call addLogger instead of getLogger // This would avoid potential bug in custom LogManager.getLogger // implementation that adds a logger if does not exist if (addLogger(sysLogger)) { // successfully added the new system logger logger = sysLogger; } else { logger = getLogger(name); } } while (logger == null); // LogManager will set the sysLogger's handlers via LogManager.addLogger method. if (logger != sysLogger && sysLogger.accessCheckedHandlers().length == 0) { // if logger already exists but handlers not set final Logger l = logger; AccessController.doPrivileged(new PrivilegedAction<Void>() { @Override public Void run() { for (Handler hdl : l.accessCheckedHandlers()) { sysLogger.addHandler(hdl); } return null; } }); } return sysLogger; }
public static void premain(String agentArgs, final Instrumentation inst) throws Exception { String s = agentArgs.substring(0, agentArgs.indexOf(".class")); clz = Class.forName(s.replace('/', '.')); InputStream in; Module m = clz.getModule(); if (m != null) { in = m.getResourceAsStream(agentArgs); } else { ClassLoader loader = RedefineClassWithNativeMethodAgent.class.getClassLoader(); in = loader.getResourceAsStream(agentArgs); } if (in == null) { throw new Exception("Cannot find class: " + agentArgs); } byte[] buffer = in.readAllBytes(); new Timer(true).schedule(new TimerTask() { public void run() { try { System.out.println("Instrumenting"); ClassDefinition cld = new ClassDefinition(clz, buffer); inst.redefineClasses(new ClassDefinition[] { cld }); } catch (Exception e) { e.printStackTrace(); } } }, 500); }
private static void testProxyClass(Module module, ClassLoader ld, Class<?>... interfaces) { Class<?> proxyClass = Proxy.getProxyClass(ld, interfaces); assertEquals(proxyClass.getModule(), module); Object proxy = Proxy.newProxyInstance(ld, interfaces, handler); assertEquals(proxy.getClass().getModule(), module); }
/** * Test the permission checks by invoking methods on the given module. * * If {@code allow} is {@code true} then the permission checks should succeed. */ static void test(Module m, String name, boolean allow) throws IOException { // test Module::getClassLoader System.out.format("Test getClassLoader on %s ...%n", m); try { ClassLoader cl = m.getClassLoader(); System.out.println(cl); if (!allow) assertTrue("getClassLoader should have failed", false); } catch (SecurityException e) { System.out.println(e + " thrown"); if (allow) throw e; } // test Module::getResourceAsStream System.out.format("Test getResourceAsStream(\"%s\") on %s ...%n", name, m); try (InputStream in = m.getResourceAsStream(name)) { System.out.println(in); if (allow && (in == null)) assertTrue(name + " not found", false); if (!allow && (in != null)) assertTrue(name + " should not be found", false); } }
/** * Define a new module to the VM. The module has the given set of * concealed packages and is defined to the given class loader. * * The resulting Module is in a larval state in that it does not not read * any other module and does not have any exports. */ public static Module defineModule(ClassLoader loader, String name, Set<String> packages) { ModuleDescriptor descriptor = new ModuleDescriptor.Builder(name).conceals(packages).build(); return JLRMA.defineModule(loader, descriptor, null); }
public static void main(String[] args) throws Exception { Module xml = Layer.boot().findModule("java.xml").get(); Set<String> allServices = new HashSet<>(Arrays.asList(expectedAllServices)); if (!allServices.equals(xml.getDescriptor().uses())) throw new AssertionError("Expect xml module uses: " + allServices + " But actually uses: " + xml.getDescriptor().uses()); long violationCount = Stream.of(args) .map(xmlProviderName -> Layer.boot().findModule(xmlProviderName).get()) .mapToLong( // services provided by the implementation in provider module provider -> provider.getDescriptor().provides().keySet().stream() .filter(serviceName -> { allServices.remove(serviceName); // remove service provided by // customized module from allServices return !belongToModule(serviceName, instantiateXMLService(serviceName), provider); }).count()) .sum(); // the remaining services should be provided by the default implementation violationCount += allServices.stream() .filter(serviceName -> !belongToModule(serviceName, instantiateXMLService(serviceName), xml)) .count(); if (violationCount > 0) throw new AssertionError(violationCount + " services are not provided by expected module"); }
static Logger getLogger(String name, Module caller) { boolean old = allowAccess.get().get(); allowAccess.get().set(true); try { return jdk.internal.logger.LazyLoggers.getLogger(name, caller); } finally { allowAccess.get().set(old); } }
Logger demandLogger(String name, String resourceBundleName, Module module) { Logger result = getLogger(name); if (result == null) { // only allocate the new logger once Logger newLogger = new Logger(name, resourceBundleName, module == null ? null : module, this, false); do { if (addLogger(newLogger)) { // We successfully added the new Logger that we // created above so return it without refetching. return newLogger; } // We didn't add the new Logger that we created above // because another thread added a Logger with the same // name after our null check above and before our call // to addLogger(). We have to refetch the Logger because // addLogger() returns a boolean instead of the Logger // reference itself. However, if the thread that created // the other Logger is not holding a strong reference to // the other Logger, then it is possible for the other // Logger to be GC'ed after we saw it in addLogger() and // before we can refetch it. If it has been GC'ed then // we'll just loop around and try again. result = getLogger(name); } while (result == null); } return result; }
/** * Checks that the given layer contains exactly the expected modules * (by name). */ private void checkLayer(Layer layer, String ... expected) { Set<String> names = layer.modules().stream() .map(Module::getName) .collect(Collectors.toSet()); assertTrue(names.size() == expected.length); for (String name : expected) { assertTrue(names.contains(name)); } }