Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
8356e9df
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
8356e9df
编写于
1月 10, 2013
作者:
M
mchung
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8005615: Java Logger fails to load tomcat logger implementation (JULI)
Reviewed-by: alanb, ahgross
上级
69aa950c
变更
5
显示空白变更内容
内联
并排
Showing
5 changed file
with
513 addition
and
140 deletion
+513
-140
src/share/classes/java/util/logging/LogManager.java
src/share/classes/java/util/logging/LogManager.java
+136
-127
src/share/classes/java/util/logging/Logger.java
src/share/classes/java/util/logging/Logger.java
+24
-13
test/java/util/logging/CustomLogManager.java
test/java/util/logging/CustomLogManager.java
+177
-0
test/java/util/logging/CustomLogManagerTest.java
test/java/util/logging/CustomLogManagerTest.java
+63
-0
test/java/util/logging/SimpleLogManager.java
test/java/util/logging/SimpleLogManager.java
+113
-0
未找到文件。
src/share/classes/java/util/logging/LogManager.java
浏览文件 @
8356e9df
...
...
@@ -158,7 +158,7 @@ public class LogManager {
// LoggerContext for system loggers and user loggers
private
final
LoggerContext
systemContext
=
new
SystemLoggerContext
();
private
final
LoggerContext
userContext
=
new
User
LoggerContext
();
private
final
LoggerContext
userContext
=
new
LoggerContext
();
private
Logger
rootLogger
;
// Have we done the primordial reading of the configuration file?
...
...
@@ -196,13 +196,13 @@ public class LogManager {
// Create and retain Logger for the root of the namespace.
manager
.
rootLogger
=
manager
.
new
RootLogger
();
manager
.
systemContext
.
addLogger
(
manager
.
rootLogger
);
manager
.
userContext
.
add
Logger
(
manager
.
rootLogger
);
manager
.
addLogger
(
manager
.
rootLogger
);
manager
.
systemContext
.
addLocal
Logger
(
manager
.
rootLogger
);
// Adding the global Logger. Doing so in the Logger.<clinit>
// would deadlock with the LogManager.<clinit>.
Logger
.
g
etGlobal
()
.
setLogManager
(
manager
);
manager
.
systemContext
.
addLogger
(
Logger
.
getGlobal
()
);
Logger
.
g
lobal
.
setLogManager
(
manager
);
manager
.
addLogger
(
Logger
.
global
);
// We don't call readConfiguration() here, as we may be running
// very early in the JVM startup sequence. Instead readConfiguration
...
...
@@ -373,7 +373,7 @@ public class LogManager {
// Returns the LoggerContext for the user code (i.e. application or AppContext).
// Loggers are isolated from each AppContext.
LoggerContext
getUserContext
()
{
private
LoggerContext
getUserContext
()
{
LoggerContext
context
=
null
;
SecurityManager
sm
=
System
.
getSecurityManager
();
...
...
@@ -394,8 +394,8 @@ public class LogManager {
if
(
javaAwtAccess
.
isMainAppContext
())
{
context
=
userContext
;
}
else
{
context
=
new
User
LoggerContext
();
context
.
addLogger
(
manager
.
rootLogger
);
context
=
new
LoggerContext
();
context
.
addLo
calLo
gger
(
manager
.
rootLogger
);
}
javaAwtAccess
.
put
(
ecx
,
LoggerContext
.
class
,
context
);
}
...
...
@@ -406,10 +406,6 @@ public class LogManager {
return
context
;
}
LoggerContext
getSystemContext
()
{
return
systemContext
;
}
private
List
<
LoggerContext
>
contexts
()
{
List
<
LoggerContext
>
cxs
=
new
ArrayList
<>();
cxs
.
add
(
systemContext
);
...
...
@@ -417,6 +413,58 @@ public class LogManager {
return
cxs
;
}
// Find or create a specified logger instance. If a logger has
// already been created with the given name it is returned.
// Otherwise a new logger instance is created and registered
// in the LogManager global namespace.
// This method will always return a non-null Logger object.
// Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by addLogger().
//
// This method must delegate to the LogManager implementation to
// add a new Logger or return the one that has been added previously
// as a LogManager subclass may override the addLogger, getLogger,
// readConfiguration, and other methods.
Logger
demandLogger
(
String
name
,
String
resourceBundleName
)
{
Logger
result
=
getLogger
(
name
);
if
(
result
==
null
)
{
// only allocate the new logger once
Logger
newLogger
=
new
Logger
(
name
,
resourceBundleName
);
do
{
if
(
addLogger
(
newLogger
))
{
// We successfully added the new Logger that we
// created above so return it without refetching.
return
newLogger
;
}
// We didn't add the new Logger that we created above
// because another thread added a Logger with the same
// name after our null check above and before our call
// to addLogger(). We have to refetch the Logger because
// addLogger() returns a boolean instead of the Logger
// reference itself. However, if the thread that created
// the other Logger is not holding a strong reference to
// the other Logger, then it is possible for the other
// Logger to be GC'ed after we saw it in addLogger() and
// before we can refetch it. If it has been GC'ed then
// we'll just loop around and try again.
result
=
getLogger
(
name
);
}
while
(
result
==
null
);
}
return
result
;
}
Logger
demandSystemLogger
(
String
name
,
String
resourceBundleName
)
{
return
systemContext
.
demandLogger
(
name
,
resourceBundleName
);
}
// LoggerContext maintains the logger namespace per context.
// The default LogManager implementation has one system context and user
// context. The system context is used to maintain the namespace for
// all system loggers and is queried by the system code. If a system logger
// doesn't exist in the user context, it'll also be added to the user context.
// The user context is queried by the user code and all other loggers are
// added in the user context.
static
class
LoggerContext
{
// Table of named Loggers that maps names to Loggers.
private
final
Hashtable
<
String
,
LoggerWeakRef
>
namedLoggers
=
new
Hashtable
<>();
...
...
@@ -427,6 +475,12 @@ public class LogManager {
this
.
root
=
new
LogNode
(
null
,
this
);
}
Logger
demandLogger
(
String
name
,
String
resourceBundleName
)
{
// a LogManager subclass may have its own implementation to add and
// get a Logger. So delegate to the LogManager to do the work.
return
manager
.
demandLogger
(
name
,
resourceBundleName
);
}
synchronized
Logger
findLogger
(
String
name
)
{
LoggerWeakRef
ref
=
namedLoggers
.
get
(
name
);
if
(
ref
==
null
)
{
...
...
@@ -441,7 +495,9 @@ public class LogManager {
return
logger
;
}
synchronized
boolean
addLogger
(
Logger
logger
)
{
// Add a logger to this context. This method will only set its level
// and process parent loggers. It doesn't set its handlers.
synchronized
boolean
addLocalLogger
(
Logger
logger
)
{
final
String
name
=
logger
.
getName
();
if
(
name
==
null
)
{
throw
new
NullPointerException
();
...
...
@@ -474,9 +530,9 @@ public class LogManager {
doSetLevel
(
logger
,
level
);
}
//
Do we have a per logger handler too?
//
Note: this will add a 200ms penalty
manager
.
loadLoggerHandlers
(
logger
,
name
,
name
+
".handlers"
);
//
instantiation of the handler is done in the LogManager.addLogger
//
implementation as a handler class may be only visible to LogManager
// subclass for the custom log manager case
processParentHandlers
(
logger
,
name
);
// Find the new node and its parent.
...
...
@@ -513,50 +569,21 @@ public class LogManager {
return
namedLoggers
.
keys
();
}
Logger
demandLogger
(
String
name
)
{
return
demandLogger
(
name
,
null
);
}
// Find or create a specified logger instance. If a logger has
// already been created with the given name it is returned.
// Otherwise a new logger instance is created and registered
// in the LogManager global namespace.
// This method will always return a non-null Logger object.
// Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by addLogger().
Logger
demandLogger
(
String
name
,
String
resourceBundleName
)
{
Logger
result
=
findLogger
(
name
);
if
(
result
==
null
)
{
// only allocate the new logger once
Logger
newLogger
=
new
Logger
(
name
,
resourceBundleName
);
do
{
if
(
addLogger
(
newLogger
))
{
// We successfully added the new Logger that we
// created above so return it without refetching.
return
newLogger
;
// If logger.getUseParentHandlers() returns 'true' and any of the logger's
// parents have levels or handlers defined, make sure they are instantiated.
private
void
processParentHandlers
(
final
Logger
logger
,
final
String
name
)
{
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
Void
>()
{
public
Void
run
()
{
if
(
logger
!=
manager
.
rootLogger
)
{
boolean
useParent
=
manager
.
getBooleanProperty
(
name
+
".useParentHandlers"
,
true
);
if
(!
useParent
)
{
logger
.
setUseParentHandlers
(
false
);
}
// We didn't add the new Logger that we created above
// because another thread added a Logger with the same
// name after our null check above and before our call
// to addLogger(). We have to refetch the Logger because
// addLogger() returns a boolean instead of the Logger
// reference itself. However, if the thread that created
// the other Logger is not holding a strong reference to
// the other Logger, then it is possible for the other
// Logger to be GC'ed after we saw it in addLogger() and
// before we can refetch it. If it has been GC'ed then
// we'll just loop around and try again.
result
=
findLogger
(
name
);
}
while
(
result
==
null
);
}
return
result
;
return
null
;
}
});
// If logger.getUseParentHandlers() returns 'true' and any of the logger's
// parents have levels or handlers defined, make sure they are instantiated.
private
void
processParentHandlers
(
Logger
logger
,
String
name
)
{
int
ix
=
1
;
for
(;;)
{
int
ix2
=
name
.
indexOf
(
"."
,
ix
);
...
...
@@ -564,12 +591,11 @@ public class LogManager {
break
;
}
String
pname
=
name
.
substring
(
0
,
ix2
);
if
(
manager
.
getProperty
(
pname
+
".level"
)
!=
null
||
manager
.
getProperty
(
pname
+
".handlers"
)
!=
null
)
{
// This pname has a level/handlers definition.
// Make sure it exists.
demandLogger
(
pname
);
demandLogger
(
pname
,
null
);
}
ix
=
ix2
+
1
;
}
...
...
@@ -607,39 +633,21 @@ public class LogManager {
}
static
class
SystemLoggerContext
extends
LoggerContext
{
// Default resource bundle for all system loggers
Logger
demandLogger
(
String
name
)
{
// default to use the system logger's resource bundle
return
super
.
demandLogger
(
name
,
Logger
.
SYSTEM_LOGGER_RB_NAME
);
}
}
static
class
UserLoggerContext
extends
LoggerContext
{
/**
* Returns a Logger of the given name if there is one registered
* in this context. Otherwise, it will return the one registered
* in the system context if there is one. The returned Logger
* instance may be initialized with a different resourceBundleName.
* If no such logger exists, a new Logger instance will be created
* and registered in this context.
*/
// Add a system logger in the system context's namespace as well as
// in the LogManager's namespace if not exist so that there is only
// one single logger of the given name. System loggers are visible
// to applications unless a logger of the same name has been added.
Logger
demandLogger
(
String
name
,
String
resourceBundleName
)
{
Logger
result
=
findLogger
(
name
);
if
(
result
==
null
)
{
// use the system logger if exists; or allocate a new logger.
// The system logger is added to the app logger context so that
// any child logger created in the app logger context can have
// a system logger as its parent if already exist.
Logger
logger
=
manager
.
systemContext
.
findLogger
(
name
);
Logger
newLogger
=
logger
!=
null
?
logger
:
new
Logger
(
name
,
resourceBundleName
);
// only allocate the new system logger once
Logger
newLogger
=
new
Logger
(
name
,
resourceBundleName
);
do
{
if
(
addLogger
(
newLogger
))
{
if
(
addLo
calLo
gger
(
newLogger
))
{
// We successfully added the new Logger that we
// created above so return it without refetching.
return
newLogger
;
}
result
=
newLogger
;
}
else
{
// We didn't add the new Logger that we created above
// because another thread added a Logger with the same
// name after our null check above and before our call
...
...
@@ -652,8 +660,24 @@ public class LogManager {
// before we can refetch it. If it has been GC'ed then
// we'll just loop around and try again.
result
=
findLogger
(
name
);
}
}
while
(
result
==
null
);
}
// Add the system logger to the LogManager's namespace if not exists
// The LogManager will set its handlers via the LogManager.addLogger method.
if
(!
manager
.
addLogger
(
result
)
&&
result
.
getHandlers
().
length
==
0
)
{
// if logger already exists but handlers not set
final
Logger
l
=
manager
.
getLogger
(
name
);
final
Logger
logger
=
result
;
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
Void
>()
{
public
Void
run
()
{
for
(
Handler
hdl
:
l
.
getHandlers
())
{
logger
.
addHandler
(
hdl
);
}
return
null
;
}
});
}
return
result
;
}
}
...
...
@@ -663,16 +687,10 @@ public class LogManager {
// be made based on the logging configuration, which can
// only be modified by trusted code.
private
void
loadLoggerHandlers
(
final
Logger
logger
,
final
String
name
,
final
String
handlersPropertyName
)
{
final
String
handlersPropertyName
)
{
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
Object
>()
{
public
Object
run
()
{
if
(
logger
!=
rootLogger
)
{
boolean
useParent
=
getBooleanProperty
(
name
+
".useParentHandlers"
,
true
);
if
(!
useParent
)
{
logger
.
setUseParentHandlers
(
false
);
}
}
String
names
[]
=
parseClassNames
(
handlersPropertyName
);
for
(
int
i
=
0
;
i
<
names
.
length
;
i
++)
{
String
word
=
names
[
i
];
...
...
@@ -700,7 +718,8 @@ public class LogManager {
}
}
return
null
;
}});
}
});
}
...
...
@@ -839,13 +858,17 @@ public class LogManager {
if
(
name
==
null
)
{
throw
new
NullPointerException
();
}
if
(
systemContext
.
findLogger
(
name
)
!=
null
)
{
LoggerContext
cx
=
getUserContext
();
if
(
cx
.
addLocalLogger
(
logger
))
{
// Do we have a per logger handler too?
// Note: this will add a 200ms penalty
loadLoggerHandlers
(
logger
,
name
,
name
+
".handlers"
);
return
true
;
}
else
{
return
false
;
}
return
getUserContext
().
addLogger
(
logger
);
}
// Private method to set a level on a logger.
// If necessary, we raise privilege before doing the call.
private
static
void
doSetLevel
(
final
Logger
logger
,
final
Level
level
)
{
...
...
@@ -864,8 +887,6 @@ public class LogManager {
}});
}
// Private method to set a parent on a logger.
// If necessary, we raise privilege before doing the setParent call.
private
static
void
doSetParent
(
final
Logger
logger
,
final
Logger
parent
)
{
...
...
@@ -900,15 +921,7 @@ public class LogManager {
* @return matching logger or null if none is found
*/
public
Logger
getLogger
(
String
name
)
{
// return the first logger added
//
// once a system logger is added in the system context, no one can
// adds a logger with the same name in the global context
// (see LogManager.addLogger). So if there is a logger in the global
// context with the same name as one in the system context, it must be
// added before the system logger was created.
Logger
logger
=
getUserContext
().
findLogger
(
name
);
return
logger
!=
null
?
logger
:
systemContext
.
findLogger
(
name
);
return
getUserContext
().
findLogger
(
name
);
}
/**
...
...
@@ -928,10 +941,7 @@ public class LogManager {
* @return enumeration of logger name strings
*/
public
Enumeration
<
String
>
getLoggerNames
()
{
// only return unique names
Set
<
String
>
names
=
new
HashSet
<>(
Collections
.
list
(
systemContext
.
getLoggerNames
()));
names
.
addAll
(
Collections
.
list
(
getUserContext
().
getLoggerNames
()));
return
Collections
.
enumeration
(
names
);
return
getUserContext
().
getLoggerNames
();
}
/**
...
...
@@ -1329,7 +1339,6 @@ public class LogManager {
// that we only instantiate the global handlers when they
// are first needed.
private
class
RootLogger
extends
Logger
{
private
RootLogger
()
{
super
(
""
,
null
);
setLevel
(
defaultLevel
);
...
...
src/share/classes/java/util/logging/Logger.java
浏览文件 @
8356e9df
...
...
@@ -31,7 +31,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
import
java.security.*
;
import
java.lang.ref.WeakReference
;
import
java.util.function.Supplier
;
import
java.util.logging.LogManager.LoggerContext
;
/**
* A Logger object is used to log messages for a specific
...
...
@@ -321,18 +320,32 @@ public class Logger {
//
// As an interim solution, if the immediate caller whose caller loader is
// null, we assume it's a system logger and add it to the system context.
private
static
LoggerContext
getLoggerContext
()
{
// These system loggers only set the resource bundle to the given
// resource bundle name (rather than the default system resource bundle).
private
static
class
SystemLoggerHelper
{
static
boolean
disableCallerCheck
=
getBooleanProperty
(
"sun.util.logging.disableCallerCheck"
);
private
static
boolean
getBooleanProperty
(
final
String
key
)
{
String
s
=
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
String
>()
{
public
String
run
()
{
return
System
.
getProperty
(
key
);
}
});
return
Boolean
.
valueOf
(
s
);
}
}
private
static
Logger
demandLogger
(
String
name
,
String
resourceBundleName
)
{
LogManager
manager
=
LogManager
.
getLogManager
();
SecurityManager
sm
=
System
.
getSecurityManager
();
if
(
sm
!=
null
)
{
// 0: Reflection 1: Logger.
getLoggerContext
2: Logger.getLogger 3: caller
if
(
sm
!=
null
&&
!
SystemLoggerHelper
.
disableCallerCheck
)
{
// 0: Reflection 1: Logger.
demandLogger
2: Logger.getLogger 3: caller
final
int
SKIP_FRAMES
=
3
;
Class
<?>
caller
=
sun
.
reflect
.
Reflection
.
getCallerClass
(
SKIP_FRAMES
);
if
(
caller
.
getClassLoader
()
==
null
)
{
return
manager
.
getSystemContext
(
);
return
manager
.
demandSystemLogger
(
name
,
resourceBundleName
);
}
}
return
manager
.
getUserContext
(
);
return
manager
.
demandLogger
(
name
,
resourceBundleName
);
}
/**
...
...
@@ -376,8 +389,7 @@ public class Logger {
// would throw an IllegalArgumentException in the second call
// because the wrapper would result in an attempt to replace
// the existing "resourceBundleForFoo" with null.
LoggerContext
context
=
getLoggerContext
();
return
context
.
demandLogger
(
name
);
return
demandLogger
(
name
,
null
);
}
/**
...
...
@@ -424,8 +436,7 @@ public class Logger {
// Synchronization is not required here. All synchronization for
// adding a new Logger object is handled by LogManager.addLogger().
public
static
Logger
getLogger
(
String
name
,
String
resourceBundleName
)
{
LoggerContext
context
=
getLoggerContext
();
Logger
result
=
context
.
demandLogger
(
name
,
resourceBundleName
);
Logger
result
=
demandLogger
(
name
,
resourceBundleName
);
// MissingResourceException or IllegalArgumentException can be
// thrown by setupResourceInfo().
...
...
@@ -438,11 +449,10 @@ public class Logger {
// i.e. caller of sun.util.logging.PlatformLogger.getLogger
static
Logger
getPlatformLogger
(
String
name
)
{
LogManager
manager
=
LogManager
.
getLogManager
();
LoggerContext
context
=
manager
.
getSystemContext
();
// all loggers in the system context will default to
// the system logger's resource bundle
Logger
result
=
context
.
demandLogger
(
name
);
Logger
result
=
manager
.
demandSystemLogger
(
name
,
SYSTEM_LOGGER_RB_NAME
);
return
result
;
}
...
...
@@ -1588,7 +1598,8 @@ public class Logger {
public
ResourceBundle
run
()
{
try
{
return
ResourceBundle
.
getBundle
(
SYSTEM_LOGGER_RB_NAME
,
locale
);
locale
,
ClassLoader
.
getSystemClassLoader
());
}
catch
(
MissingResourceException
e
)
{
throw
new
InternalError
(
e
.
toString
());
}
...
...
test/java/util/logging/CustomLogManager.java
0 → 100644
浏览文件 @
8356e9df
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.io.*
;
import
java.util.*
;
import
java.util.logging.*
;
/*
* Custom LogManager implementation to verify that the implementation delegates
* to the LogManager subclass to register both system logger and user logger.
*
* The LogManager implementation is the one configuring the logger's property
* such as level, handler, etc.
*/
public
class
CustomLogManager
extends
LogManager
{
static
LogManager
INSTANCE
;
Map
<
String
,
Logger
>
namedLoggers
=
new
HashMap
<>();
Properties
props
=
initConfig
();
public
CustomLogManager
()
{
if
(
INSTANCE
!=
null
)
{
throw
new
RuntimeException
(
"CustomLogManager already created"
);
}
INSTANCE
=
this
;
}
public
synchronized
boolean
addLogger
(
Logger
logger
)
{
String
name
=
logger
.
getName
();
if
(
namedLoggers
.
containsKey
(
name
))
{
return
false
;
}
namedLoggers
.
put
(
name
,
logger
);
// set level
if
(
props
.
get
(
name
+
".level"
)
!=
null
)
{
logger
.
setLevel
(
Level
.
parse
(
props
.
getProperty
(
name
+
".level"
)));
}
// add handlers
if
(
props
.
get
(
name
+
".handlers"
)
!=
null
&&
logger
.
getHandlers
().
length
==
0
)
{
logger
.
addHandler
(
new
CustomHandler
());
}
// add parent loggers
int
ix
=
1
;
for
(;;)
{
int
ix2
=
name
.
indexOf
(
"."
,
ix
);
if
(
ix2
<
0
)
{
break
;
}
String
pname
=
name
.
substring
(
0
,
ix2
);
if
(
props
.
get
(
pname
+
".level"
)
!=
null
||
props
.
get
(
pname
+
".handlers"
)
!=
null
)
{
// This pname has a level/handlers definition.
// Make sure it exists.
//
// The test doesn't set the parent for simplicity.
if
(!
namedLoggers
.
containsKey
(
pname
))
{
Logger
.
getLogger
(
pname
);
}
}
ix
=
ix2
+
1
;
}
return
true
;
}
public
synchronized
Logger
getLogger
(
String
name
)
{
return
namedLoggers
.
get
(
name
);
}
public
synchronized
Enumeration
<
String
>
getLoggerNames
()
{
return
Collections
.
enumeration
(
namedLoggers
.
keySet
());
}
public
String
getProperty
(
String
name
)
{
return
props
.
getProperty
(
name
);
}
public
void
readConfiguration
()
{
// do nothing
}
public
void
readConfiguration
(
InputStream
ins
)
{
// do nothing
}
private
Properties
initConfig
()
{
Properties
props
=
new
Properties
();
props
.
put
(
".level"
,
"CONFIG"
);
props
.
put
(
"CustomLogManagerTest.level"
,
"WARNING"
);
props
.
put
(
"CustomLogManagerTest.handlers"
,
"CustomLogManager$CustomHandler"
);
props
.
put
(
"SimpleLogManager.level"
,
"INFO"
);
props
.
put
(
"SimpleLogManager.handlers"
,
"CustomLogManager$CustomHandler"
);
props
.
put
(
"CustomLogManager$CustomHandler.level"
,
"WARNING"
);
props
.
put
(
".handlers"
,
"CustomLogManager$CustomHandler"
);
props
.
put
(
"org.foo.bar.level"
,
"SEVERE"
);
props
.
put
(
"org.foo.handlers"
,
"CustomLogManager$CustomHandler"
);
props
.
put
(
"org.openjdk.level"
,
"SEVERE"
);
props
.
put
(
"org.openjdk.handlers"
,
"CustomLogManager$CustomHandler"
);
props
.
put
(
"org.openjdk.core.level"
,
"INFO"
);
return
props
;
}
public
static
void
checkLogger
(
String
name
)
{
checkLogger
(
name
,
null
);
}
public
static
void
checkLogger
(
String
name
,
String
resourceBundleName
)
{
Logger
logger
=
INSTANCE
.
getLogger
(
name
);
if
(
logger
==
null
)
{
throw
new
RuntimeException
(
"Logger \""
+
name
+
"\" not exist"
);
}
System
.
out
.
format
(
"Logger \"%s\" level=%s handlers=%s resourcebundle=%s%n"
,
name
,
logger
.
getLevel
(),
Arrays
.
toString
(
logger
.
getHandlers
()),
logger
.
getResourceBundleName
());
String
rb
=
logger
.
getResourceBundleName
();
if
(
rb
!=
resourceBundleName
&&
(
rb
==
null
||
rb
.
equals
(
resourceBundleName
)))
{
throw
new
RuntimeException
(
"Logger \""
+
name
+
"\" unexpected resource bundle: "
+
rb
);
}
String
value
=
INSTANCE
.
getProperty
(
name
+
".level"
);
String
level
=
logger
.
getLevel
()
!=
null
?
logger
.
getLevel
().
getName
()
:
null
;
if
(
level
!=
value
&&
(
level
==
null
||
level
.
equals
(
value
)))
{
throw
new
RuntimeException
(
"Logger \""
+
name
+
"\" unexpected level: "
+
level
);
}
Handler
[]
handlers
=
logger
.
getHandlers
();
String
hdl
=
INSTANCE
.
getProperty
(
name
+
".handlers"
);
if
((
hdl
==
null
&&
handlers
.
length
!=
0
)
||
(
hdl
!=
null
&&
handlers
.
length
!=
1
))
{
throw
new
RuntimeException
(
"Logger \""
+
name
+
"\" unexpected handler: "
+
Arrays
.
toString
(
handlers
));
}
checkParents
(
name
);
}
private
static
void
checkParents
(
String
name
)
{
int
ix
=
1
;
for
(;;)
{
int
ix2
=
name
.
indexOf
(
"."
,
ix
);
if
(
ix2
<
0
)
{
break
;
}
String
pname
=
name
.
substring
(
0
,
ix2
);
if
(
INSTANCE
.
getProperty
(
pname
+
".level"
)
!=
null
||
INSTANCE
.
getProperty
(
pname
+
".handlers"
)
!=
null
)
{
// This pname has a level/handlers definition.
// Make sure it exists.
checkLogger
(
pname
);
}
ix
=
ix2
+
1
;
}
}
// only CustomLogManager can create an instance of CustomHandler
private
class
CustomHandler
extends
StreamHandler
{
}
}
test/java/util/logging/CustomLogManagerTest.java
0 → 100644
浏览文件 @
8356e9df
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.io.*
;
import
java.util.*
;
import
java.util.logging.*
;
import
sun.util.logging.PlatformLogger
;
/*
* @test
* @bug 8005615
* @summary Add loggers to custom log manager
*
* @compile -XDignore.symbol.file CustomLogManagerTest.java CustomLogManager.java
* @run main/othervm -Djava.util.logging.manager=CustomLogManager CustomLogManagerTest
*/
public
class
CustomLogManagerTest
{
private
static
final
String
RESOURCE_BUNDLE
=
"sun.util.logging.resources.logging"
;
public
static
void
main
(
String
[]
args
)
{
String
mgr
=
System
.
getProperty
(
"java.util.logging.manager"
);
if
(!
mgr
.
equals
(
"CustomLogManager"
))
{
throw
new
RuntimeException
(
"java.util.logging.manager not set"
);
}
Logger
.
getLogger
(
CustomLogManagerTest
.
class
.
getName
());
Logger
.
getLogger
(
"org.foo.Foo"
);
Logger
.
getLogger
(
"org.foo.bar.Foo"
,
RESOURCE_BUNDLE
);
// platform logger will be set with the default system resource bundle
PlatformLogger
.
getLogger
(
"org.openjdk.core.logger"
);
if
(
LogManager
.
getLogManager
()
!=
CustomLogManager
.
INSTANCE
)
{
throw
new
RuntimeException
(
LogManager
.
getLogManager
()
+
" not CustomLogManager"
);
}
CustomLogManager
.
checkLogger
(
CustomLogManagerTest
.
class
.
getName
());
CustomLogManager
.
checkLogger
(
"org.foo.Foo"
);
CustomLogManager
.
checkLogger
(
"org.foo.bar.Foo"
,
RESOURCE_BUNDLE
);
CustomLogManager
.
checkLogger
(
Logger
.
GLOBAL_LOGGER_NAME
);
CustomLogManager
.
checkLogger
(
""
);
CustomLogManager
.
checkLogger
(
"org.openjdk.core.logger"
,
RESOURCE_BUNDLE
);
}
}
test/java/util/logging/SimpleLogManager.java
0 → 100644
浏览文件 @
8356e9df
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import
java.util.*
;
import
java.util.logging.*
;
import
sun.util.logging.PlatformLogger
;
/*
* @test
* @bug 8005615
* @summary A LogManager subclass overrides its own implementation of named
* logger (see the subclassing information in the Logger class specification)
*
* @compile -XDignore.symbol.file CustomLogManager.java SimpleLogManager.java
* @run main/othervm -Djava.util.logging.manager=SimpleLogManager SimpleLogManager
*/
public
class
SimpleLogManager
extends
CustomLogManager
{
public
static
void
main
(
String
[]
args
)
{
String
classname
=
System
.
getProperty
(
"java.util.logging.manager"
);
if
(!
classname
.
equals
(
"SimpleLogManager"
))
{
throw
new
RuntimeException
(
"java.util.logging.manager not set"
);
}
Logger
logger
=
Logger
.
getLogger
(
SimpleLogManager
.
class
.
getName
());
Logger
.
getLogger
(
"org.foo.bar.Foo"
);
// a platform logger used by the system code is just a Logger instance.
PlatformLogger
.
getLogger
(
"org.openjdk.core.logger"
);
LogManager
mgr
=
LogManager
.
getLogManager
();
if
(
mgr
!=
CustomLogManager
.
INSTANCE
||
!(
mgr
instanceof
SimpleLogManager
))
{
throw
new
RuntimeException
(
LogManager
.
getLogManager
()
+
" not SimpleLogManager"
);
}
checkCustomLogger
(
SimpleLogManager
.
class
.
getName
(),
null
);
checkCustomLogger
(
"org.foo.bar.Foo"
,
null
);
checkCustomLogger
(
"org.openjdk.core.logger"
,
"sun.util.logging.resources.logging"
);
// ## The LogManager.demandLogger method does not handle custom log manager
// ## that overrides the getLogger method to return a custom logger
// ## (see the test case in 8005640). Logger.getLogger may return
// ## a Logger instance but LogManager overrides it with a custom Logger
// ## instance like this case.
//
// However, the specification of LogManager and Logger subclassing is
// not clear whether this is supported or not. The following check
// just captures the current behavior.
if
(
logger
instanceof
CustomLogger
)
{
throw
new
RuntimeException
(
logger
+
" not CustomLogger"
);
}
}
private
static
void
checkCustomLogger
(
String
name
,
String
resourceBundleName
)
{
CustomLogManager
.
checkLogger
(
name
,
resourceBundleName
);
Logger
logger1
=
Logger
.
getLogger
(
name
);
Logger
logger2
=
LogManager
.
getLogManager
().
getLogger
(
name
);
if
(
logger1
!=
logger2
)
{
throw
new
RuntimeException
(
logger1
+
" != "
+
logger2
);
}
if
(!(
logger1
instanceof
CustomLogger
))
{
throw
new
RuntimeException
(
logger1
+
" not CustomLogger"
);
}
}
/*
* This SimpleLogManager overrides the addLogger method to replace
* the given logger with a custom logger.
*
* It's unclear what the recommended way to use custom logger is.
* A LogManager subclass might override the getLogger method to return
* a custom Logger and create a new custom logger if not exist so that
* Logger.getLogger() can return a custom Logger instance but that violates
* the LogManager.getLogger() spec which should return null if not found.
*/
public
synchronized
boolean
addLogger
(
Logger
logger
)
{
String
name
=
logger
.
getName
();
if
(
namedLoggers
.
containsKey
(
name
))
{
return
false
;
}
CustomLogger
newLogger
=
new
CustomLogger
(
logger
);
super
.
addLogger
(
newLogger
);
return
true
;
}
public
class
CustomLogger
extends
Logger
{
CustomLogger
(
Logger
logger
)
{
super
(
logger
.
getName
(),
logger
.
getResourceBundleName
());
}
CustomLogger
(
String
name
)
{
super
(
name
,
null
);
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录