Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java
41159 views
1
/*
2
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
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
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
package jdk.internal.logger;
26
27
import java.io.FilePermission;
28
import java.security.AccessController;
29
import java.security.Permission;
30
import java.security.PrivilegedAction;
31
import java.util.Iterator;
32
import java.util.Locale;
33
import java.util.ServiceConfigurationError;
34
import java.util.ServiceLoader;
35
import sun.security.util.SecurityConstants;
36
import sun.security.action.GetPropertyAction;
37
38
/**
39
* Helper class used to load the {@link java.lang.System.LoggerFinder}.
40
*/
41
public final class LoggerFinderLoader {
42
private static volatile System.LoggerFinder service;
43
private static final Object lock = new int[0];
44
static final Permission CLASSLOADER_PERMISSION =
45
SecurityConstants.GET_CLASSLOADER_PERMISSION;
46
static final Permission READ_PERMISSION =
47
new FilePermission("<<ALL FILES>>",
48
SecurityConstants.FILE_READ_ACTION);
49
public static final RuntimePermission LOGGERFINDER_PERMISSION =
50
new RuntimePermission("loggerFinder");
51
52
// This is used to control how the LoggerFinderLoader handles
53
// errors when instantiating the LoggerFinder provider.
54
// ERROR => throws ServiceConfigurationError
55
// WARNING => Do not fail, use plain default (simple logger) implementation,
56
// prints warning on console. (this is the default)
57
// DEBUG => Do not fail, use plain default (simple logger) implementation,
58
// prints warning and exception stack trace on console.
59
// QUIET => Do not fail and stay silent.
60
private static enum ErrorPolicy { ERROR, WARNING, DEBUG, QUIET };
61
62
// This class is static and cannot be instantiated.
63
private LoggerFinderLoader() {
64
throw new InternalError("LoggerFinderLoader cannot be instantiated");
65
}
66
67
68
// Return the loaded LoggerFinder, or load it if not already loaded.
69
private static System.LoggerFinder service() {
70
if (service != null) return service;
71
synchronized(lock) {
72
if (service != null) return service;
73
service = loadLoggerFinder();
74
}
75
// Since the LoggerFinder is already loaded - we can stop using
76
// temporary loggers.
77
BootstrapLogger.redirectTemporaryLoggers();
78
return service;
79
}
80
81
// Get configuration error policy
82
private static ErrorPolicy configurationErrorPolicy() {
83
String errorPolicy =
84
GetPropertyAction.privilegedGetProperty("jdk.logger.finder.error");
85
if (errorPolicy == null || errorPolicy.isEmpty()) {
86
return ErrorPolicy.WARNING;
87
}
88
try {
89
return ErrorPolicy.valueOf(errorPolicy.toUpperCase(Locale.ROOT));
90
} catch (IllegalArgumentException x) {
91
return ErrorPolicy.WARNING;
92
}
93
}
94
95
// Whether multiple provider should be considered as an error.
96
// This is further submitted to the configuration error policy.
97
private static boolean ensureSingletonProvider() {
98
return Boolean.parseBoolean(
99
GetPropertyAction.privilegedGetProperty("jdk.logger.finder.singleton"));
100
}
101
102
@SuppressWarnings("removal")
103
private static Iterator<System.LoggerFinder> findLoggerFinderProviders() {
104
final Iterator<System.LoggerFinder> iterator;
105
if (System.getSecurityManager() == null) {
106
iterator = ServiceLoader.load(System.LoggerFinder.class,
107
ClassLoader.getSystemClassLoader()).iterator();
108
} else {
109
final PrivilegedAction<Iterator<System.LoggerFinder>> pa =
110
() -> ServiceLoader.load(System.LoggerFinder.class,
111
ClassLoader.getSystemClassLoader()).iterator();
112
iterator = AccessController.doPrivileged(pa, null,
113
LOGGERFINDER_PERMISSION, CLASSLOADER_PERMISSION,
114
READ_PERMISSION);
115
}
116
return iterator;
117
}
118
119
// Loads the LoggerFinder using ServiceLoader. If no LoggerFinder
120
// is found returns the default (possibly JUL based) implementation
121
private static System.LoggerFinder loadLoggerFinder() {
122
System.LoggerFinder result;
123
try {
124
// Iterator iterates with the access control context stored
125
// at ServiceLoader creation time.
126
final Iterator<System.LoggerFinder> iterator =
127
findLoggerFinderProviders();
128
if (iterator.hasNext()) {
129
result = iterator.next();
130
if (iterator.hasNext() && ensureSingletonProvider()) {
131
throw new ServiceConfigurationError(
132
"More than on LoggerFinder implementation");
133
}
134
} else {
135
result = loadDefaultImplementation();
136
}
137
} catch (Error | RuntimeException x) {
138
// next caller will get the plain default impl (not linked
139
// to java.util.logging)
140
service = result = new DefaultLoggerFinder();
141
ErrorPolicy errorPolicy = configurationErrorPolicy();
142
if (errorPolicy == ErrorPolicy.ERROR) {
143
// rethrow any exception as a ServiceConfigurationError.
144
if (x instanceof Error) {
145
throw x;
146
} else {
147
throw new ServiceConfigurationError(
148
"Failed to instantiate LoggerFinder provider; Using default.", x);
149
}
150
} else if (errorPolicy != ErrorPolicy.QUIET) {
151
// if QUIET just silently use the plain default impl
152
// otherwise, log a warning, possibly adding the exception
153
// stack trace (if DEBUG is specified).
154
SimpleConsoleLogger logger =
155
new SimpleConsoleLogger("jdk.internal.logger", false);
156
logger.log(System.Logger.Level.WARNING,
157
"Failed to instantiate LoggerFinder provider; Using default.");
158
if (errorPolicy == ErrorPolicy.DEBUG) {
159
logger.log(System.Logger.Level.WARNING,
160
"Exception raised trying to instantiate LoggerFinder", x);
161
}
162
}
163
}
164
return result;
165
}
166
167
@SuppressWarnings("removal")
168
private static System.LoggerFinder loadDefaultImplementation() {
169
final SecurityManager sm = System.getSecurityManager();
170
final Iterator<DefaultLoggerFinder> iterator;
171
if (sm == null) {
172
iterator = ServiceLoader.loadInstalled(DefaultLoggerFinder.class).iterator();
173
} else {
174
// We use limited do privileged here - the minimum set of
175
// permissions required to 'see' the META-INF/services resources
176
// seems to be CLASSLOADER_PERMISSION and READ_PERMISSION.
177
// Note that do privileged is required because
178
// otherwise the SecurityManager will prevent the ServiceLoader
179
// from seeing the installed provider.
180
PrivilegedAction<Iterator<DefaultLoggerFinder>> pa = () ->
181
ServiceLoader.loadInstalled(DefaultLoggerFinder.class).iterator();
182
iterator = AccessController.doPrivileged(pa, null,
183
LOGGERFINDER_PERMISSION, CLASSLOADER_PERMISSION,
184
READ_PERMISSION);
185
}
186
DefaultLoggerFinder result = null;
187
try {
188
// Iterator iterates with the access control context stored
189
// at ServiceLoader creation time.
190
if (iterator.hasNext()) {
191
result = iterator.next();
192
}
193
} catch (RuntimeException x) {
194
throw new ServiceConfigurationError(
195
"Failed to instantiate default LoggerFinder", x);
196
}
197
if (result == null) {
198
result = new DefaultLoggerFinder();
199
}
200
return result;
201
}
202
203
public static System.LoggerFinder getLoggerFinder() {
204
@SuppressWarnings("removal")
205
final SecurityManager sm = System.getSecurityManager();
206
if (sm != null) {
207
sm.checkPermission(LOGGERFINDER_PERMISSION);
208
}
209
return service();
210
}
211
212
}
213
214