Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
8b5d3f94
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
3
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看板
体验新版 GitCode,发现更多精彩内容 >>
提交
8b5d3f94
编写于
7月 31, 2008
作者:
D
dfuchs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6730926: Document that create/registerMBean can throw RuntimeMBeanException from postRegister
Reviewed-by: emcmanus
上级
be479f20
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
693 addition
and
19 deletion
+693
-19
src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java
...om/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java
+39
-14
src/share/classes/javax/management/MBeanRegistration.java
src/share/classes/javax/management/MBeanRegistration.java
+24
-1
src/share/classes/javax/management/MBeanServer.java
src/share/classes/javax/management/MBeanServer.java
+19
-0
src/share/classes/javax/management/MBeanServerConnection.java
...share/classes/javax/management/MBeanServerConnection.java
+95
-4
test/javax/management/MBeanServer/PostExceptionTest.java
test/javax/management/MBeanServer/PostExceptionTest.java
+516
-0
未找到文件。
src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java
浏览文件 @
8b5d3f94
...
...
@@ -453,11 +453,12 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
final
ResourceContext
context
=
unregisterFromRepository
(
resource
,
instance
,
name
);
if
(
instance
instanceof
MBeanRegistration
)
postDeregisterInvoke
((
MBeanRegistration
)
instance
);
context
.
done
();
try
{
if
(
instance
instanceof
MBeanRegistration
)
postDeregisterInvoke
(
name
,(
MBeanRegistration
)
instance
);
}
finally
{
context
.
done
();
}
}
public
ObjectInstance
getObjectInstance
(
ObjectName
name
)
...
...
@@ -989,10 +990,12 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
registerFailed
=
false
;
registered
=
true
;
}
finally
{
postRegister
(
mbean
,
registered
,
registerFailed
);
try
{
postRegister
(
logicalName
,
mbean
,
registered
,
registerFailed
);
}
finally
{
if
(
registered
)
context
.
done
();
}
}
context
.
done
();
return
new
ObjectInstance
(
logicalName
,
classname
);
}
...
...
@@ -1051,7 +1054,8 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
}
private
static
void
postRegister
(
DynamicMBean
mbean
,
boolean
registrationDone
,
boolean
registerFailed
)
{
ObjectName
logicalName
,
DynamicMBean
mbean
,
boolean
registrationDone
,
boolean
registerFailed
)
{
if
(
registerFailed
&&
mbean
instanceof
DynamicMBean2
)
((
DynamicMBean2
)
mbean
).
registerFailed
();
...
...
@@ -1059,11 +1063,19 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
if
(
mbean
instanceof
MBeanRegistration
)
((
MBeanRegistration
)
mbean
).
postRegister
(
registrationDone
);
}
catch
(
RuntimeException
e
)
{
MBEANSERVER_LOGGER
.
fine
(
"While registering MBean ["
+
logicalName
+
"]: "
+
"Exception thrown by postRegister: "
+
"rethrowing <"
+
e
+
">, but keeping the MBean registered"
);
throw
new
RuntimeMBeanException
(
e
,
"RuntimeException thrown in postRegister method"
);
"RuntimeException thrown in postRegister method: "
+
"rethrowing <"
+
e
+
">, but keeping the MBean registered"
);
}
catch
(
Error
er
)
{
MBEANSERVER_LOGGER
.
fine
(
"While registering MBean ["
+
logicalName
+
"]: "
+
"Error thrown by postRegister: "
+
"rethrowing <"
+
er
+
">, but keeping the MBean registered"
);
throw
new
RuntimeErrorException
(
er
,
"Error thrown in postRegister method"
);
"Error thrown in postRegister method: "
+
"rethrowing <"
+
er
+
">, but keeping the MBean registered"
);
}
}
...
...
@@ -1076,15 +1088,28 @@ public class DefaultMBeanServerInterceptor implements MBeanServerInterceptor {
}
}
private
static
void
postDeregisterInvoke
(
MBeanRegistration
moi
)
{
private
static
void
postDeregisterInvoke
(
ObjectName
mbean
,
MBeanRegistration
moi
)
{
try
{
moi
.
postDeregister
();
}
catch
(
RuntimeException
e
)
{
MBEANSERVER_LOGGER
.
fine
(
"While unregistering MBean ["
+
mbean
+
"]: "
+
"Exception thrown by postDeregister: "
+
"rethrowing <"
+
e
+
">, although the MBean is succesfully "
+
"unregistered"
);
throw
new
RuntimeMBeanException
(
e
,
"RuntimeException thrown in postDeregister method"
);
"RuntimeException thrown in postDeregister method: "
+
"rethrowing <"
+
e
+
">, although the MBean is sucessfully unregistered"
);
}
catch
(
Error
er
)
{
MBEANSERVER_LOGGER
.
fine
(
"While unregistering MBean ["
+
mbean
+
"]: "
+
"Error thrown by postDeregister: "
+
"rethrowing <"
+
er
+
">, although the MBean is succesfully "
+
"unregistered"
);
throw
new
RuntimeErrorException
(
er
,
"Error thrown in postDeregister method"
);
"Error thrown in postDeregister method: "
+
"rethrowing <"
+
er
+
">, although the MBean is sucessfully unregistered"
);
}
}
...
...
src/share/classes/javax/management/MBeanRegistration.java
浏览文件 @
8b5d3f94
...
...
@@ -158,7 +158,19 @@ public interface MBeanRegistration {
/**
* Allows the MBean to perform any operations needed after having been
* registered in the MBean server or after the registration has failed.
*
* <p>If the implementation of this method throws a {@link RuntimeException}
* or an {@link Error}, the MBean Server will rethrow those inside
* a {@link RuntimeMBeanException} or {@link RuntimeErrorException},
* respectively. However, throwing an exception in {@code postRegister}
* will not change the state of the MBean:
* if the MBean was already registered ({@code registrationDone} is
* {@code true}), the MBean will remain registered. </p>
* <p>This might be confusing for the code calling {@code createMBean()}
* or {@code registerMBean()}, as such code might assume that MBean
* registration has failed when such an exception is raised.
* Therefore it is recommended that implementations of
* {@code postRegister} do not throw Runtime Exceptions or Errors if it
* can be avoided.</p>
* @param registrationDone Indicates whether or not the MBean has
* been successfully registered in the MBean server. The value
* false means that the registration phase has failed.
...
...
@@ -178,6 +190,17 @@ public interface MBeanRegistration {
/**
* Allows the MBean to perform any operations needed after having been
* unregistered in the MBean server.
* <p>If the implementation of this method throws a {@link RuntimeException}
* or an {@link Error}, the MBean Server will rethrow those inside
* a {@link RuntimeMBeanException} or {@link RuntimeErrorException},
* respectively. However, throwing an excepption in {@code postDeregister}
* will not change the state of the MBean:
* the MBean was already successfully deregistered and will remain so. </p>
* <p>This might be confusing for the code calling
* {@code unregisterMBean()}, as it might assume that MBean deregistration
* has failed. Therefore it is recommended that implementations of
* {@code postDeregister} do not throw Runtime Exceptions or Errors if it
* can be avoided.</p>
*/
public
void
postDeregister
();
...
...
src/share/classes/javax/management/MBeanServer.java
浏览文件 @
8b5d3f94
...
...
@@ -328,11 +328,30 @@ public interface MBeanServer extends MBeanServerConnection {
* <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
* interface) method of the MBean has thrown an exception. The
* MBean will not be registered.
* @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
* <CODE>RuntimeException</CODE>, the <CODE>registerMBean<CODE> method will
* throw a <CODE>RuntimeMBeanException</CODE>, although the MBean
* registration succeeded. In such a case, the MBean will be actually
* registered even though the <CODE>registerMBean<CODE> method
* threw an exception. Note that <CODE>RuntimeMBeanException</CODE> can
* also be thrown by <CODE>preRegister</CODE>, in which case the MBean
* will not be registered.
* @exception RuntimeErrorException If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws an
* <CODE>Error</CODE>, the <CODE>registerMBean<CODE> method will
* throw a <CODE>RuntimeErrorException</CODE>, although the MBean
* registration succeeded. In such a case, the MBean will be actually
* registered even though the <CODE>registerMBean<CODE> method
* threw an exception. Note that <CODE>RuntimeErrorException</CODE> can
* also be thrown by <CODE>preRegister</CODE>, in which case the MBean
* will not be registered.
* @exception NotCompliantMBeanException This object is not a JMX
* compliant MBean
* @exception RuntimeOperationsException Wraps a
* <CODE>java.lang.IllegalArgumentException</CODE>: The object
* passed in parameter is null or no object name is specified.
* @see javax.management.MBeanRegistration
*/
public
ObjectInstance
registerMBean
(
Object
object
,
ObjectName
name
)
throws
InstanceAlreadyExistsException
,
MBeanRegistrationException
,
...
...
src/share/classes/javax/management/MBeanServerConnection.java
浏览文件 @
8b5d3f94
...
...
@@ -75,6 +75,24 @@ public interface MBeanServerConnection {
* <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
* interface) method of the MBean has thrown an exception. The
* MBean will not be registered.
* @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
* <CODE>RuntimeException</CODE>, the <CODE>createMBean<CODE> method will
* throw a <CODE>RuntimeMBeanException</CODE>, although the MBean creation
* and registration succeeded. In such a case, the MBean will be actually
* registered even though the <CODE>createMBean<CODE> method
* threw an exception. Note that <CODE>RuntimeMBeanException</CODE> can
* also be thrown by <CODE>preRegister</CODE>, in which case the MBean
* will not be registered.
* @exception RuntimeErrorException If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws an
* <CODE>Error</CODE>, the <CODE>createMBean<CODE> method will
* throw a <CODE>RuntimeErrorException</CODE>, although the MBean creation
* and registration succeeded. In such a case, the MBean will be actually
* registered even though the <CODE>createMBean<CODE> method
* threw an exception. Note that <CODE>RuntimeErrorException</CODE> can
* also be thrown by <CODE>preRegister</CODE>, in which case the MBean
* will not be registered.
* @exception MBeanException The constructor of the MBean has
* thrown an exception
* @exception NotCompliantMBeanException This class is not a JMX
...
...
@@ -86,7 +104,7 @@ public interface MBeanServerConnection {
* is specified for the MBean.
* @exception IOException A communication problem occurred when
* talking to the MBean server.
*
*
@see javax.management.MBeanRegistration
*/
public
ObjectInstance
createMBean
(
String
className
,
ObjectName
name
)
throws
ReflectionException
,
InstanceAlreadyExistsException
,
...
...
@@ -129,6 +147,24 @@ public interface MBeanServerConnection {
* <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
* interface) method of the MBean has thrown an exception. The
* MBean will not be registered.
* @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
* <CODE>RuntimeException</CODE>, the <CODE>createMBean<CODE> method will
* throw a <CODE>RuntimeMBeanException</CODE>, although the MBean creation
* and registration succeeded. In such a case, the MBean will be actually
* registered even though the <CODE>createMBean<CODE> method
* threw an exception. Note that <CODE>RuntimeMBeanException</CODE> can
* also be thrown by <CODE>preRegister</CODE>, in which case the MBean
* will not be registered.
* @exception RuntimeErrorException If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws an
* <CODE>Error</CODE>, the <CODE>createMBean<CODE> method will
* throw a <CODE>RuntimeErrorException</CODE>, although the MBean creation
* and registration succeeded. In such a case, the MBean will be actually
* registered even though the <CODE>createMBean<CODE> method
* threw an exception. Note that <CODE>RuntimeErrorException</CODE> can
* also be thrown by <CODE>preRegister</CODE>, in which case the MBean
* will not be registered.
* @exception MBeanException The constructor of the MBean has
* thrown an exception
* @exception NotCompliantMBeanException This class is not a JMX
...
...
@@ -142,6 +178,7 @@ public interface MBeanServerConnection {
* is specified for the MBean.
* @exception IOException A communication problem occurred when
* talking to the MBean server.
* @see javax.management.MBeanRegistration
*/
public
ObjectInstance
createMBean
(
String
className
,
ObjectName
name
,
ObjectName
loaderName
)
...
...
@@ -185,6 +222,24 @@ public interface MBeanServerConnection {
* <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
* interface) method of the MBean has thrown an exception. The
* MBean will not be registered.
* @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
* <CODE>RuntimeException</CODE>, the <CODE>createMBean<CODE> method will
* throw a <CODE>RuntimeMBeanException</CODE>, although the MBean creation
* and registration succeeded. In such a case, the MBean will be actually
* registered even though the <CODE>createMBean<CODE> method
* threw an exception. Note that <CODE>RuntimeMBeanException</CODE> can
* also be thrown by <CODE>preRegister</CODE>, in which case the MBean
* will not be registered.
* @exception RuntimeErrorException If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws an
* <CODE>Error</CODE>, the <CODE>createMBean<CODE> method will
* throw a <CODE>RuntimeErrorException</CODE>, although the MBean creation
* and registration succeeded. In such a case, the MBean will be actually
* registered even though the <CODE>createMBean<CODE> method
* threw an exception. Note that <CODE>RuntimeErrorException</CODE> can
* also be thrown by <CODE>preRegister</CODE>, in which case the MBean
* will not be registered.
* @exception MBeanException The constructor of the MBean has
* thrown an exception
* @exception NotCompliantMBeanException This class is not a JMX
...
...
@@ -196,7 +251,7 @@ public interface MBeanServerConnection {
* is specified for the MBean.
* @exception IOException A communication problem occurred when
* talking to the MBean server.
*
*
@see javax.management.MBeanRegistration
*/
public
ObjectInstance
createMBean
(
String
className
,
ObjectName
name
,
Object
params
[],
String
signature
[])
...
...
@@ -239,6 +294,24 @@ public interface MBeanServerConnection {
* <CODE>preRegister</CODE> (<CODE>MBeanRegistration</CODE>
* interface) method of the MBean has thrown an exception. The
* MBean will not be registered.
* @exception RuntimeMBeanException If the <CODE>postRegister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
* <CODE>RuntimeException</CODE>, the <CODE>createMBean<CODE> method will
* throw a <CODE>RuntimeMBeanException</CODE>, although the MBean creation
* and registration succeeded. In such a case, the MBean will be actually
* registered even though the <CODE>createMBean<CODE> method
* threw an exception. Note that <CODE>RuntimeMBeanException</CODE> can
* also be thrown by <CODE>preRegister</CODE>, in which case the MBean
* will not be registered.
* @exception RuntimeErrorException If the <CODE>postRegister</CODE> method
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws an
* <CODE>Error</CODE>, the <CODE>createMBean<CODE> method will
* throw a <CODE>RuntimeErrorException</CODE>, although the MBean creation
* and registration succeeded. In such a case, the MBean will be actually
* registered even though the <CODE>createMBean<CODE> method
* threw an exception. Note that <CODE>RuntimeErrorException</CODE> can
* also be thrown by <CODE>preRegister</CODE>, in which case the MBean
* will not be registered.
* @exception MBeanException The constructor of the MBean has
* thrown an exception
* @exception NotCompliantMBeanException This class is not a JMX
...
...
@@ -252,7 +325,7 @@ public interface MBeanServerConnection {
* is specified for the MBean.
* @exception IOException A communication problem occurred when
* talking to the MBean server.
*
*
@see javax.management.MBeanRegistration
*/
public
ObjectInstance
createMBean
(
String
className
,
ObjectName
name
,
ObjectName
loaderName
,
Object
params
[],
...
...
@@ -275,6 +348,24 @@ public interface MBeanServerConnection {
* @exception MBeanRegistrationException The preDeregister
* ((<CODE>MBeanRegistration</CODE> interface) method of the MBean
* has thrown an exception.
* @exception RuntimeMBeanException If the <CODE>postDeregister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws a
* <CODE>RuntimeException</CODE>, the <CODE>unregisterMBean<CODE> method
* will throw a <CODE>RuntimeMBeanException</CODE>, although the MBean
* unregistration succeeded. In such a case, the MBean will be actually
* unregistered even though the <CODE>unregisterMBean<CODE> method
* threw an exception. Note that <CODE>RuntimeMBeanException</CODE> can
* also be thrown by <CODE>preDeregister</CODE>, in which case the MBean
* will remain registered.
* @exception RuntimeErrorException If the <CODE>postDeregister</CODE>
* (<CODE>MBeanRegistration</CODE> interface) method of the MBean throws an
* <CODE>Error</CODE>, the <CODE>unregisterMBean<CODE> method will
* throw a <CODE>RuntimeErrorException</CODE>, although the MBean
* unregistration succeeded. In such a case, the MBean will be actually
* unregistered even though the <CODE>unregisterMBean<CODE> method
* threw an exception. Note that <CODE>RuntimeMBeanException</CODE> can
* also be thrown by <CODE>preDeregister</CODE>, in which case the MBean
* will remain registered.
* @exception RuntimeOperationsException Wraps a
* <CODE>java.lang.IllegalArgumentException</CODE>: The object
* name in parameter is null or the MBean you are when trying to
...
...
@@ -282,7 +373,7 @@ public interface MBeanServerConnection {
* MBeanServerDelegate} MBean.
* @exception IOException A communication problem occurred when
* talking to the MBean server.
*
*
@see javax.management.MBeanRegistration
*/
public
void
unregisterMBean
(
ObjectName
name
)
throws
InstanceNotFoundException
,
MBeanRegistrationException
,
...
...
test/javax/management/MBeanServer/PostExceptionTest.java
0 → 100644
浏览文件 @
8b5d3f94
/*
* Copyright 2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6730926
* @summary Check behaviour of MBeanServer when postRegister and postDeregister
* throw exceptions.
* @author Daniel Fuchs
* @compile PostExceptionTest.java
* @run main PostExceptionTest
*/
import
javax.management.*
;
import
java.io.Serializable
;
import
java.net.URL
;
import
java.util.EnumSet
;
import
javax.management.loading.MLet
;
public
class
PostExceptionTest
{
/**
* A test case where we instantiate an ExceptionalWombatMBean (or a
* subclass of it) which will throw the exception {@code t} from within
* the methods indicated by {@code where}
*/
public
static
class
Case
{
public
final
Throwable
t
;
public
final
EnumSet
<
WHERE
>
where
;
public
Case
(
Throwable
t
,
EnumSet
<
WHERE
>
where
)
{
this
.
t
=
t
;
this
.
where
=
where
;
}
}
// Various methods to create an instance of Case in a single line
// --------------------------------------------------------------
public
static
Case
caze
(
Throwable
t
,
WHERE
w
)
{
return
new
Case
(
t
,
EnumSet
.
of
(
w
));
}
public
static
Case
caze
(
Throwable
t
,
EnumSet
<
WHERE
>
where
)
{
return
new
Case
(
t
,
where
);
}
public
static
Case
caze
(
Throwable
t
,
WHERE
w
,
WHERE
...
rest
)
{
return
new
Case
(
t
,
EnumSet
.
of
(
w
,
rest
));
}
/**
* Here is the list of our test cases:
*/
public
static
Case
[]
cases
={
caze
(
new
RuntimeException
(),
WHERE
.
PREREGISTER
),
caze
(
new
RuntimeException
(),
WHERE
.
POSTREGISTER
),
caze
(
new
RuntimeException
(),
WHERE
.
POSTREGISTER
,
WHERE
.
PREDEREGISTER
),
caze
(
new
RuntimeException
(),
WHERE
.
POSTREGISTER
,
WHERE
.
POSTDEREGISTER
),
caze
(
new
Exception
(),
WHERE
.
PREREGISTER
),
caze
(
new
Exception
(),
WHERE
.
POSTREGISTER
),
caze
(
new
Exception
(),
WHERE
.
POSTREGISTER
,
WHERE
.
PREDEREGISTER
),
caze
(
new
Exception
(),
WHERE
.
POSTREGISTER
,
WHERE
.
POSTDEREGISTER
),
caze
(
new
Error
(),
WHERE
.
PREREGISTER
),
caze
(
new
Error
(),
WHERE
.
POSTREGISTER
),
caze
(
new
Error
(),
WHERE
.
POSTREGISTER
,
WHERE
.
PREDEREGISTER
),
caze
(
new
Error
(),
WHERE
.
POSTREGISTER
,
WHERE
.
POSTDEREGISTER
),
caze
(
new
RuntimeException
(),
EnumSet
.
allOf
(
WHERE
.
class
)),
caze
(
new
Exception
(),
EnumSet
.
allOf
(
WHERE
.
class
)),
caze
(
new
Error
(),
EnumSet
.
allOf
(
WHERE
.
class
)),
};
public
static
void
main
(
String
[]
args
)
throws
Exception
{
System
.
out
.
println
(
"Test behaviour of MBeanServer when postRegister "
+
"or postDeregister throw exceptions"
);
MBeanServer
mbs
=
MBeanServerFactory
.
newMBeanServer
();
int
failures
=
0
;
final
ObjectName
n
=
new
ObjectName
(
"test:type=Wombat"
);
// We're going to test each cases, using each of the 4 createMBean
// forms + registerMBean in turn to create the MBean.
// Wich method is used to create the MBean is indicated by "how"
//
for
(
Case
caze:
cases
)
{
for
(
CREATE
how
:
CREATE
.
values
())
{
failures
+=
test
(
mbs
,
n
,
how
,
caze
.
t
,
caze
.
where
);
}
}
if
(
failures
==
0
)
System
.
out
.
println
(
"Test passed"
);
else
{
System
.
out
.
println
(
"TEST FAILED: "
+
failures
+
" failure(s)"
);
System
.
exit
(
1
);
}
}
// Execute a test case composed of:
// mbs: The MBeanServer where the MBean will be registered,
// name: The name of that MBean
// how: How will the MBean be created/registered (which MBeanServer
// method)
// t: The exception/error that the MBean will throw
// where: In which pre/post register/deregister method the exception/error
// will be thrown
//
private
static
int
test
(
MBeanServer
mbs
,
ObjectName
name
,
CREATE
how
,
Throwable
t
,
EnumSet
<
WHERE
>
where
)
throws
Exception
{
System
.
out
.
println
(
"-------<"
+
how
+
"> / <"
+
t
+
"> / "
+
where
+
"-------"
);
int
failures
=
0
;
ObjectInstance
oi
=
null
;
Exception
reg
=
null
;
// exception thrown by create/register
Exception
unreg
=
null
;
// exception thrown by unregister
try
{
// Create the MBean
oi
=
how
.
create
(
t
,
where
,
mbs
,
name
);
}
catch
(
Exception
xx
)
{
reg
=
xx
;
}
final
ObjectName
n
=
(
oi
==
null
)?
name:
oi
.
getObjectName
();
final
boolean
isRegistered
=
mbs
.
isRegistered
(
n
);
try
{
// If the MBean is registered, unregister it
if
(
isRegistered
)
mbs
.
unregisterMBean
(
n
);
}
catch
(
Exception
xxx
)
{
unreg
=
xxx
;
}
final
boolean
isUnregistered
=
!
mbs
.
isRegistered
(
n
);
if
(!
isUnregistered
)
{
// if the MBean is still registered (preDeregister threw an
// exception) signify to the MBean that it now should stop
// throwing anaything and unregister it.
JMX
.
newMBeanProxy
(
mbs
,
n
,
ExceptionalWombatMBean
.
class
).
end
();
mbs
.
unregisterMBean
(
n
);
}
// Now analyze the result. If we didn't ask the MBean to throw any
// exception then reg should be null.
if
(
where
.
isEmpty
()
&&
reg
!=
null
)
{
System
.
out
.
println
(
"Unexpected registration exception: "
+
reg
);
throw
new
RuntimeException
(
"Unexpected registration exception: "
+
reg
,
reg
);
}
// If we didn't ask the MBean to throw any exception then unreg should
// also be null.
if
(
where
.
isEmpty
()
&&
unreg
!=
null
)
{
System
.
out
.
println
(
"Unexpected unregistration exception: "
+
unreg
);
throw
new
RuntimeException
(
"Unexpected unregistration exception: "
+
unreg
,
unreg
);
}
// If we asked the MBean to throw an exception in either of preRegister
// or postRegister, then reg should not be null.
if
((
where
.
contains
(
WHERE
.
PREREGISTER
)
||
where
.
contains
(
WHERE
.
POSTREGISTER
))&&
reg
==
null
)
{
System
.
out
.
println
(
"Expected registration exception not "
+
"thrown by "
+
where
);
throw
new
RuntimeException
(
"Expected registration exception not "
+
"thrown by "
+
where
);
}
// If we asked the MBean not to throw any exception in preRegister
// then the MBean should have been registered, unregisterMBean should
// have been called.
// If we asked the MBean to throw an exception in either of preDeregister
// or postDeregister, then unreg should not be null.
if
((
where
.
contains
(
WHERE
.
PREDEREGISTER
)
||
where
.
contains
(
WHERE
.
POSTDEREGISTER
))&&
unreg
==
null
&&
!
where
.
contains
(
WHERE
.
PREREGISTER
))
{
System
.
out
.
println
(
"Expected unregistration exception not "
+
"thrown by "
+
where
);
throw
new
RuntimeException
(
"Expected unregistration exception not "
+
"thrown by "
+
where
);
}
// If we asked the MBean to throw an exception in preRegister
// then the MBean should not have been registered.
if
(
where
.
contains
(
WHERE
.
PREREGISTER
))
{
if
(
isRegistered
)
{
System
.
out
.
println
(
"MBean is still registered ["
+
where
+
"]: "
+
name
+
" / "
+
reg
);
throw
new
RuntimeException
(
"MBean is still registered ["
+
where
+
"]: "
+
name
+
" / "
+
reg
,
reg
);
}
}
// If we asked the MBean not to throw an exception in preRegister,
// but to throw an exception in postRegister, then the MBean should
// have been registered.
if
(
where
.
contains
(
WHERE
.
POSTREGISTER
)
&&
!
where
.
contains
(
WHERE
.
PREREGISTER
))
{
if
(!
isRegistered
)
{
System
.
out
.
println
(
"MBean is already unregistered ["
+
where
+
"]: "
+
name
+
" / "
+
reg
);
throw
new
RuntimeException
(
"MBean is already unregistered ["
+
where
+
"]: "
+
name
+
" / "
+
reg
,
reg
);
}
}
// If we asked the MBean to throw an exception in preRegister,
// check that the exception we caught was as expected.
//
if
(
where
.
contains
(
WHERE
.
PREREGISTER
))
{
WHERE
.
PREREGISTER
.
check
(
reg
,
t
);
}
else
if
(
where
.
contains
(
WHERE
.
POSTREGISTER
))
{
// If we asked the MBean to throw an exception in postRegister,
// check that the exception we caught was as expected.
// We don't do this check if we asked the MBean to also throw an
// exception in pre register, because postRegister will not have
// been called.
WHERE
.
POSTREGISTER
.
check
(
reg
,
t
);
}
if
(!
isRegistered
)
return
failures
;
// The MBean was registered, so unregisterMBean was called. Check
// unregisterMBean exceptions...
//
// If we asked the MBean to throw an exception in preDeregister
// then the MBean should not have been deregistered.
if
(
where
.
contains
(
WHERE
.
PREDEREGISTER
))
{
if
(
isUnregistered
)
{
System
.
out
.
println
(
"MBean is already unregistered ["
+
where
+
"]: "
+
name
+
" / "
+
unreg
);
throw
new
RuntimeException
(
"MBean is already unregistered ["
+
where
+
"]: "
+
name
+
" / "
+
unreg
,
unreg
);
}
}
// If we asked the MBean not to throw an exception in preDeregister,
// but to throw an exception in postDeregister, then the MBean should
// have been deregistered.
if
(
where
.
contains
(
WHERE
.
POSTDEREGISTER
)
&&
!
where
.
contains
(
WHERE
.
PREDEREGISTER
))
{
if
(!
isUnregistered
)
{
System
.
out
.
println
(
"MBean is not unregistered ["
+
where
+
"]: "
+
name
+
" / "
+
unreg
);
throw
new
RuntimeException
(
"MBean is not unregistered ["
+
where
+
"]: "
+
name
+
" / "
+
unreg
,
unreg
);
}
}
// If we asked the MBean to throw an exception in preDeregister,
// check that the exception we caught was as expected.
//
if
(
where
.
contains
(
WHERE
.
PREDEREGISTER
))
{
WHERE
.
PREDEREGISTER
.
check
(
unreg
,
t
);
}
else
if
(
where
.
contains
(
WHERE
.
POSTDEREGISTER
))
{
// If we asked the MBean to throw an exception in postDeregister,
// check that the exception we caught was as expected.
// We don't do this check if we asked the MBean to also throw an
// exception in pre register, because postRegister will not have
// been called.
WHERE
.
POSTDEREGISTER
.
check
(
unreg
,
t
);
}
return
failures
;
}
/**
* This enum lists the 4 methods in MBeanRegistration.
*/
public
static
enum
WHERE
{
PREREGISTER
,
POSTREGISTER
,
PREDEREGISTER
,
POSTDEREGISTER
;
// Checks that an exception thrown by the MBeanServer correspond to
// what is expected when an MBean throws an exception in this
// MBeanRegistration method ("this" is one of the 4 enum values above)
//
public
void
check
(
Exception
thrown
,
Throwable
t
)
throws
Exception
{
if
(
t
instanceof
RuntimeException
)
{
if
(!(
thrown
instanceof
RuntimeMBeanException
))
{
System
.
out
.
println
(
"Expected RuntimeMBeanException, got "
+
thrown
);
throw
new
Exception
(
"Expected RuntimeMBeanException, got "
+
thrown
);
}
}
else
if
(
t
instanceof
Error
)
{
if
(!(
thrown
instanceof
RuntimeErrorException
))
{
System
.
out
.
println
(
"Expected RuntimeErrorException, got "
+
thrown
);
throw
new
Exception
(
"Expected RuntimeErrorException, got "
+
thrown
);
}
}
else
if
(
t
instanceof
Exception
)
{
if
(
EnumSet
.
of
(
POSTDEREGISTER
,
POSTREGISTER
).
contains
(
this
))
{
if
(!(
thrown
instanceof
RuntimeMBeanException
))
{
System
.
out
.
println
(
"Expected RuntimeMBeanException, got "
+
thrown
);
throw
new
Exception
(
"Expected RuntimeMBeanException, got "
+
thrown
);
}
if
(!
(
thrown
.
getCause
()
instanceof
RuntimeException
))
{
System
.
out
.
println
(
"Bad cause: "
+
"expected RuntimeException, "
+
"got <"
+
thrown
.
getCause
()+
">"
);
throw
new
Exception
(
"Bad cause: "
+
"expected RuntimeException, "
+
"got <"
+
thrown
.
getCause
()+
">"
);
}
}
if
(
EnumSet
.
of
(
PREDEREGISTER
,
PREREGISTER
).
contains
(
this
))
{
if
(!(
thrown
instanceof
MBeanRegistrationException
))
{
System
.
out
.
println
(
"Expected "
+
"MBeanRegistrationException, got "
+
thrown
);
throw
new
Exception
(
"Expected "
+
"MBeanRegistrationException, got "
+
thrown
);
}
if
(!
(
thrown
.
getCause
()
instanceof
Exception
))
{
System
.
out
.
println
(
"Bad cause: "
+
"expected Exception, "
+
"got <"
+
thrown
.
getCause
()+
">"
);
throw
new
Exception
(
"Bad cause: "
+
"expected Exception, "
+
"got <"
+
thrown
.
getCause
()+
">"
);
}
}
}
}
}
/**
* This enum lists the 5 methods to create and register an
* ExceptionalWombat MBean
*/
public
static
enum
CREATE
{
CREATE1
()
{
// Creates an ExceptionalWombat MBean using createMBean form #1
public
ObjectInstance
create
(
Throwable
t
,
EnumSet
<
WHERE
>
where
,
MBeanServer
server
,
ObjectName
name
)
throws
Exception
{
ExceptionallyHackyWombat
.
t
=
t
;
ExceptionallyHackyWombat
.
w
=
where
;
return
server
.
createMBean
(
ExceptionallyHackyWombat
.
class
.
getName
(),
name
);
}
},
CREATE2
()
{
// Creates an ExceptionalWombat MBean using createMBean form #2
public
ObjectInstance
create
(
Throwable
t
,
EnumSet
<
WHERE
>
where
,
MBeanServer
server
,
ObjectName
name
)
throws
Exception
{
ExceptionallyHackyWombat
.
t
=
t
;
ExceptionallyHackyWombat
.
w
=
where
;
final
ObjectName
loaderName
=
registerMLet
(
server
);
return
server
.
createMBean
(
ExceptionallyHackyWombat
.
class
.
getName
(),
name
,
loaderName
);
}
},
CREATE3
()
{
// Creates an ExceptionalWombat MBean using createMBean form #3
public
ObjectInstance
create
(
Throwable
t
,
EnumSet
<
WHERE
>
where
,
MBeanServer
server
,
ObjectName
name
)
throws
Exception
{
final
Object
[]
params
=
{
t
,
where
};
final
String
[]
signature
=
{
Throwable
.
class
.
getName
(),
EnumSet
.
class
.
getName
()
};
return
server
.
createMBean
(
ExceptionalWombat
.
class
.
getName
(),
name
,
params
,
signature
);
}
},
CREATE4
()
{
// Creates an ExceptionalWombat MBean using createMBean form #4
public
ObjectInstance
create
(
Throwable
t
,
EnumSet
<
WHERE
>
where
,
MBeanServer
server
,
ObjectName
name
)
throws
Exception
{
final
Object
[]
params
=
{
t
,
where
};
final
String
[]
signature
=
{
Throwable
.
class
.
getName
(),
EnumSet
.
class
.
getName
()
};
return
server
.
createMBean
(
ExceptionalWombat
.
class
.
getName
(),
name
,
registerMLet
(
server
),
params
,
signature
);
}
},
REGISTER
()
{
// Creates an ExceptionalWombat MBean using registerMBean
public
ObjectInstance
create
(
Throwable
t
,
EnumSet
<
WHERE
>
where
,
MBeanServer
server
,
ObjectName
name
)
throws
Exception
{
final
ExceptionalWombat
wombat
=
new
ExceptionalWombat
(
t
,
where
);
return
server
.
registerMBean
(
wombat
,
name
);
}
};
// Creates an ExceptionalWombat MBean using the method denoted by this
// Enum value - one of CREATE1, CREATE2, CREATE3, CREATE4, or REGISTER.
public
abstract
ObjectInstance
create
(
Throwable
t
,
EnumSet
<
WHERE
>
where
,
MBeanServer
server
,
ObjectName
name
)
throws
Exception
;
// This is a bit of a hack - we use an MLet that delegates to the
// System ClassLoader so that we can use createMBean form #2 and #3
// while still using the same class loader (system).
// This is necessary to make the ExceptionallyHackyWombatMBean work ;-)
//
public
ObjectName
registerMLet
(
MBeanServer
server
)
throws
Exception
{
final
ObjectName
name
=
new
ObjectName
(
"test:type=MLet"
);
if
(
server
.
isRegistered
(
name
))
{
return
name
;
}
final
MLet
mlet
=
new
MLet
(
new
URL
[
0
],
ClassLoader
.
getSystemClassLoader
());
return
server
.
registerMBean
(
mlet
,
name
).
getObjectName
();
}
}
/**
*A Wombat MBean that can throw exceptions or errors in any of the
* MBeanRegistration methods.
*/
public
static
interface
ExceptionalWombatMBean
{
// Tells the MBean to stop throwing exceptions - we sometime
// need to call this at the end of the test so that we can
// actually unregister the MBean.
public
void
end
();
}
/**
*A Wombat MBean that can throw exceptions or errors in any of the
* MBeanRegistration methods.
*/
public
static
class
ExceptionalWombat
implements
ExceptionalWombatMBean
,
MBeanRegistration
{
private
final
Throwable
throwable
;
private
final
EnumSet
<
WHERE
>
where
;
private
volatile
boolean
end
=
false
;
public
ExceptionalWombat
(
Throwable
t
,
EnumSet
<
WHERE
>
where
)
{
this
.
throwable
=
t
;
this
.
where
=
where
;
}
private
Exception
doThrow
()
{
if
(
throwable
instanceof
Error
)
throw
(
Error
)
throwable
;
if
(
throwable
instanceof
RuntimeException
)
throw
(
RuntimeException
)
throwable
;
return
(
Exception
)
throwable
;
}
public
ObjectName
preRegister
(
MBeanServer
server
,
ObjectName
name
)
throws
Exception
{
if
(!
end
&&
where
.
contains
(
WHERE
.
PREREGISTER
))
throw
doThrow
();
return
name
;
}
public
void
postRegister
(
Boolean
registrationDone
)
{
if
(!
end
&&
where
.
contains
(
WHERE
.
POSTREGISTER
))
throw
new
RuntimeException
(
doThrow
());
}
public
void
preDeregister
()
throws
Exception
{
if
(!
end
&&
where
.
contains
(
WHERE
.
PREDEREGISTER
))
throw
doThrow
();
}
public
void
postDeregister
()
{
if
(!
end
&&
where
.
contains
(
WHERE
.
POSTREGISTER
))
throw
new
RuntimeException
(
doThrow
());
}
public
void
end
()
{
this
.
end
=
true
;
}
}
/**
* This is a big ugly hack to call createMBean form #1 and #2 - where
* the empty constructor is used. Since we still want to supply parameters
* to the ExceptionalWombat super class, we temporarily store these
* parameter value in a static volatile before calling create MBean.
* Of course this only works because our test is sequential and single
* threaded, and nobody but our test uses this ExceptionallyHackyWombat.
*/
public
static
class
ExceptionallyHackyWombat
extends
ExceptionalWombat
{
public
static
volatile
Throwable
t
;
public
static
volatile
EnumSet
<
WHERE
>
w
;
public
ExceptionallyHackyWombat
()
{
super
(
t
,
w
);
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录