提交 b38ca313 编写于 作者: J jgish

8002070: Remove the stack search for a resource bundle for Logger to use

Summary: The fragile, vulnerable, stack crawling has been eliminated from findResourceBundle(String)
Reviewed-by: mchung, alanb
上级 4d10f182
/*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -26,10 +26,13 @@
package java.util.logging;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.security.*;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Supplier;
/**
......@@ -104,7 +107,7 @@ import java.util.function.Supplier;
* unnecessary message construction. For example, if the developer wants to
* log system health status for diagnosis, with the String-accepting version,
* the code would look like:
<code><pre>
<pre><code>
class DiagnosisMessages {
static String systemHealthStatus() {
......@@ -114,26 +117,20 @@ import java.util.function.Supplier;
}
...
logger.log(Level.FINER, DiagnosisMessages.systemHealthStatus());
</pre></code>
</code></pre>
* With the above code, the health status is collected unnecessarily even when
* the log level FINER is disabled. With the Supplier-accepting version as
* below, the status will only be collected when the log level FINER is
* enabled.
<code><pre>
<pre><code>
logger.log(Level.FINER, DiagnosisMessages::systemHealthStatus);
</pre></code>
</code></pre>
* <p>
* When mapping ResourceBundle names to ResourceBundles, the Logger
* will first try to use the Thread's ContextClassLoader. If that
* is null it will try the SystemClassLoader instead. As a temporary
* transition feature in the initial implementation, if the Logger is
* unable to locate a ResourceBundle from the ContextClassLoader or
* SystemClassLoader the Logger will also search up the class stack
* and use successive calling ClassLoaders to try to locate a ResourceBundle.
* (This call stack search is to allow containers to transition to
* using ContextClassLoaders and is likely to be removed in future
* versions.)
* is null it will try the
* {@linkplain java.lang.ClassLoader#getSystemClassLoader() system ClassLoader} instead.
* <p>
* Formatting (including localization) is the responsibility of
* the output Handler, which will typically call a Formatter.
......@@ -1541,12 +1538,16 @@ public class Logger {
return useParentHandlers;
}
// Private utility method to map a resource bundle name to an
// actual resource bundle, using a simple one-entry cache.
// Returns null for a null name.
// May also return null if we can't find the resource bundle and
// there is no suitable previous cached value.
/**
* Private utility method to map a resource bundle name to an
* actual resource bundle, using a simple one-entry cache.
* Returns null for a null name.
* May also return null if we can't find the resource bundle and
* there is no suitable previous cached value.
*
* @param name the ResourceBundle to locate
* @return ResourceBundle specified by name or null if not found
*/
private synchronized ResourceBundle findResourceBundle(String name) {
// Return a null bundle for a null name.
if (name == null) {
......@@ -1556,13 +1557,13 @@ public class Logger {
Locale currentLocale = Locale.getDefault();
// Normally we should hit on our simple one entry cache.
if (catalog != null && currentLocale == catalogLocale
&& name == catalogName) {
if (catalog != null && currentLocale.equals(catalogLocale)
&& name.equals(catalogName)) {
return catalog;
}
// Use the thread's context ClassLoader. If there isn't one,
// use the SystemClassloader.
// Use the thread's context ClassLoader. If there isn't one, use the
// {@linkplain java.lang.ClassLoader#getSystemClassLoader() system ClassLoader}.
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null) {
cl = ClassLoader.getSystemClassLoader();
......@@ -1573,46 +1574,9 @@ public class Logger {
catalogLocale = currentLocale;
return catalog;
} catch (MissingResourceException ex) {
// Woops. We can't find the ResourceBundle in the default
// ClassLoader. Drop through.
}
// Fall back to searching up the call stack and trying each
// calling ClassLoader.
for (int ix = 0; ; ix++) {
Class clz = sun.reflect.Reflection.getCallerClass(ix);
if (clz == null) {
break;
}
ClassLoader cl2 = clz.getClassLoader();
if (cl2 == null) {
cl2 = ClassLoader.getSystemClassLoader();
}
if (cl == cl2) {
// We've already checked this classloader.
continue;
}
cl = cl2;
try {
catalog = ResourceBundle.getBundle(name, currentLocale, cl);
catalogName = name;
catalogLocale = currentLocale;
return catalog;
} catch (MissingResourceException ex) {
// Ok, this one didn't work either.
// Drop through, and try the next one.
}
}
if (name.equals(catalogName)) {
// Return the previous cached value for that name.
// This may be null.
return catalog;
}
// Sorry, we're out of luck.
return null;
}
}
// Private utility method to initialize our one entry
// resource bundle name cache.
......@@ -1638,8 +1602,7 @@ public class Logger {
resourceBundleName + " != " + name);
}
ResourceBundle rb = findResourceBundle(name);
if (rb == null) {
if (findResourceBundle(name) == null) {
// We've failed to find an expected ResourceBundle.
throw new MissingResourceException("Can't find " + name + " bundle", name, "");
}
......
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -23,13 +23,14 @@
/*
* @test
* @bug 7045594
* @bug 7045594 8002070
* @summary ResourceBundle setting race in Logger.getLogger(name, rbName)
* @author Daniel D. Daugherty
* @build RacingThreadsTest LoggerResourceBundleRace
* @run main LoggerResourceBundleRace
* @run main/othervm LoggerResourceBundleRace
*
* (In samevm mode, the bundle classes don't end up in the classpath.)
*/
import java.util.ListResourceBundle;
import java.util.MissingResourceException;
import java.util.concurrent.atomic.AtomicInteger;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册