Line 0
Link Here
|
|
|
1 |
# HG changeset patch |
2 |
# User coffeys |
3 |
# Date 1360107230 0 |
4 |
# Node ID cff0241d217f7b463d58ddcd0add8d41de9eb280 |
5 |
# Parent dabed5898de907431b524952aade46f0b6b960aa |
6 |
8005615: Java Logger fails to load tomcat logger implementation (JULI) |
7 |
Reviewed-by: mchung |
8 |
|
9 |
diff --git a/src/share/classes/java/util/logging/LogManager.java b/src/share/classes/java/util/logging/LogManager.java |
10 |
--- jdk/src/share/classes/java/util/logging/LogManager.java |
11 |
+++ jdk/src/share/classes/java/util/logging/LogManager.java |
12 |
@@ -1,5 +1,5 @@ |
13 |
/* |
14 |
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. |
15 |
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. |
16 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
17 |
* |
18 |
* This code is free software; you can redistribute it and/or modify it |
19 |
@@ -159,7 +159,7 @@ |
20 |
|
21 |
// LoggerContext for system loggers and user loggers |
22 |
private final LoggerContext systemContext = new SystemLoggerContext(); |
23 |
- private final LoggerContext userContext = new UserLoggerContext(); |
24 |
+ private final LoggerContext userContext = new LoggerContext(); |
25 |
private Logger rootLogger; |
26 |
|
27 |
// Have we done the primordial reading of the configuration file? |
28 |
@@ -197,13 +197,13 @@ |
29 |
|
30 |
// Create and retain Logger for the root of the namespace. |
31 |
manager.rootLogger = manager.new RootLogger(); |
32 |
- manager.systemContext.addLogger(manager.rootLogger); |
33 |
- manager.userContext.addLogger(manager.rootLogger); |
34 |
+ manager.addLogger(manager.rootLogger); |
35 |
+ manager.systemContext.addLocalLogger(manager.rootLogger); |
36 |
|
37 |
// Adding the global Logger. Doing so in the Logger.<clinit> |
38 |
// would deadlock with the LogManager.<clinit>. |
39 |
Logger.global.setLogManager(manager); |
40 |
- manager.systemContext.addLogger(Logger.global); |
41 |
+ manager.addLogger(Logger.global); |
42 |
|
43 |
// We don't call readConfiguration() here, as we may be running |
44 |
// very early in the JVM startup sequence. Instead readConfiguration |
45 |
@@ -329,7 +329,7 @@ |
46 |
|
47 |
// Returns the LoggerContext for the user code (i.e. application or AppContext). |
48 |
// Loggers are isolated from each AppContext. |
49 |
- LoggerContext getUserContext() { |
50 |
+ private LoggerContext getUserContext() { |
51 |
LoggerContext context = null; |
52 |
|
53 |
SecurityManager sm = System.getSecurityManager(); |
54 |
@@ -350,8 +350,8 @@ |
55 |
if (javaAwtAccess.isMainAppContext()) { |
56 |
context = userContext; |
57 |
} else { |
58 |
- context = new UserLoggerContext(); |
59 |
- context.addLogger(manager.rootLogger); |
60 |
+ context = new LoggerContext(); |
61 |
+ context.addLocalLogger(manager.rootLogger); |
62 |
} |
63 |
javaAwtAccess.put(ecx, LoggerContext.class, context); |
64 |
} |
65 |
@@ -362,10 +362,6 @@ |
66 |
return context; |
67 |
} |
68 |
|
69 |
- LoggerContext getSystemContext() { |
70 |
- return systemContext; |
71 |
- } |
72 |
- |
73 |
private List<LoggerContext> contexts() { |
74 |
List<LoggerContext> cxs = new ArrayList<LoggerContext>(); |
75 |
cxs.add(systemContext); |
76 |
@@ -373,6 +369,58 @@ |
77 |
return cxs; |
78 |
} |
79 |
|
80 |
+ // Find or create a specified logger instance. If a logger has |
81 |
+ // already been created with the given name it is returned. |
82 |
+ // Otherwise a new logger instance is created and registered |
83 |
+ // in the LogManager global namespace. |
84 |
+ // This method will always return a non-null Logger object. |
85 |
+ // Synchronization is not required here. All synchronization for |
86 |
+ // adding a new Logger object is handled by addLogger(). |
87 |
+ // |
88 |
+ // This method must delegate to the LogManager implementation to |
89 |
+ // add a new Logger or return the one that has been added previously |
90 |
+ // as a LogManager subclass may override the addLogger, getLogger, |
91 |
+ // readConfiguration, and other methods. |
92 |
+ Logger demandLogger(String name, String resourceBundleName) { |
93 |
+ Logger result = getLogger(name); |
94 |
+ if (result == null) { |
95 |
+ // only allocate the new logger once |
96 |
+ Logger newLogger = new Logger(name, resourceBundleName); |
97 |
+ do { |
98 |
+ if (addLogger(newLogger)) { |
99 |
+ // We successfully added the new Logger that we |
100 |
+ // created above so return it without refetching. |
101 |
+ return newLogger; |
102 |
+ } |
103 |
+ |
104 |
+ // We didn't add the new Logger that we created above |
105 |
+ // because another thread added a Logger with the same |
106 |
+ // name after our null check above and before our call |
107 |
+ // to addLogger(). We have to refetch the Logger because |
108 |
+ // addLogger() returns a boolean instead of the Logger |
109 |
+ // reference itself. However, if the thread that created |
110 |
+ // the other Logger is not holding a strong reference to |
111 |
+ // the other Logger, then it is possible for the other |
112 |
+ // Logger to be GC'ed after we saw it in addLogger() and |
113 |
+ // before we can refetch it. If it has been GC'ed then |
114 |
+ // we'll just loop around and try again. |
115 |
+ result = getLogger(name); |
116 |
+ } while (result == null); |
117 |
+ } |
118 |
+ return result; |
119 |
+ } |
120 |
+ |
121 |
+ Logger demandSystemLogger(String name, String resourceBundleName) { |
122 |
+ return systemContext.demandLogger(name, resourceBundleName); |
123 |
+ } |
124 |
+ |
125 |
+ // LoggerContext maintains the logger namespace per context. |
126 |
+ // The default LogManager implementation has one system context and user |
127 |
+ // context. The system context is used to maintain the namespace for |
128 |
+ // all system loggers and is queried by the system code. If a system logger |
129 |
+ // doesn't exist in the user context, it'll also be added to the user context. |
130 |
+ // The user context is queried by the user code and all other loggers are |
131 |
+ // added in the user context. |
132 |
static class LoggerContext { |
133 |
// Table of named Loggers that maps names to Loggers. |
134 |
|
135 |
@@ -385,6 +433,12 @@ |
136 |
this.root = new LogNode(null, this); |
137 |
} |
138 |
|
139 |
+ Logger demandLogger(String name, String resourceBundleName) { |
140 |
+ // a LogManager subclass may have its own implementation to add and |
141 |
+ // get a Logger. So delegate to the LogManager to do the work. |
142 |
+ return manager.demandLogger(name, resourceBundleName); |
143 |
+ } |
144 |
+ |
145 |
synchronized Logger findLogger(String name) { |
146 |
LoggerWeakRef ref = namedLoggers.get(name); |
147 |
if (ref == null) { |
148 |
@@ -399,7 +453,9 @@ |
149 |
return logger; |
150 |
} |
151 |
|
152 |
- synchronized boolean addLogger(Logger logger) { |
153 |
+ // Add a logger to this context. This method will only set its level |
154 |
+ // and process parent loggers. It doesn't set its handlers. |
155 |
+ synchronized boolean addLocalLogger(Logger logger) { |
156 |
final String name = logger.getName(); |
157 |
if (name == null) { |
158 |
throw new NullPointerException(); |
159 |
@@ -432,9 +488,6 @@ |
160 |
doSetLevel(logger, level); |
161 |
} |
162 |
|
163 |
- // Do we have a per logger handler too? |
164 |
- // Note: this will add a 200ms penalty |
165 |
- manager.loadLoggerHandlers(logger, name, name + ".handlers"); |
166 |
processParentHandlers(logger, name); |
167 |
|
168 |
// Find the new node and its parent. |
169 |
@@ -471,49 +524,21 @@ |
170 |
return namedLoggers.keys(); |
171 |
} |
172 |
|
173 |
- Logger demandLogger(String name) { |
174 |
- return demandLogger(name, null); |
175 |
- } |
176 |
- |
177 |
- // Find or create a specified logger instance. If a logger has |
178 |
- // already been created with the given name it is returned. |
179 |
- // Otherwise a new logger instance is created and registered |
180 |
- // in the LogManager global namespace. |
181 |
- // This method will always return a non-null Logger object. |
182 |
- // Synchronization is not required here. All synchronization for |
183 |
- // adding a new Logger object is handled by addLogger(). |
184 |
- Logger demandLogger(String name, String resourceBundleName) { |
185 |
- Logger result = findLogger(name); |
186 |
- if (result == null) { |
187 |
- // only allocate the new logger once |
188 |
- Logger newLogger = new Logger(name, resourceBundleName); |
189 |
- do { |
190 |
- if (addLogger(newLogger)) { |
191 |
- // We successfully added the new Logger that we |
192 |
- // created above so return it without refetching. |
193 |
- return newLogger; |
194 |
- } |
195 |
- |
196 |
- // We didn't add the new Logger that we created above |
197 |
- // because another thread added a Logger with the same |
198 |
- // name after our null check above and before our call |
199 |
- // to addLogger(). We have to refetch the Logger because |
200 |
- // addLogger() returns a boolean instead of the Logger |
201 |
- // reference itself. However, if the thread that created |
202 |
- // the other Logger is not holding a strong reference to |
203 |
- // the other Logger, then it is possible for the other |
204 |
- // Logger to be GC'ed after we saw it in addLogger() and |
205 |
- // before we can refetch it. If it has been GC'ed then |
206 |
- // we'll just loop around and try again. |
207 |
- result = findLogger(name); |
208 |
- } while (result == null); |
209 |
- } |
210 |
- return result; |
211 |
- } |
212 |
- |
213 |
// If logger.getUseParentHandlers() returns 'true' and any of the logger's |
214 |
// parents have levels or handlers defined, make sure they are instantiated. |
215 |
- private void processParentHandlers(Logger logger, String name) { |
216 |
+ private void processParentHandlers(final Logger logger, final String name) { |
217 |
+ AccessController.doPrivileged(new PrivilegedAction<Void>() { |
218 |
+ public Void run() { |
219 |
+ if (logger != manager.rootLogger) { |
220 |
+ boolean useParent = manager.getBooleanProperty(name + ".useParentHandlers", true); |
221 |
+ if (!useParent) { |
222 |
+ logger.setUseParentHandlers(false); |
223 |
+ } |
224 |
+ } |
225 |
+ return null; |
226 |
+ } |
227 |
+ }); |
228 |
+ |
229 |
int ix = 1; |
230 |
for (;;) { |
231 |
int ix2 = name.indexOf(".", ix); |
232 |
@@ -526,12 +551,12 @@ |
233 |
|| manager.getProperty(pname + ".handlers") != null) { |
234 |
// This pname has a level/handlers definition. |
235 |
// Make sure it exists. |
236 |
- demandLogger(pname); |
237 |
+ demandLogger(pname, null); |
238 |
} |
239 |
ix = ix2 + 1; |
240 |
} |
241 |
} |
242 |
- |
243 |
+ |
244 |
// Gets a node in our tree of logger nodes. |
245 |
// If necessary, create it. |
246 |
LogNode getNode(String name) { |
247 |
@@ -564,74 +589,55 @@ |
248 |
} |
249 |
|
250 |
static class SystemLoggerContext extends LoggerContext { |
251 |
- // Default resource bundle for all system loggers |
252 |
- |
253 |
- Logger demandLogger(String name) { |
254 |
- // default to use the system logger's resource bundle |
255 |
- return super.demandLogger(name, Logger.SYSTEM_LOGGER_RB_NAME); |
256 |
- } |
257 |
- } |
258 |
- |
259 |
- static class UserLoggerContext extends LoggerContext { |
260 |
- |
261 |
- /** |
262 |
- * Returns a Logger of the given name if there is one registered |
263 |
- * in this context. Otherwise, it will return the one registered |
264 |
- * in the system context if there is one. The returned Logger |
265 |
- * instance may be initialized with a different resourceBundleName. |
266 |
- * If no such logger exists, a new Logger instance will be created |
267 |
- * and registered in this context. |
268 |
- */ |
269 |
+ // Add a system logger in the system context's namespace as well as |
270 |
+ // in the LogManager's namespace if not exist so that there is only |
271 |
+ // one single logger of the given name. System loggers are visible |
272 |
+ // to applications unless a logger of the same name has been added. |
273 |
Logger demandLogger(String name, String resourceBundleName) { |
274 |
Logger result = findLogger(name); |
275 |
if (result == null) { |
276 |
- // use the system logger if exists; or allocate a new logger. |
277 |
- // The system logger is added to the app logger context so that |
278 |
- // any child logger created in the app logger context can have |
279 |
- // a system logger as its parent if already exist. |
280 |
- Logger logger = manager.systemContext.findLogger(name); |
281 |
- Logger newLogger = |
282 |
- logger != null ? logger : new Logger(name, resourceBundleName); |
283 |
+ // only allocate the new system logger once |
284 |
+ Logger newLogger = new Logger(name, resourceBundleName); |
285 |
do { |
286 |
- if (addLogger(newLogger)) { |
287 |
+ if (addLocalLogger(newLogger)) { |
288 |
// We successfully added the new Logger that we |
289 |
// created above so return it without refetching. |
290 |
- return newLogger; |
291 |
+ result = newLogger; |
292 |
+ } else { |
293 |
+ // We didn't add the new Logger that we created above |
294 |
+ // because another thread added a Logger with the same |
295 |
+ // name after our null check above and before our call |
296 |
+ // to addLogger(). We have to refetch the Logger because |
297 |
+ // addLogger() returns a boolean instead of the Logger |
298 |
+ // reference itself. However, if the thread that created |
299 |
+ // the other Logger is not holding a strong reference to |
300 |
+ // the other Logger, then it is possible for the other |
301 |
+ // Logger to be GC'ed after we saw it in addLogger() and |
302 |
+ // before we can refetch it. If it has been GC'ed then |
303 |
+ // we'll just loop around and try again. |
304 |
+ result = findLogger(name); |
305 |
} |
306 |
- |
307 |
- // We didn't add the new Logger that we created above |
308 |
- // because another thread added a Logger with the same |
309 |
- // name after our null check above and before our call |
310 |
- // to addLogger(). We have to refetch the Logger because |
311 |
- // addLogger() returns a boolean instead of the Logger |
312 |
- // reference itself. However, if the thread that created |
313 |
- // the other Logger is not holding a strong reference to |
314 |
- // the other Logger, then it is possible for the other |
315 |
- // Logger to be GC'ed after we saw it in addLogger() and |
316 |
- // before we can refetch it. If it has been GC'ed then |
317 |
- // we'll just loop around and try again. |
318 |
- result = findLogger(name); |
319 |
} while (result == null); |
320 |
} |
321 |
- return result; |
322 |
+ // Add the system logger to the LogManager's namespace if not exists |
323 |
+ // The LogManager will set its handlers via the LogManager.addLogger method. |
324 |
+ if (!manager.addLogger(result) && result.getHandlers().length == 0) { |
325 |
+ // if logger already exists but handlers not set |
326 |
+ final Logger l = manager.getLogger(name); |
327 |
+ final Logger logger = result; |
328 |
+ AccessController.doPrivileged(new PrivilegedAction<Void>() { |
329 |
+ public Void run() { |
330 |
+ for (Handler hdl : l.getHandlers()) { |
331 |
+ logger.addHandler(hdl); |
332 |
+ } |
333 |
+ return null; |
334 |
+ } |
335 |
+ }); |
336 |
+ } |
337 |
+ return result; |
338 |
} |
339 |
} |
340 |
|
341 |
- // Package-level method. |
342 |
- // Find or create a specified logger instance. If a logger has |
343 |
- // already been created with the given name it is returned. |
344 |
- // Otherwise a new logger instance is created and registered |
345 |
- // in the LogManager global namespace. |
346 |
- synchronized Logger demandLogger(String name) { |
347 |
- Logger result = getLogger(name); |
348 |
- if (result == null) { |
349 |
- result = new Logger(name, null); |
350 |
- addLogger(result); |
351 |
- result = getLogger(name); |
352 |
- } |
353 |
- return result; |
354 |
- } |
355 |
- |
356 |
// Add new per logger handlers. |
357 |
// We need to raise privilege here. All our decisions will |
358 |
// be made based on the logging configuration, which can |
359 |
@@ -640,12 +646,6 @@ |
360 |
final String handlersPropertyName) { |
361 |
AccessController.doPrivileged(new PrivilegedAction<Object>() { |
362 |
public Object run() { |
363 |
- if (logger != rootLogger) { |
364 |
- boolean useParent = getBooleanProperty(name + ".useParentHandlers", true); |
365 |
- if (!useParent) { |
366 |
- logger.setUseParentHandlers(false); |
367 |
- } |
368 |
- } |
369 |
|
370 |
String names[] = parseClassNames(handlersPropertyName); |
371 |
for (int i = 0; i < names.length; i++) { |
372 |
@@ -674,10 +674,10 @@ |
373 |
} |
374 |
} |
375 |
return null; |
376 |
- }}); |
377 |
+ } |
378 |
+ }); |
379 |
} |
380 |
|
381 |
- |
382 |
// loggerRefQueue holds LoggerWeakRef objects for Logger objects |
383 |
// that have been GC'ed. |
384 |
private final ReferenceQueue<Logger> loggerRefQueue |
385 |
@@ -815,10 +815,15 @@ |
386 |
if (name == null) { |
387 |
throw new NullPointerException(); |
388 |
} |
389 |
- if (systemContext.findLogger(name) != null) { |
390 |
+ LoggerContext cx = getUserContext(); |
391 |
+ if (cx.addLocalLogger(logger)) { |
392 |
+ // Do we have a per logger handler too? |
393 |
+ // Note: this will add a 200ms penalty |
394 |
+ loadLoggerHandlers(logger, name, name + ".handlers"); |
395 |
+ return true; |
396 |
+ } else { |
397 |
return false; |
398 |
} |
399 |
- return getUserContext().addLogger(logger); |
400 |
} |
401 |
|
402 |
// Private method to set a level on a logger. |
403 |
@@ -839,8 +844,6 @@ |
404 |
}}); |
405 |
} |
406 |
|
407 |
- |
408 |
- |
409 |
// Private method to set a parent on a logger. |
410 |
// If necessary, we raise privilege before doing the setParent call. |
411 |
private static void doSetParent(final Logger logger, final Logger parent) { |
412 |
@@ -875,15 +878,7 @@ |
413 |
* @return matching logger or null if none is found |
414 |
*/ |
415 |
public Logger getLogger(String name) { |
416 |
- // return the first logger added |
417 |
- // |
418 |
- // once a system logger is added in the system context, no one can |
419 |
- // adds a logger with the same name in the global context |
420 |
- // (see LogManager.addLogger). So if there is a logger in the global |
421 |
- // context with the same name as one in the system context, it must be |
422 |
- // added before the system logger was created. |
423 |
- Logger logger = getUserContext().findLogger(name); |
424 |
- return logger != null ? logger : systemContext.findLogger(name); |
425 |
+ return getUserContext().findLogger(name); |
426 |
} |
427 |
|
428 |
/** |
429 |
@@ -903,11 +898,7 @@ |
430 |
* @return enumeration of logger name strings |
431 |
*/ |
432 |
public Enumeration<String> getLoggerNames() { |
433 |
- // only return unique names |
434 |
- Set<String> names = |
435 |
- new HashSet<String>(Collections.list(systemContext.getLoggerNames())); |
436 |
- names.addAll(Collections.list(getUserContext().getLoggerNames())); |
437 |
- return Collections.enumeration(names); |
438 |
+ return getUserContext().getLoggerNames(); |
439 |
} |
440 |
|
441 |
/** |
442 |
@@ -1229,7 +1220,6 @@ |
443 |
loadLoggerHandlers(rootLogger, null, "handlers"); |
444 |
} |
445 |
|
446 |
- |
447 |
private final Permission controlPermission = new LoggingPermission("control", null); |
448 |
|
449 |
void checkPermission() { |
450 |
@@ -1288,7 +1278,6 @@ |
451 |
// that we only instantiate the global handlers when they |
452 |
// are first needed. |
453 |
private class RootLogger extends Logger { |
454 |
- |
455 |
private RootLogger() { |
456 |
super("", null); |
457 |
setLevel(defaultLevel); |
458 |
diff --git a/src/share/classes/java/util/logging/Logger.java b/src/share/classes/java/util/logging/Logger.java |
459 |
--- jdk/src/share/classes/java/util/logging/Logger.java |
460 |
+++ jdk/src/share/classes/java/util/logging/Logger.java |
461 |
@@ -1,5 +1,5 @@ |
462 |
/* |
463 |
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. |
464 |
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. |
465 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
466 |
* |
467 |
* This code is free software; you can redistribute it and/or modify it |
468 |
@@ -29,7 +29,6 @@ |
469 |
import java.util.*; |
470 |
import java.security.*; |
471 |
import java.lang.ref.WeakReference; |
472 |
-import java.util.logging.LogManager.LoggerContext; |
473 |
|
474 |
/** |
475 |
* A Logger object is used to log messages for a specific |
476 |
@@ -283,18 +282,32 @@ |
477 |
// |
478 |
// As an interim solution, if the immediate caller whose caller loader is |
479 |
// null, we assume it's a system logger and add it to the system context. |
480 |
- private static LoggerContext getLoggerContext() { |
481 |
+ // These system loggers only set the resource bundle to the given |
482 |
+ // resource bundle name (rather than the default system resource bundle). |
483 |
+ private static class SystemLoggerHelper { |
484 |
+ static boolean disableCallerCheck = getBooleanProperty("sun.util.logging.disableCallerCheck"); |
485 |
+ private static boolean getBooleanProperty(final String key) { |
486 |
+ String s = AccessController.doPrivileged(new PrivilegedAction<String>() { |
487 |
+ public String run() { |
488 |
+ return System.getProperty(key); |
489 |
+ } |
490 |
+ }); |
491 |
+ return Boolean.valueOf(s); |
492 |
+ } |
493 |
+ } |
494 |
+ |
495 |
+ private static Logger demandLogger(String name, String resourceBundleName) { |
496 |
LogManager manager = LogManager.getLogManager(); |
497 |
SecurityManager sm = System.getSecurityManager(); |
498 |
- if (sm != null) { |
499 |
+ if (sm != null && !SystemLoggerHelper.disableCallerCheck) { |
500 |
// 0: Reflection 1: Logger.getLoggerContext 2: Logger.getLogger 3: caller |
501 |
final int SKIP_FRAMES = 3; |
502 |
Class<?> caller = sun.reflect.Reflection.getCallerClass(SKIP_FRAMES); |
503 |
if (caller.getClassLoader() == null) { |
504 |
- return manager.getSystemContext(); |
505 |
+ return manager.demandSystemLogger(name, resourceBundleName); |
506 |
} |
507 |
} |
508 |
- return manager.getUserContext(); |
509 |
+ return manager.demandLogger(name, resourceBundleName); |
510 |
} |
511 |
|
512 |
/** |
513 |
@@ -325,8 +338,7 @@ |
514 |
* @throws NullPointerException if the name is null. |
515 |
*/ |
516 |
public static synchronized Logger getLogger(String name) { |
517 |
- LoggerContext context = getLoggerContext(); |
518 |
- return context.demandLogger(name); |
519 |
+ return demandLogger(name, null); |
520 |
} |
521 |
|
522 |
/** |
523 |
@@ -369,8 +381,7 @@ |
524 |
* @throws NullPointerException if the name is null. |
525 |
*/ |
526 |
public static synchronized Logger getLogger(String name, String resourceBundleName) { |
527 |
- LoggerContext context = getLoggerContext(); |
528 |
- Logger result = context.demandLogger(name, resourceBundleName); |
529 |
+ Logger result = demandLogger(name, resourceBundleName); |
530 |
if (result.resourceBundleName == null) { |
531 |
// Note: we may get a MissingResourceException here. |
532 |
result.setupResourceInfo(resourceBundleName); |
533 |
@@ -1300,7 +1311,8 @@ |
534 |
public ResourceBundle run() { |
535 |
try { |
536 |
return ResourceBundle.getBundle(SYSTEM_LOGGER_RB_NAME, |
537 |
- locale); |
538 |
+ locale, |
539 |
+ ClassLoader.getSystemClassLoader()); |
540 |
} catch (MissingResourceException e) { |
541 |
throw new InternalError(e.toString()); |
542 |
} |