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 } |
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 |