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 import java.util.concurrent.ConcurrentHashMap; |
31 |
32 |
32 |
33 |
33 /** |
34 /** |
34 * A custom ClassLoader to load the concrete LoggerFinder class |
35 * A custom ClassLoader to load the concrete LoggerFinder class |
35 * with all permissions. |
36 * with all permissions. |
37 * @author danielfuchs |
38 * @author danielfuchs |
38 */ |
39 */ |
39 public class CustomSystemClassLoader extends ClassLoader { |
40 public class CustomSystemClassLoader extends ClassLoader { |
40 |
41 |
41 |
42 |
42 Class<?> loggerFinderClass = null; |
43 private final ConcurrentHashMap<String, Class<?>> classes = new ConcurrentHashMap<>(); |
43 // Class<?> loggerImplClass = null; |
|
44 |
44 |
45 public CustomSystemClassLoader() { |
45 public CustomSystemClassLoader() { |
46 super(); |
46 super(); |
47 } |
47 } |
48 public CustomSystemClassLoader(ClassLoader parent) { |
48 public CustomSystemClassLoader(ClassLoader parent) { |
49 super(parent); |
49 super(parent); |
50 } |
50 } |
51 |
51 |
52 private Class<?> defineFinderClass(String name) |
52 private Class<?> defineFinderClass(String name) |
53 throws ClassNotFoundException { |
53 throws ClassNotFoundException { |
|
54 |
|
55 Class<?> loggerFinderClass = classes.get(name); |
|
56 if (loggerFinderClass != null) return loggerFinderClass; |
|
57 |
54 final Object obj = getClassLoadingLock(name); |
58 final Object obj = getClassLoadingLock(name); |
55 synchronized(obj) { |
59 synchronized(obj) { |
|
60 loggerFinderClass = classes.get(name); |
56 if (loggerFinderClass != null) return loggerFinderClass; |
61 if (loggerFinderClass != null) return loggerFinderClass; |
57 |
62 |
58 URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation(); |
63 URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation(); |
59 File file = new File(url.getPath(), name+".class"); |
64 File file = new File(url.getPath(), name+".class"); |
60 if (file.canRead()) { |
65 if (file.canRead()) { |
64 perms.add(new AllPermission()); |
69 perms.add(new AllPermission()); |
65 loggerFinderClass = defineClass( |
70 loggerFinderClass = defineClass( |
66 name, b, 0, b.length, new ProtectionDomain( |
71 name, b, 0, b.length, new ProtectionDomain( |
67 this.getClass().getProtectionDomain().getCodeSource(), |
72 this.getClass().getProtectionDomain().getCodeSource(), |
68 perms)); |
73 perms)); |
|
74 classes.put(name, loggerFinderClass); |
69 System.out.println("Loaded " + name); |
75 System.out.println("Loaded " + name); |
70 return loggerFinderClass; |
76 return loggerFinderClass; |
71 } catch (Throwable ex) { |
77 } catch (Throwable ex) { |
72 ex.printStackTrace(); |
78 ex.printStackTrace(); |
73 throw new ClassNotFoundException(name, ex); |
79 throw new ClassNotFoundException(name, ex); |
76 throw new ClassNotFoundException(name, |
82 throw new ClassNotFoundException(name, |
77 new IOException(file.toPath() + ": can't read")); |
83 new IOException(file.toPath() + ": can't read")); |
78 } |
84 } |
79 } |
85 } |
80 } |
86 } |
81 // private Class<?> defineLoggerImplClass(String name) |
87 |
82 // throws ClassNotFoundException { |
|
83 // final Object obj = getClassLoadingLock(name); |
|
84 // synchronized(obj) { |
|
85 // if (loggerImplClass != null) return loggerImplClass; |
|
86 // |
|
87 // URL url = this.getClass().getProtectionDomain().getCodeSource().getLocation(); |
|
88 // File file = new File(url.getPath(), name+".class"); |
|
89 // if (file.canRead()) { |
|
90 // try { |
|
91 // byte[] b = Files.readAllBytes(file.toPath()); |
|
92 // Permissions perms = new Permissions(); |
|
93 // perms.add(new AllPermission()); |
|
94 // loggerImplClass = defineClass( |
|
95 // name, b, 0, b.length, new ProtectionDomain( |
|
96 // this.getClass().getProtectionDomain().getCodeSource(), |
|
97 // perms)); |
|
98 // System.out.println("Loaded " + name); |
|
99 // return loggerImplClass; |
|
100 // } catch (Throwable ex) { |
|
101 // ex.printStackTrace(); |
|
102 // throw new ClassNotFoundException(name, ex); |
|
103 // } |
|
104 // } else { |
|
105 // throw new ClassNotFoundException(name, |
|
106 // new IOException(file.toPath() + ": can't read")); |
|
107 // } |
|
108 // } |
|
109 // } |
|
110 // |
|
111 @Override |
88 @Override |
112 public synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { |
89 public synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { |
113 if (name.endsWith("$LogProducerFinder")) { |
90 if (name.equals("LogProducerFinder") || name.startsWith("LogProducerFinder$")) { |
114 Class<?> c = defineFinderClass(name); |
91 Class<?> c = defineFinderClass(name); |
115 if (resolve) { |
92 if (resolve) { |
116 resolveClass(c); |
93 resolveClass(c); |
117 } |
94 } |
118 return c; |
95 return c; |
119 } |
96 } |
120 // if (name.endsWith("$LogProducerFinder$LoggerImpl")) { |
|
121 // Class<?> c = defineLoggerImplClass(name); |
|
122 // if (resolve) { |
|
123 // resolveClass(c); |
|
124 // } |
|
125 // return c; |
|
126 // } |
|
127 return super.loadClass(name, resolve); |
97 return super.loadClass(name, resolve); |
128 } |
98 } |
129 |
99 |
130 @Override |
100 @Override |
131 protected Class<?> findClass(String name) throws ClassNotFoundException { |
101 protected Class<?> findClass(String name) throws ClassNotFoundException { |
132 // if (name.endsWith("$LogProducerFinder$LoggerImpl")) { |
102 if (name.equals("LogProducerFinder") || name.startsWith("LogProducerFinder$")) { |
133 // return defineLoggerImplClass(name); |
|
134 // } |
|
135 if (name.endsWith("$$LogProducerFinder")) { |
|
136 return defineFinderClass(name); |
103 return defineFinderClass(name); |
137 } |
104 } |
138 return super.findClass(name); |
105 return super.findClass(name); |
139 } |
106 } |
140 |
107 |