test/jdk/java/lang/System/LoggerFinder/internal/BaseLoggerBridgeTest/CustomSystemClassLoader.java
changeset 53044 432795b1c2c8
parent 47216 71c04702a3d5
equal deleted inserted replaced
53043:fd2e8f941ded 53044:432795b1c2c8
     1 /*
     1 /*
     2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    26 import java.net.URL;
    26 import java.net.URL;
    27 import java.nio.file.Files;
    27 import java.nio.file.Files;
    28 import java.security.AllPermission;
    28 import java.security.AllPermission;
    29 import java.security.Permissions;
    29 import java.security.Permissions;
    30 import java.security.ProtectionDomain;
    30 import java.security.ProtectionDomain;
    31 
    31 import java.util.concurrent.ConcurrentHashMap;
    32 
    32 
    33 /**
    33 /**
    34  * A custom ClassLoader to load the concrete LoggerFinder class
    34  * A custom ClassLoader to load the concrete LoggerFinder class
    35  * with all permissions.
    35  * with all permissions.
    36  *
    36  *
    37  * @author danielfuchs
    37  * @author danielfuchs
    38  */
    38  */
    39 public class CustomSystemClassLoader extends ClassLoader {
    39 public class CustomSystemClassLoader extends ClassLoader {
    40 
    40 
    41 
    41 
    42     Class<?> finderClass = null;
    42     private final ConcurrentHashMap<String, Class<?>> classes = new ConcurrentHashMap<>();
    43 
    43 
    44     public CustomSystemClassLoader() {
    44     public CustomSystemClassLoader() {
    45         super();
    45         super();
    46     }
    46     }
    47     public CustomSystemClassLoader(ClassLoader parent) {
    47     public CustomSystemClassLoader(ClassLoader parent) {
    48         super(parent);
    48         super(parent);
    49     }
    49     }
    50 
    50 
    51     private Class<?> defineFinderClass(String name)
    51     private Class<?> defineFinderClass(String name)
    52         throws ClassNotFoundException {
    52         throws ClassNotFoundException {
       
    53         Class<?> finderClass = classes.get(name);
       
    54         if (finderClass != null) return finderClass;
       
    55 
    53         final Object obj = getClassLoadingLock(name);
    56         final Object obj = getClassLoadingLock(name);
       
    57 
    54         synchronized(obj) {
    58         synchronized(obj) {
       
    59             finderClass = classes.get(name);
    55             if (finderClass != null) return finderClass;
    60             if (finderClass != null) return finderClass;
    56 
    61 
    57             URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation();
    62             URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation();
    58             File file = new File(url.getPath(), name+".class");
    63             File file = new File(url.getPath(), name+".class");
    59             if (file.canRead()) {
    64             if (file.canRead()) {
    64                     finderClass = defineClass(
    69                     finderClass = defineClass(
    65                             name, b, 0, b.length, new ProtectionDomain(
    70                             name, b, 0, b.length, new ProtectionDomain(
    66                             this.getClass().getProtectionDomain().getCodeSource(),
    71                             this.getClass().getProtectionDomain().getCodeSource(),
    67                             perms));
    72                             perms));
    68                     System.out.println("Loaded " + name);
    73                     System.out.println("Loaded " + name);
       
    74                     classes.put(name, finderClass);
    69                     return finderClass;
    75                     return finderClass;
    70                 } catch (Throwable ex) {
    76                 } catch (Throwable ex) {
    71                     ex.printStackTrace();
    77                     ex.printStackTrace();
    72                     throw new ClassNotFoundException(name, ex);
    78                     throw new ClassNotFoundException(name, ex);
    73                 }
    79                 }
    78         }
    84         }
    79     }
    85     }
    80 
    86 
    81     @Override
    87     @Override
    82     public synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    88     public synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    83         if (name.endsWith("$BaseLoggerFinder")) {
    89         if (name.equals("BaseLoggerFinder") || name.startsWith("BaseLoggerFinder$")) {
    84             Class<?> c = defineFinderClass(name);
    90             Class<?> c = defineFinderClass(name);
    85             if (resolve) {
    91             if (resolve) {
    86                 resolveClass(c);
    92                 resolveClass(c);
    87             }
    93             }
    88             return c;
    94             return c;
    90         return super.loadClass(name, resolve);
    96         return super.loadClass(name, resolve);
    91     }
    97     }
    92 
    98 
    93     @Override
    99     @Override
    94     protected Class<?> findClass(String name) throws ClassNotFoundException {
   100     protected Class<?> findClass(String name) throws ClassNotFoundException {
    95         if (name.endsWith("$BaseLoggerFinder")) {
   101         if (name.equals("BaseLoggerFinder") || name.startsWith("BaseLoggerFinder$")) {
    96             return defineFinderClass(name);
   102             return defineFinderClass(name);
    97         }
   103         }
    98         return super.findClass(name);
   104         return super.findClass(name);
    99     }
   105     }
   100 
   106