Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
0a690d3a
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看板
提交
0a690d3a
编写于
7月 09, 2008
作者:
T
tbell
浏览文件
操作
浏览文件
下载
差异文件
Merge
上级
33565c22
13a831aa
变更
46
展开全部
隐藏空白更改
内联
并排
Showing
46 changed file
with
5449 addition
and
617 deletion
+5449
-617
src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java
...om/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java
+357
-162
src/share/classes/com/sun/jmx/mbeanserver/DynamicMBean2.java
src/share/classes/com/sun/jmx/mbeanserver/DynamicMBean2.java
+2
-12
src/share/classes/com/sun/jmx/mbeanserver/Introspector.java
src/share/classes/com/sun/jmx/mbeanserver/Introspector.java
+178
-51
src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java
src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java
+22
-7
src/share/classes/com/sun/jmx/mbeanserver/MBeanInjector.java
src/share/classes/com/sun/jmx/mbeanserver/MBeanInjector.java
+291
-0
src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java
...re/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java
+154
-7
src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java
src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java
+5
-1
src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java
...e/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java
+24
-8
src/share/classes/com/sun/jmx/mbeanserver/MXBeanSupport.java
src/share/classes/com/sun/jmx/mbeanserver/MXBeanSupport.java
+2
-2
src/share/classes/com/sun/jmx/mbeanserver/NotifySupport.java
src/share/classes/com/sun/jmx/mbeanserver/NotifySupport.java
+186
-0
src/share/classes/com/sun/jmx/mbeanserver/Repository.java
src/share/classes/com/sun/jmx/mbeanserver/Repository.java
+124
-37
src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanIntrospector.java
...es/com/sun/jmx/mbeanserver/StandardMBeanIntrospector.java
+22
-11
src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanSupport.java
...classes/com/sun/jmx/mbeanserver/StandardMBeanSupport.java
+21
-22
src/share/classes/com/sun/jmx/mbeanserver/Util.java
src/share/classes/com/sun/jmx/mbeanserver/Util.java
+5
-0
src/share/classes/javax/management/BinaryRelQueryExp.java
src/share/classes/javax/management/BinaryRelQueryExp.java
+1
-0
src/share/classes/javax/management/Description.java
src/share/classes/javax/management/Description.java
+180
-0
src/share/classes/javax/management/Descriptor.java
src/share/classes/javax/management/Descriptor.java
+15
-8
src/share/classes/javax/management/DescriptorFields.java
src/share/classes/javax/management/DescriptorFields.java
+137
-0
src/share/classes/javax/management/DescriptorKey.java
src/share/classes/javax/management/DescriptorKey.java
+45
-7
src/share/classes/javax/management/DynamicWrapperMBean.java
src/share/classes/javax/management/DynamicWrapperMBean.java
+62
-0
src/share/classes/javax/management/Impact.java
src/share/classes/javax/management/Impact.java
+105
-0
src/share/classes/javax/management/JMX.java
src/share/classes/javax/management/JMX.java
+26
-0
src/share/classes/javax/management/MBean.java
src/share/classes/javax/management/MBean.java
+68
-0
src/share/classes/javax/management/MBeanOperationInfo.java
src/share/classes/javax/management/MBeanOperationInfo.java
+26
-14
src/share/classes/javax/management/MBeanRegistration.java
src/share/classes/javax/management/MBeanRegistration.java
+98
-6
src/share/classes/javax/management/MBeanServer.java
src/share/classes/javax/management/MBeanServer.java
+7
-4
src/share/classes/javax/management/MBeanServerConnection.java
...share/classes/javax/management/MBeanServerConnection.java
+6
-0
src/share/classes/javax/management/MXBean.java
src/share/classes/javax/management/MXBean.java
+27
-4
src/share/classes/javax/management/ManagedAttribute.java
src/share/classes/javax/management/ManagedAttribute.java
+64
-0
src/share/classes/javax/management/ManagedOperation.java
src/share/classes/javax/management/ManagedOperation.java
+67
-0
src/share/classes/javax/management/NotQueryExp.java
src/share/classes/javax/management/NotQueryExp.java
+1
-0
src/share/classes/javax/management/NotificationBroadcasterSupport.java
...sses/javax/management/NotificationBroadcasterSupport.java
+2
-1
src/share/classes/javax/management/NotificationInfo.java
src/share/classes/javax/management/NotificationInfo.java
+117
-0
src/share/classes/javax/management/NotificationInfos.java
src/share/classes/javax/management/NotificationInfos.java
+72
-0
src/share/classes/javax/management/SendNotification.java
src/share/classes/javax/management/SendNotification.java
+38
-0
src/share/classes/javax/management/StandardEmitterMBean.java
src/share/classes/javax/management/StandardEmitterMBean.java
+157
-41
src/share/classes/javax/management/StandardMBean.java
src/share/classes/javax/management/StandardMBean.java
+139
-6
src/share/classes/javax/management/modelmbean/RequiredModelMBean.java
...asses/javax/management/modelmbean/RequiredModelMBean.java
+61
-7
src/share/classes/javax/management/monitor/package.html
src/share/classes/javax/management/monitor/package.html
+11
-8
src/share/classes/javax/management/package.html
src/share/classes/javax/management/package.html
+282
-191
test/javax/management/Introspector/AnnotatedMBeanTest.java
test/javax/management/Introspector/AnnotatedMBeanTest.java
+337
-0
test/javax/management/Introspector/AnnotatedNotificationInfoTest.java
...anagement/Introspector/AnnotatedNotificationInfoTest.java
+271
-0
test/javax/management/Introspector/MBeanDescriptionTest.java
test/javax/management/Introspector/MBeanDescriptionTest.java
+830
-0
test/javax/management/Introspector/ParameterNameTest.java
test/javax/management/Introspector/ParameterNameTest.java
+116
-0
test/javax/management/Introspector/ResourceInjectionTest.java
.../javax/management/Introspector/ResourceInjectionTest.java
+656
-0
test/javax/management/Introspector/annot/Name.java
test/javax/management/Introspector/annot/Name.java
+32
-0
未找到文件。
src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java
浏览文件 @
0a690d3a
此差异已折叠。
点击以展开。
src/share/classes/com/sun/jmx/mbeanserver/DynamicMBean2.java
浏览文件 @
0a690d3a
...
...
@@ -25,7 +25,7 @@
package
com.sun.jmx.mbeanserver
;
import
javax.management.DynamicMBean
;
import
javax.management.Dynamic
Wrapper
MBean
;
import
javax.management.MBeanServer
;
import
javax.management.ObjectName
;
...
...
@@ -35,17 +35,7 @@ import javax.management.ObjectName;
*
* @since 1.6
*/
public
interface
DynamicMBean2
extends
DynamicMBean
{
/**
* The resource corresponding to this MBean. This is the object whose
* class name should be reflected by the MBean's
* getMBeanInfo().getClassName() for example. For a "plain"
* DynamicMBean it will be "this". For an MBean that wraps another
* object, like javax.management.StandardMBean, it will be the wrapped
* object.
*/
public
Object
getResource
();
public
interface
DynamicMBean2
extends
DynamicWrapperMBean
{
/**
* The name of this MBean's class, as used by permission checks.
* This is typically equal to getResource().getClass().getName().
...
...
src/share/classes/com/sun/jmx/mbeanserver/Introspector.java
浏览文件 @
0a690d3a
...
...
@@ -25,23 +25,39 @@
package
com.sun.jmx.mbeanserver
;
import
com.sun.jmx.remote.util.EnvHelp
;
import
java.beans.BeanInfo
;
import
java.beans.PropertyDescriptor
;
import
java.lang.annotation.Annotation
;
import
java.lang.reflect.AnnotatedElement
;
import
java.lang.reflect.Array
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
import
java.lang.reflect.Proxy
;
import
java.lang.reflect.UndeclaredThrowableException
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.logging.Level
;
import
javax.management.AttributeNotFoundException
;
import
javax.management.Description
;
import
javax.management.Descriptor
;
import
javax.management.DescriptorFields
;
import
javax.management.DescriptorKey
;
import
javax.management.DynamicMBean
;
import
javax.management.ImmutableDescriptor
;
import
javax.management.MBean
;
import
javax.management.MBeanInfo
;
import
javax.management.MXBean
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.openmbean.CompositeData
;
import
javax.management.openmbean.MXBeanMappingFactory
;
import
static
com
.
sun
.
jmx
.
defaults
.
JmxProperties
.
MBEANSERVER_LOGGER
;
import
com.sun.jmx.mbeanserver.Util
;
import
com.sun.jmx.remote.util.EnvHelp
;
import
java.beans.BeanInfo
;
import
java.beans.PropertyDescriptor
;
...
...
@@ -133,8 +149,12 @@ public class Introspector {
}
}
public
static
void
checkCompliance
(
Class
mbeanClass
)
throws
NotCompliantMBeanException
{
public
static
void
checkCompliance
(
Class
<?>
mbeanClass
)
throws
NotCompliantMBeanException
{
// Check that @Resource is used correctly (if it used).
MBeanInjector
.
validate
(
mbeanClass
);
// Is DynamicMBean?
//
if
(
DynamicMBean
.
class
.
isAssignableFrom
(
mbeanClass
))
...
...
@@ -157,21 +177,39 @@ public class Introspector {
}
catch
(
NotCompliantMBeanException
e
)
{
mxbeanException
=
e
;
}
// Is @MBean or @MXBean class?
// In fact we find @MBean or @MXBean as a hacky variant of
// getStandardMBeanInterface or getMXBeanInterface. If we get here
// then nothing worked.
final
String
msg
=
"MBean class "
+
mbeanClass
.
getName
()
+
" does not implement "
+
"DynamicMBean, neither follows the Standard MBean conventions ("
+
mbeanException
.
toString
()
+
") nor the MXBean conventions ("
+
mxbeanException
.
toString
()
+
")"
;
"DynamicMBean; does not follow the Standard MBean conventions ("
+
mbeanException
.
toString
()
+
"); does not follow the MXBean conventions ("
+
mxbeanException
.
toString
()
+
"); and does not have or inherit the @"
+
MBean
.
class
.
getSimpleName
()
+
" or @"
+
MXBean
.
class
.
getSimpleName
()
+
" annotation"
;
throw
new
NotCompliantMBeanException
(
msg
);
}
/**
* <p>Make a DynamicMBean out of the existing MBean object. The object
* may already be a DynamicMBean, or it may be a Standard MBean or
* MXBean, possibly defined using {@code @MBean} or {@code @MXBean}.</p>
* @param mbean the object to convert to a DynamicMBean.
* @param <T> a type parameter defined for implementation convenience
* (which would have to be removed if this method were part of the public
* API).
* @return the converted DynamicMBean.
* @throws NotCompliantMBeanException if {@code mbean} is not a compliant
* MBean object, including the case where it is null.
*/
public
static
<
T
>
DynamicMBean
makeDynamicMBean
(
T
mbean
)
throws
NotCompliantMBeanException
{
if
(
mbean
==
null
)
throw
new
NotCompliantMBeanException
(
"Null MBean object"
);
if
(
mbean
instanceof
DynamicMBean
)
return
(
DynamicMBean
)
mbean
;
final
Class
mbeanClass
=
mbean
.
getClass
();
final
Class
<?>
mbeanClass
=
mbean
.
getClass
();
Class
<?
super
T
>
c
=
null
;
try
{
c
=
Util
.
cast
(
getStandardMBeanInterface
(
mbeanClass
));
...
...
@@ -270,7 +308,7 @@ public class Introspector {
* Return <code>null</code> if the MBean is a DynamicMBean,
* or if no MBean interface is found.
*/
public
static
Class
getMBeanInterface
(
Class
baseClass
)
{
public
static
Class
<?>
getMBeanInterface
(
Class
<?>
baseClass
)
{
// Check if the given class implements the MBean interface
// or the Dynamic MBean interface
if
(
isDynamic
(
baseClass
))
return
null
;
...
...
@@ -291,10 +329,12 @@ public class Introspector {
* @throws NotCompliantMBeanException The specified class is
* not a JMX compliant Standard MBean.
*/
public
static
Class
getStandardMBeanInterface
(
Class
baseClass
)
throws
NotCompliantMBeanException
{
Class
current
=
baseClass
;
Class
mbeanInterface
=
null
;
public
static
<
T
>
Class
<?
super
T
>
getStandardMBeanInterface
(
Class
<
T
>
baseClass
)
throws
NotCompliantMBeanException
{
if
(
baseClass
.
isAnnotationPresent
(
MBean
.
class
))
return
baseClass
;
Class
<?
super
T
>
current
=
baseClass
;
Class
<?
super
T
>
mbeanInterface
=
null
;
while
(
current
!=
null
)
{
mbeanInterface
=
findMBeanInterface
(
current
,
current
.
getName
());
...
...
@@ -321,8 +361,10 @@ public class Introspector {
* @throws NotCompliantMBeanException The specified class is
* not a JMX compliant MXBean.
*/
public
static
Class
getMXBeanInterface
(
Class
baseClass
)
public
static
<
T
>
Class
<?
super
T
>
getMXBeanInterface
(
Class
<
T
>
baseClass
)
throws
NotCompliantMBeanException
{
if
(
hasMXBeanAnnotation
(
baseClass
))
return
baseClass
;
try
{
return
MXBeanSupport
.
findMXBeanInterface
(
baseClass
);
}
catch
(
Exception
e
)
{
...
...
@@ -345,19 +387,24 @@ public class Introspector {
* ------------------------------------------
*/
static
boolean
hasMXBeanAnnotation
(
Class
<?>
c
)
{
MXBean
m
=
c
.
getAnnotation
(
MXBean
.
class
);
return
(
m
!=
null
&&
m
.
value
());
}
/**
* Try to find the MBean interface corresponding to the class aName
* - i.e. <i>aName</i>MBean, from within aClass and its superclasses.
**/
private
static
Class
findMBeanInterface
(
Class
aClass
,
String
aName
)
{
Class
current
=
aClass
;
private
static
<
T
>
Class
<?
super
T
>
findMBeanInterface
(
Class
<
T
>
aClass
,
String
aName
)
{
Class
<?
super
T
>
current
=
aClass
;
while
(
current
!=
null
)
{
final
Class
[]
interfaces
=
current
.
getInterfaces
();
final
Class
<?>
[]
interfaces
=
current
.
getInterfaces
();
final
int
len
=
interfaces
.
length
;
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
final
Class
inter
=
implementsMBean
(
interfaces
[
i
]
,
aName
);
Class
<?
super
T
>
inter
=
Util
.
cast
(
interfaces
[
i
]);
inter
=
implementsMBean
(
inter
,
aName
);
if
(
inter
!=
null
)
return
inter
;
}
current
=
current
.
getSuperclass
();
...
...
@@ -365,6 +412,48 @@ public class Introspector {
return
null
;
}
public
static
String
descriptionForElement
(
AnnotatedElement
elmt
)
{
if
(
elmt
==
null
)
return
null
;
Description
d
=
elmt
.
getAnnotation
(
Description
.
class
);
if
(
d
==
null
)
return
null
;
return
d
.
value
();
}
public
static
String
descriptionForParameter
(
Annotation
[]
parameterAnnotations
)
{
for
(
Annotation
a
:
parameterAnnotations
)
{
if
(
a
instanceof
Description
)
return
((
Description
)
a
).
value
();
}
return
null
;
}
public
static
String
nameForParameter
(
Annotation
[]
parameterAnnotations
)
{
for
(
Annotation
a
:
parameterAnnotations
)
{
Class
<?
extends
Annotation
>
ac
=
a
.
annotationType
();
// You'd really have to go out of your way to have more than
// one @Name annotation, so we don't check for that.
if
(
ac
.
getSimpleName
().
equals
(
"Name"
))
{
try
{
Method
value
=
ac
.
getMethod
(
"value"
);
if
(
value
.
getReturnType
()
==
String
.
class
&&
value
.
getParameterTypes
().
length
==
0
)
{
return
(
String
)
value
.
invoke
(
a
);
}
}
catch
(
Exception
e
)
{
MBEANSERVER_LOGGER
.
log
(
Level
.
WARNING
,
"Unexpected exception getting @"
+
ac
.
getName
(),
e
);
}
}
}
return
null
;
}
public
static
Descriptor
descriptorForElement
(
final
AnnotatedElement
elmt
)
{
if
(
elmt
==
null
)
return
ImmutableDescriptor
.
EMPTY_DESCRIPTOR
;
...
...
@@ -372,41 +461,18 @@ public class Introspector {
return
descriptorForAnnotations
(
annots
);
}
public
static
Descriptor
descriptorForAnnotation
(
Annotation
annot
)
{
return
descriptorForAnnotations
(
new
Annotation
[]
{
annot
});
}
public
static
Descriptor
descriptorForAnnotations
(
Annotation
[]
annots
)
{
if
(
annots
.
length
==
0
)
return
ImmutableDescriptor
.
EMPTY_DESCRIPTOR
;
Map
<
String
,
Object
>
descriptorMap
=
new
HashMap
<
String
,
Object
>();
for
(
Annotation
a
:
annots
)
{
Class
<?
extends
Annotation
>
c
=
a
.
annotationType
();
Method
[]
elements
=
c
.
getMethods
();
for
(
Method
element
:
elements
)
{
DescriptorKey
key
=
element
.
getAnnotation
(
DescriptorKey
.
class
);
if
(
key
!=
null
)
{
String
name
=
key
.
value
();
Object
value
;
try
{
value
=
element
.
invoke
(
a
);
}
catch
(
RuntimeException
e
)
{
// we don't expect this - except for possibly
// security exceptions?
// RuntimeExceptions shouldn't be "UndeclaredThrowable".
// anyway...
//
throw
e
;
}
catch
(
Exception
e
)
{
// we don't expect this
throw
new
UndeclaredThrowableException
(
e
);
}
value
=
annotationToField
(
value
);
Object
oldValue
=
descriptorMap
.
put
(
name
,
value
);
if
(
oldValue
!=
null
&&
!
equals
(
oldValue
,
value
))
{
final
String
msg
=
"Inconsistent values for descriptor field "
+
name
+
" from annotations: "
+
value
+
" :: "
+
oldValue
;
throw
new
IllegalArgumentException
(
msg
);
}
}
}
if
(
a
instanceof
DescriptorFields
)
addDescriptorFieldsToMap
(
descriptorMap
,
(
DescriptorFields
)
a
);
addAnnotationFieldsToMap
(
descriptorMap
,
a
);
}
if
(
descriptorMap
.
isEmpty
())
...
...
@@ -415,6 +481,62 @@ public class Introspector {
return
new
ImmutableDescriptor
(
descriptorMap
);
}
private
static
void
addDescriptorFieldsToMap
(
Map
<
String
,
Object
>
descriptorMap
,
DescriptorFields
df
)
{
for
(
String
field
:
df
.
value
())
{
int
eq
=
field
.
indexOf
(
'='
);
if
(
eq
<
0
)
{
throw
new
IllegalArgumentException
(
"@DescriptorFields string must contain '=': "
+
field
);
}
String
name
=
field
.
substring
(
0
,
eq
);
String
value
=
field
.
substring
(
eq
+
1
);
addToMap
(
descriptorMap
,
name
,
value
);
}
}
private
static
void
addAnnotationFieldsToMap
(
Map
<
String
,
Object
>
descriptorMap
,
Annotation
a
)
{
Class
<?
extends
Annotation
>
c
=
a
.
annotationType
();
Method
[]
elements
=
c
.
getMethods
();
for
(
Method
element
:
elements
)
{
DescriptorKey
key
=
element
.
getAnnotation
(
DescriptorKey
.
class
);
if
(
key
!=
null
)
{
String
name
=
key
.
value
();
Object
value
;
try
{
value
=
element
.
invoke
(
a
);
}
catch
(
RuntimeException
e
)
{
// we don't expect this - except for possibly
// security exceptions?
// RuntimeExceptions shouldn't be "UndeclaredThrowable".
// anyway...
throw
e
;
}
catch
(
Exception
e
)
{
// we don't expect this
throw
new
UndeclaredThrowableException
(
e
);
}
if
(!
key
.
omitIfDefault
()
||
!
equals
(
value
,
element
.
getDefaultValue
()))
{
value
=
annotationToField
(
value
);
addToMap
(
descriptorMap
,
name
,
value
);
}
}
}
}
private
static
void
addToMap
(
Map
<
String
,
Object
>
descriptorMap
,
String
name
,
Object
value
)
{
Object
oldValue
=
descriptorMap
.
put
(
name
,
value
);
if
(
oldValue
!=
null
&&
!
equals
(
oldValue
,
value
))
{
final
String
msg
=
"Inconsistent values for descriptor field "
+
name
+
" from annotations: "
+
value
+
" :: "
+
oldValue
;
throw
new
IllegalArgumentException
(
msg
);
}
}
/**
* Throws a NotCompliantMBeanException or a SecurityException.
* @param notCompliant the class which was under examination
...
...
@@ -473,8 +595,13 @@ public class Introspector {
// The only other possibility is that the value is another
// annotation, or that the language has evolved since this code
// was written. We don't allow for either of those currently.
// If it is indeed another annotation, then x will be a proxy
// with an unhelpful name like $Proxy2. So we extract the
// proxy's interface to use that in the exception message.
if
(
Proxy
.
isProxyClass
(
c
))
c
=
c
.
getInterfaces
()[
0
];
// array "can't be empty"
throw
new
IllegalArgumentException
(
"Illegal type for annotation "
+
"element
: "
+
x
.
getClass
()
.
getName
());
"element
using @DescriptorKey: "
+
c
.
getName
());
}
// This must be consistent with the check for duplicate field values in
...
...
@@ -490,15 +617,15 @@ public class Introspector {
* @param c The interface to be tested
* @param clName The name of the class implementing this interface
*/
private
static
Class
implementsMBean
(
Class
c
,
String
clName
)
{
private
static
<
T
>
Class
<?
super
T
>
implementsMBean
(
Class
<
T
>
c
,
String
clName
)
{
String
clMBeanName
=
clName
+
"MBean"
;
if
(
c
.
getName
().
equals
(
clMBeanName
))
{
return
c
;
}
Class
[]
interfaces
=
c
.
getInterfaces
();
Class
<?>
[]
interfaces
=
c
.
getInterfaces
();
for
(
int
i
=
0
;
i
<
interfaces
.
length
;
i
++)
{
if
(
interfaces
[
i
].
getName
().
equals
(
clMBeanName
))
return
interfaces
[
i
]
;
return
Util
.
cast
(
interfaces
[
i
])
;
}
return
null
;
...
...
src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java
浏览文件 @
0a690d3a
...
...
@@ -33,6 +33,10 @@ import java.util.Comparator;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
javax.management.MBean
;
import
javax.management.MXBean
;
import
javax.management.ManagedAttribute
;
import
javax.management.ManagedOperation
;
import
javax.management.NotCompliantMBeanException
;
/**
...
...
@@ -125,18 +129,26 @@ class MBeanAnalyzer<M> {
for
(
Method
m
:
methods
)
{
final
String
name
=
m
.
getName
();
final
int
nParams
=
m
.
getParameterTypes
().
length
;
final
boolean
managedOp
=
m
.
isAnnotationPresent
(
ManagedOperation
.
class
);
final
boolean
managedAttr
=
m
.
isAnnotationPresent
(
ManagedAttribute
.
class
);
if
(
managedOp
&&
managedAttr
)
{
throw
new
NotCompliantMBeanException
(
"Method "
+
name
+
" has both @ManagedOperation and @ManagedAttribute"
);
}
final
M
cm
=
introspector
.
mFrom
(
m
);
String
attrName
=
""
;
if
(
name
.
startsWith
(
"get"
))
attrName
=
name
.
substring
(
3
);
else
if
(
name
.
startsWith
(
"is"
)
&&
m
.
getReturnType
()
==
boolean
.
class
)
attrName
=
name
.
substring
(
2
);
if
(!
managedOp
)
{
if
(
name
.
startsWith
(
"get"
))
attrName
=
name
.
substring
(
3
);
else
if
(
name
.
startsWith
(
"is"
)
&&
m
.
getReturnType
()
==
boolean
.
class
)
attrName
=
name
.
substring
(
2
);
}
if
(
attrName
.
length
()
!=
0
&&
nParams
==
0
&&
m
.
getReturnType
()
!=
void
.
class
)
{
&&
m
.
getReturnType
()
!=
void
.
class
&&
!
managedOp
)
{
// It's a getter
// Check we don't have both isX and getX
AttrMethods
<
M
>
am
=
attrMap
.
get
(
attrName
);
...
...
@@ -153,7 +165,7 @@ class MBeanAnalyzer<M> {
attrMap
.
put
(
attrName
,
am
);
}
else
if
(
name
.
startsWith
(
"set"
)
&&
name
.
length
()
>
3
&&
nParams
==
1
&&
m
.
getReturnType
()
==
void
.
class
)
{
m
.
getReturnType
()
==
void
.
class
&&
!
managedOp
)
{
// It's a setter
attrName
=
name
.
substring
(
3
);
AttrMethods
<
M
>
am
=
attrMap
.
get
(
attrName
);
...
...
@@ -166,6 +178,9 @@ class MBeanAnalyzer<M> {
}
am
.
setter
=
cm
;
attrMap
.
put
(
attrName
,
am
);
}
else
if
(
managedAttr
)
{
throw
new
NotCompliantMBeanException
(
"Method "
+
name
+
" has @ManagedAttribute but is not a valid getter or setter"
);
}
else
{
// It's an operation
List
<
M
>
cms
=
opMap
.
get
(
name
);
...
...
src/share/classes/com/sun/jmx/mbeanserver/MBeanInjector.java
0 → 100644
浏览文件 @
0a690d3a
/*
* Copyright 2007 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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.
*/
package
com.sun.jmx.mbeanserver
;
import
java.lang.ref.WeakReference
;
import
java.security.PrivilegedAction
;
import
java.util.Map
;
import
java.util.WeakHashMap
;
import
javax.annotation.Resource
;
import
javax.management.MBeanServer
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.ObjectName
;
import
static
com
.
sun
.
jmx
.
mbeanserver
.
Util
.
newMap
;
import
java.lang.reflect.AccessibleObject
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
import
java.security.AccessController
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
javax.management.SendNotification
;
public
class
MBeanInjector
{
private
static
Class
<?>[]
injectedClasses
=
{
MBeanServer
.
class
,
ObjectName
.
class
,
SendNotification
.
class
,
};
public
static
void
inject
(
Object
mbean
,
MBeanServer
mbs
,
ObjectName
name
)
throws
Exception
{
ClassInjector
injector
=
injectorForClass
(
mbean
.
getClass
());
injector
.
inject
(
mbean
,
MBeanServer
.
class
,
mbs
);
injector
.
inject
(
mbean
,
ObjectName
.
class
,
name
);
}
public
static
boolean
injectsSendNotification
(
Object
mbean
)
throws
NotCompliantMBeanException
{
ClassInjector
injector
=
injectorForClass
(
mbean
.
getClass
());
return
injector
.
injects
(
SendNotification
.
class
);
}
public
static
void
injectSendNotification
(
Object
mbean
,
SendNotification
sn
)
throws
Exception
{
ClassInjector
injector
=
injectorForClass
(
mbean
.
getClass
());
injector
.
inject
(
mbean
,
SendNotification
.
class
,
sn
);
}
public
static
void
validate
(
Class
<?>
c
)
throws
NotCompliantMBeanException
{
injectorForClass
(
c
);
}
private
static
class
ClassInjector
{
private
Map
<
Class
<?>,
List
<
Field
>>
fields
;
private
Map
<
Class
<?>,
List
<
Method
>>
methods
;
ClassInjector
(
Class
<?>
c
)
throws
NotCompliantMBeanException
{
fields
=
newMap
();
methods
=
newMap
();
Class
<?>
sup
=
c
.
getSuperclass
();
ClassInjector
supInjector
;
if
(
sup
==
null
)
{
supInjector
=
null
;
}
else
{
supInjector
=
injectorForClass
(
sup
);
fields
.
putAll
(
supInjector
.
fields
);
methods
.
putAll
(
supInjector
.
methods
);
}
addMembers
(
c
);
eliminateOverriddenMethods
();
// If we haven't added any new fields or methods to what we
// inherited, then we can share the parent's maps.
if
(
supInjector
!=
null
)
{
if
(
fields
.
equals
(
supInjector
.
fields
))
fields
=
supInjector
.
fields
;
if
(
methods
.
equals
(
supInjector
.
methods
))
methods
=
supInjector
.
methods
;
}
}
boolean
injects
(
Class
<?>
c
)
{
return
(
fields
.
get
(
c
)
!=
null
||
methods
.
get
(
c
)
!=
null
);
}
<
T
>
void
inject
(
Object
instance
,
Class
<
T
>
type
,
T
resource
)
throws
Exception
{
List
<
Field
>
fs
=
fields
.
get
(
type
);
if
(
fs
!=
null
)
{
for
(
Field
f
:
fs
)
f
.
set
(
instance
,
resource
);
}
List
<
Method
>
ms
=
methods
.
get
(
type
);
if
(
ms
!=
null
)
{
for
(
Method
m
:
ms
)
{
try
{
m
.
invoke
(
instance
,
resource
);
}
catch
(
InvocationTargetException
e
)
{
Throwable
cause
=
e
.
getCause
();
if
(
cause
instanceof
Error
)
throw
(
Error
)
cause
;
else
throw
(
Exception
)
cause
;
}
}
}
}
private
void
eliminateOverriddenMethods
()
{
/* Covariant overriding is unlikely, but it is possible that the
* parent has a @Resource method that we override with another
* @Resource method. We don't want to invoke both methods,
* because polymorphism means we would actually invoke the same
* method twice.
*/
for
(
Map
.
Entry
<
Class
<?>,
List
<
Method
>>
entry
:
methods
.
entrySet
())
{
List
<
Method
>
list
=
entry
.
getValue
();
list
=
MBeanAnalyzer
.
eliminateCovariantMethods
(
list
);
entry
.
setValue
(
list
);
}
}
/*
* Find Fields or Methods within the given Class that we can inject
* resource references into. Suppose we want to know if a Field can get
* a reference to an ObjectName. We'll accept fields like this:
*
* @Resource
* private transient ObjectName name;
*
* or like this:
*
* @Resource(type = ObjectName.class)
* private transient Object name;
*
* but not like this:
*
* @Resource
* private transient Object name;
*
* (Plain @Resource is equivalent to @Resource(type = Object.class).)
*
* We don't want to inject into everything that might possibly accept
* an ObjectName reference, because examples like the last one above
* could also accept an MBeanServer reference or any other sort of
* reference.
*
* So we accept a Field if it has a @Resource annotation and either
* (a) its type is ObjectName or a subclass and its @Resource type is
* compatible with ObjectName (e.g. it is Object); or
* (b) its type is compatible with ObjectName and its @Resource type
* is exactly ObjectName. Fields that meet these criteria will not
* meet the same criteria with respect to other types such as MBeanServer.
*
* The same logic applies mutatis mutandis to Methods such as this:
*
* @Resource
* private void setObjectName1(ObjectName name)
* @Resource(type = Object.class)
* private void setObjectName2(Object name)
*/
private
void
addMembers
(
final
Class
<?>
c
)
throws
NotCompliantMBeanException
{
AccessibleObject
[][]
memberArrays
=
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
AccessibleObject
[][]>()
{
public
AccessibleObject
[][]
run
()
{
return
new
AccessibleObject
[][]
{
c
.
getDeclaredFields
(),
c
.
getDeclaredMethods
()
};
}
});
for
(
AccessibleObject
[]
members
:
memberArrays
)
{
for
(
final
AccessibleObject
member
:
members
)
{
Resource
res
=
member
.
getAnnotation
(
Resource
.
class
);
if
(
res
==
null
)
continue
;
final
Field
field
;
final
Method
method
;
final
Class
<?>
memberType
;
final
int
modifiers
;
if
(
member
instanceof
Field
)
{
field
=
(
Field
)
member
;
memberType
=
field
.
getType
();
modifiers
=
field
.
getModifiers
();
method
=
null
;
}
else
{
field
=
null
;
method
=
(
Method
)
member
;
Class
<?>[]
paramTypes
=
method
.
getParameterTypes
();
if
(
paramTypes
.
length
!=
1
)
{
throw
new
NotCompliantMBeanException
(
"@Resource method must have exactly 1 "
+
"parameter: "
+
method
);
}
if
(
method
.
getReturnType
()
!=
void
.
class
)
{
throw
new
NotCompliantMBeanException
(
"@Resource method must return void: "
+
method
);
}
memberType
=
paramTypes
[
0
];
modifiers
=
method
.
getModifiers
();
}
if
(
Modifier
.
isStatic
(
modifiers
))
{
throw
new
NotCompliantMBeanException
(
"@Resource method or field cannot be static: "
+
member
);
}
for
(
Class
<?>
injectedClass
:
injectedClasses
)
{
Class
<?>[]
types
=
{
memberType
,
res
.
type
()};
boolean
accept
=
false
;
for
(
int
i
=
0
;
i
<
2
;
i
++)
{
if
(
types
[
i
]
==
injectedClass
&&
types
[
1
-
i
].
isAssignableFrom
(
injectedClass
))
{
accept
=
true
;
break
;
}
}
if
(
accept
)
{
AccessController
.
doPrivileged
(
new
PrivilegedAction
<
Void
>()
{
public
Void
run
()
{
member
.
setAccessible
(
true
);
return
null
;
}
});
addToMap
(
fields
,
injectedClass
,
field
);
addToMap
(
methods
,
injectedClass
,
method
);
}
}
}
}
}
private
static
<
K
,
V
>
void
addToMap
(
Map
<
K
,
List
<
V
>>
map
,
K
key
,
V
value
)
{
if
(
value
==
null
)
return
;
List
<
V
>
list
=
map
.
get
(
key
);
if
(
list
==
null
)
list
=
Collections
.
singletonList
(
value
);
else
{
if
(
list
.
size
()
==
1
)
list
=
new
ArrayList
<
V
>(
list
);
list
.
add
(
value
);
}
map
.
put
(
key
,
list
);
}
}
private
static
synchronized
ClassInjector
injectorForClass
(
Class
<?>
c
)
throws
NotCompliantMBeanException
{
WeakReference
<
ClassInjector
>
wr
=
injectorMap
.
get
(
c
);
ClassInjector
ci
=
(
wr
==
null
)
?
null
:
wr
.
get
();
if
(
ci
==
null
)
{
ci
=
new
ClassInjector
(
c
);
injectorMap
.
put
(
c
,
new
WeakReference
<
ClassInjector
>(
ci
));
}
return
ci
;
}
private
static
Map
<
Class
<?>,
WeakReference
<
ClassInjector
>>
injectorMap
=
new
WeakHashMap
<
Class
<?>,
WeakReference
<
ClassInjector
>>();
}
src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java
浏览文件 @
0a690d3a
...
...
@@ -36,20 +36,28 @@ import java.lang.reflect.Method;
import
java.lang.reflect.Type
;
import
java.util.Arrays
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.WeakHashMap
;
import
javax.management.Description
;
import
javax.management.Descriptor
;
import
javax.management.ImmutableDescriptor
;
import
javax.management.IntrospectionException
;
import
javax.management.InvalidAttributeValueException
;
import
javax.management.MBean
;
import
javax.management.MBeanAttributeInfo
;
import
javax.management.MBeanConstructorInfo
;
import
javax.management.MBeanException
;
import
javax.management.MBeanInfo
;
import
javax.management.MBeanNotificationInfo
;
import
javax.management.MBeanOperationInfo
;
import
javax.management.MXBean
;
import
javax.management.ManagedAttribute
;
import
javax.management.ManagedOperation
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.NotificationBroadcaster
;
import
javax.management.NotificationInfo
;
import
javax.management.NotificationInfos
;
import
javax.management.ReflectionException
;
/**
...
...
@@ -153,6 +161,25 @@ abstract class MBeanIntrospector<M> {
abstract
MBeanAttributeInfo
getMBeanAttributeInfo
(
String
attributeName
,
M
getter
,
M
setter
)
throws
IntrospectionException
;
final
String
getAttributeDescription
(
String
attributeName
,
String
defaultDescription
,
Method
getter
,
Method
setter
)
throws
IntrospectionException
{
String
g
=
Introspector
.
descriptionForElement
(
getter
);
String
s
=
Introspector
.
descriptionForElement
(
setter
);
if
(
g
==
null
)
{
if
(
s
==
null
)
return
defaultDescription
;
else
return
s
;
}
else
if
(
s
==
null
||
g
.
equals
(
s
))
{
return
g
;
}
else
{
throw
new
IntrospectionException
(
"Inconsistent @Description on getter and setter for "
+
"attribute "
+
attributeName
);
}
}
/**
* Construct an MBeanOperationInfo for the given operation based on
* the M it was derived from.
...
...
@@ -184,8 +211,12 @@ abstract class MBeanIntrospector<M> {
}
void
checkCompliance
(
Class
<?>
mbeanType
)
throws
NotCompliantMBeanException
{
if
(!
mbeanType
.
isInterface
())
{
throw
new
NotCompliantMBeanException
(
"Not an interface: "
+
if
(!
mbeanType
.
isInterface
()
&&
!
mbeanType
.
isAnnotationPresent
(
MBean
.
class
)
&&
!
Introspector
.
hasMXBeanAnnotation
(
mbeanType
))
{
throw
new
NotCompliantMBeanException
(
"Not an interface and "
+
"does not have @"
+
MBean
.
class
.
getSimpleName
()
+
" or @"
+
MXBean
.
class
.
getSimpleName
()
+
" annotation: "
+
mbeanType
.
getName
());
}
}
...
...
@@ -194,7 +225,12 @@ abstract class MBeanIntrospector<M> {
* Get the methods to be analyzed to build the MBean interface.
*/
List
<
Method
>
getMethods
(
final
Class
<?>
mbeanType
)
throws
Exception
{
return
Arrays
.
asList
(
mbeanType
.
getMethods
());
if
(
mbeanType
.
isInterface
())
return
Arrays
.
asList
(
mbeanType
.
getMethods
());
final
List
<
Method
>
methods
=
newList
();
getAnnotatedMethods
(
mbeanType
,
methods
);
return
methods
;
}
final
PerInterface
<
M
>
getPerInterface
(
Class
<?>
mbeanInterface
)
...
...
@@ -232,8 +268,11 @@ abstract class MBeanIntrospector<M> {
MBeanAnalyzer
<
M
>
analyzer
)
throws
IntrospectionException
{
final
MBeanInfoMaker
maker
=
new
MBeanInfoMaker
();
analyzer
.
visit
(
maker
);
final
String
description
=
final
String
de
faultDe
scription
=
"Information on the management interface of the MBean"
;
String
description
=
Introspector
.
descriptionForElement
(
mbeanInterface
);
if
(
description
==
null
)
description
=
defaultDescription
;
return
maker
.
makeMBeanInfo
(
mbeanInterface
,
description
);
}
...
...
@@ -407,7 +446,15 @@ abstract class MBeanIntrospector<M> {
throws
NotCompliantMBeanException
{
MBeanInfo
mbi
=
getClassMBeanInfo
(
resource
.
getClass
(),
perInterface
);
MBeanNotificationInfo
[]
notifs
=
findNotifications
(
resource
);
MBeanNotificationInfo
[]
notifs
;
try
{
notifs
=
findNotifications
(
resource
);
}
catch
(
RuntimeException
e
)
{
NotCompliantMBeanException
x
=
new
NotCompliantMBeanException
(
e
.
getMessage
());
x
.
initCause
(
e
);
throw
x
;
}
Descriptor
d
=
getSpecificMBeanDescriptor
();
boolean
anyNotifs
=
(
notifs
!=
null
&&
notifs
.
length
>
0
);
if
(!
anyNotifs
&&
ImmutableDescriptor
.
EMPTY_DESCRIPTOR
.
equals
(
d
))
...
...
@@ -460,13 +507,43 @@ abstract class MBeanIntrospector<M> {
}
}
/*
* Add to "methods" every public method that has the @ManagedAttribute
* or @ManagedOperation annotation, in the given class or any of
* its superclasses or superinterfaces.
*
* We always add superclass or superinterface methods first, so that
* the stable sort used by eliminateCovariantMethods will put the
* method from the most-derived class last. This means that we will
* see the version of the @ManagedAttribute (or ...Operation) annotation
* from that method, which might have a different description or whatever.
*/
private
static
void
getAnnotatedMethods
(
Class
<?>
c
,
List
<
Method
>
methods
)
throws
Exception
{
Class
<?>
sup
=
c
.
getSuperclass
();
if
(
sup
!=
null
)
getAnnotatedMethods
(
sup
,
methods
);
Class
<?>[]
intfs
=
c
.
getInterfaces
();
for
(
Class
<?>
intf
:
intfs
)
getAnnotatedMethods
(
intf
,
methods
);
for
(
Method
m
:
c
.
getMethods
())
{
// We are careful not to add m if it is inherited from a parent
// class or interface, because duplicate methods lead to nasty
// behaviour in eliminateCovariantMethods.
if
(
m
.
getDeclaringClass
()
==
c
&&
(
m
.
isAnnotationPresent
(
ManagedAttribute
.
class
)
||
m
.
isAnnotationPresent
(
ManagedOperation
.
class
)))
methods
.
add
(
m
);
}
}
static
MBeanNotificationInfo
[]
findNotifications
(
Object
moi
)
{
if
(!(
moi
instanceof
NotificationBroadcaster
))
return
null
;
MBeanNotificationInfo
[]
mbn
=
((
NotificationBroadcaster
)
moi
).
getNotificationInfo
();
if
(
mbn
==
null
||
mbn
.
length
==
0
)
return
null
;
return
findNotificationsFromAnnotations
(
moi
.
getClass
())
;
MBeanNotificationInfo
[]
result
=
new
MBeanNotificationInfo
[
mbn
.
length
];
for
(
int
i
=
0
;
i
<
mbn
.
length
;
i
++)
{
...
...
@@ -478,11 +555,81 @@ abstract class MBeanIntrospector<M> {
return
result
;
}
private
static
MBeanNotificationInfo
[]
findNotificationsFromAnnotations
(
Class
<?>
mbeanClass
)
{
Class
<?>
c
=
getAnnotatedNotificationInfoClass
(
mbeanClass
);
if
(
c
==
null
)
return
null
;
NotificationInfo
ni
=
c
.
getAnnotation
(
NotificationInfo
.
class
);
NotificationInfos
nis
=
c
.
getAnnotation
(
NotificationInfos
.
class
);
List
<
NotificationInfo
>
list
=
newList
();
if
(
ni
!=
null
)
list
.
add
(
ni
);
if
(
nis
!=
null
)
list
.
addAll
(
Arrays
.
asList
(
nis
.
value
()));
if
(
list
.
isEmpty
())
return
null
;
List
<
MBeanNotificationInfo
>
mbnis
=
newList
();
for
(
NotificationInfo
x
:
list
)
{
// The Descriptor includes any fields explicitly specified by
// x.descriptorFields(), plus any fields from the contained
// @Description annotation.
Descriptor
d
=
new
ImmutableDescriptor
(
x
.
descriptorFields
());
d
=
ImmutableDescriptor
.
union
(
d
,
Introspector
.
descriptorForAnnotation
(
x
.
description
()));
MBeanNotificationInfo
mbni
=
new
MBeanNotificationInfo
(
x
.
types
(),
x
.
notificationClass
().
getName
(),
x
.
description
().
value
(),
d
);
mbnis
.
add
(
mbni
);
}
return
mbnis
.
toArray
(
new
MBeanNotificationInfo
[
mbnis
.
size
()]);
}
private
static
final
Map
<
Class
<?>,
WeakReference
<
Class
<?>>>
annotatedNotificationInfoClasses
=
newWeakHashMap
();
private
static
Class
<?>
getAnnotatedNotificationInfoClass
(
Class
<?>
baseClass
)
{
synchronized
(
annotatedNotificationInfoClasses
)
{
WeakReference
<
Class
<?>>
wr
=
annotatedNotificationInfoClasses
.
get
(
baseClass
);
if
(
wr
!=
null
)
return
wr
.
get
();
Class
<?>
c
=
null
;
if
(
baseClass
.
isAnnotationPresent
(
NotificationInfo
.
class
)
||
baseClass
.
isAnnotationPresent
(
NotificationInfos
.
class
))
{
c
=
baseClass
;
}
else
{
Class
<?>[]
intfs
=
baseClass
.
getInterfaces
();
for
(
Class
<?>
intf
:
intfs
)
{
Class
<?>
c1
=
getAnnotatedNotificationInfoClass
(
intf
);
if
(
c1
!=
null
)
{
if
(
c
!=
null
)
{
throw
new
IllegalArgumentException
(
"Class "
+
baseClass
.
getName
()
+
" inherits "
+
"@NotificationInfo(s) from both "
+
c
.
getName
()
+
" and "
+
c1
.
getName
());
}
c
=
c1
;
}
}
}
// Record the result of the search. If no @NotificationInfo(s)
// were found, c is null, and we store a WeakReference(null).
// This prevents us from having to search again and fail again.
annotatedNotificationInfoClasses
.
put
(
baseClass
,
new
WeakReference
<
Class
<?>>(
c
));
return
c
;
}
}
private
static
MBeanConstructorInfo
[]
findConstructors
(
Class
<?>
c
)
{
Constructor
[]
cons
=
c
.
getConstructors
();
MBeanConstructorInfo
[]
mbc
=
new
MBeanConstructorInfo
[
cons
.
length
];
for
(
int
i
=
0
;
i
<
cons
.
length
;
i
++)
{
final
String
descr
=
"Public constructor of the MBean"
;
String
descr
=
"Public constructor of the MBean"
;
Description
d
=
cons
[
i
].
getAnnotation
(
Description
.
class
);
if
(
d
!=
null
)
descr
=
d
.
value
();
mbc
[
i
]
=
new
MBeanConstructorInfo
(
descr
,
cons
[
i
]);
}
return
mbc
;
...
...
src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java
浏览文件 @
0a690d3a
...
...
@@ -263,10 +263,14 @@ public abstract class MBeanSupport<M>
return
resource
.
getClass
().
getName
();
}
public
final
Object
get
Resource
()
{
public
final
Object
get
WrappedObject
()
{
return
resource
;
}
public
final
ClassLoader
getWrappedClassLoader
()
{
return
resource
.
getClass
().
getClassLoader
();
}
public
final
Class
<?>
getMBeanInterface
()
{
return
perInterface
.
getMBeanInterface
();
}
...
...
src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java
浏览文件 @
0a690d3a
...
...
@@ -35,6 +35,7 @@ import java.lang.reflect.Method;
import
java.lang.reflect.Type
;
import
java.util.Map
;
import
java.util.WeakHashMap
;
import
javax.management.Description
;
import
javax.management.Descriptor
;
import
javax.management.ImmutableDescriptor
;
import
javax.management.IntrospectionException
;
...
...
@@ -43,6 +44,7 @@ import javax.management.MBeanAttributeInfo;
import
javax.management.MBeanException
;
import
javax.management.MBeanOperationInfo
;
import
javax.management.MBeanParameterInfo
;
import
javax.management.ManagedOperation
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.openmbean.MXBeanMappingFactory
;
import
javax.management.openmbean.OpenMBeanAttributeInfoSupport
;
...
...
@@ -180,7 +182,10 @@ class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
final
boolean
isWritable
=
(
setter
!=
null
);
final
boolean
isIs
=
isReadable
&&
getName
(
getter
).
startsWith
(
"is"
);
final
String
description
=
attributeName
;
final
String
description
=
getAttributeDescription
(
attributeName
,
attributeName
,
getter
==
null
?
null
:
getter
.
getMethod
(),
setter
==
null
?
null
:
setter
.
getMethod
());
final
OpenType
<?>
openType
;
final
Type
originalType
;
...
...
@@ -229,13 +234,17 @@ class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
MBeanOperationInfo
getMBeanOperationInfo
(
String
operationName
,
ConvertingMethod
operation
)
{
final
Method
method
=
operation
.
getMethod
();
final
String
description
=
operationName
;
String
description
=
operationName
;
/* Ideally this would be an empty string, but
OMBOperationInfo constructor forbids that. Also, we
could consult an annotation to get a useful
description. */
OMBOperationInfo constructor forbids that. */
Description
d
=
method
.
getAnnotation
(
Description
.
class
);
if
(
d
!=
null
)
description
=
d
.
value
();
final
int
impact
=
MBeanOperationInfo
.
UNKNOWN
;
int
impact
=
MBeanOperationInfo
.
UNKNOWN
;
ManagedOperation
annot
=
method
.
getAnnotation
(
ManagedOperation
.
class
);
if
(
annot
!=
null
)
impact
=
annot
.
impact
().
getCode
();
final
OpenType
<?>
returnType
=
operation
.
getOpenReturnType
();
final
Type
originalReturnType
=
operation
.
getGenericReturnType
();
...
...
@@ -247,8 +256,15 @@ class MXBeanIntrospector extends MBeanIntrospector<ConvertingMethod> {
boolean
openParameterTypes
=
true
;
Annotation
[][]
annots
=
method
.
getParameterAnnotations
();
for
(
int
i
=
0
;
i
<
paramTypes
.
length
;
i
++)
{
final
String
paramName
=
"p"
+
i
;
final
String
paramDescription
=
paramName
;
String
paramName
=
Introspector
.
nameForParameter
(
annots
[
i
]);
if
(
paramName
==
null
)
paramName
=
"p"
+
i
;
String
paramDescription
=
Introspector
.
descriptionForParameter
(
annots
[
i
]);
if
(
paramDescription
==
null
)
paramDescription
=
paramName
;
final
OpenType
<?>
openType
=
paramTypes
[
i
];
final
Type
originalType
=
originalParamTypes
[
i
];
Descriptor
descriptor
=
...
...
src/share/classes/com/sun/jmx/mbeanserver/MXBeanSupport.java
浏览文件 @
0a690d3a
...
...
@@ -161,7 +161,7 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
synchronized
(
lock
)
{
this
.
mxbeanLookup
=
MXBeanLookup
.
Plain
.
lookupFor
(
server
);
this
.
mxbeanLookup
.
addReference
(
name
,
get
Resource
());
this
.
mxbeanLookup
.
addReference
(
name
,
get
WrappedObject
());
this
.
objectName
=
name
;
}
}
...
...
@@ -170,7 +170,7 @@ public class MXBeanSupport extends MBeanSupport<ConvertingMethod> {
public
void
unregister
()
{
synchronized
(
lock
)
{
if
(
mxbeanLookup
!=
null
)
{
if
(
mxbeanLookup
.
removeReference
(
objectName
,
get
Resource
()))
if
(
mxbeanLookup
.
removeReference
(
objectName
,
get
WrappedObject
()))
objectName
=
null
;
}
// XXX: need to revisit the whole register/unregister logic in
...
...
src/share/classes/com/sun/jmx/mbeanserver/NotifySupport.java
0 → 100644
浏览文件 @
0a690d3a
/*
* Copyright 2007 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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.
*/
package
com.sun.jmx.mbeanserver
;
import
javax.management.Attribute
;
import
javax.management.AttributeList
;
import
javax.management.AttributeNotFoundException
;
import
javax.management.DynamicMBean
;
import
javax.management.DynamicWrapperMBean
;
import
javax.management.InvalidAttributeValueException
;
import
javax.management.ListenerNotFoundException
;
import
javax.management.MBeanException
;
import
javax.management.MBeanInfo
;
import
javax.management.MBeanNotificationInfo
;
import
javax.management.MBeanRegistration
;
import
javax.management.MBeanServer
;
import
javax.management.NotificationBroadcasterSupport
;
import
javax.management.NotificationEmitter
;
import
javax.management.NotificationFilter
;
import
javax.management.NotificationListener
;
import
javax.management.ObjectName
;
import
javax.management.ReflectionException
;
/**
* Create wrappers for DynamicMBean that implement NotificationEmitter
* and SendNotification.
*/
public
class
NotifySupport
implements
DynamicMBean2
,
NotificationEmitter
,
MBeanRegistration
{
private
final
DynamicMBean
mbean
;
private
final
NotificationBroadcasterSupport
nbs
;
public
static
DynamicMBean
wrap
(
DynamicMBean
mbean
,
NotificationBroadcasterSupport
nbs
)
{
return
new
NotifySupport
(
mbean
,
nbs
);
}
private
NotifySupport
(
DynamicMBean
mbean
,
NotificationBroadcasterSupport
nbs
)
{
this
.
mbean
=
mbean
;
this
.
nbs
=
nbs
;
}
public
static
NotificationBroadcasterSupport
getNB
(
DynamicMBean
mbean
)
{
if
(
mbean
instanceof
NotifySupport
)
return
((
NotifySupport
)
mbean
).
nbs
;
else
return
null
;
}
public
String
getClassName
()
{
if
(
mbean
instanceof
DynamicMBean2
)
return
((
DynamicMBean2
)
mbean
).
getClassName
();
Object
w
=
mbean
;
if
(
w
instanceof
DynamicWrapperMBean
)
w
=
((
DynamicWrapperMBean
)
w
).
getWrappedObject
();
return
w
.
getClass
().
getName
();
}
public
void
preRegister2
(
MBeanServer
mbs
,
ObjectName
name
)
throws
Exception
{
if
(
mbean
instanceof
DynamicMBean2
)
((
DynamicMBean2
)
mbean
).
preRegister2
(
mbs
,
name
);
}
public
void
registerFailed
()
{
if
(
mbean
instanceof
DynamicMBean2
)
((
DynamicMBean2
)
mbean
).
registerFailed
();
}
public
Object
getWrappedObject
()
{
if
(
mbean
instanceof
DynamicWrapperMBean
)
return
((
DynamicWrapperMBean
)
mbean
).
getWrappedObject
();
else
return
mbean
;
}
public
ClassLoader
getWrappedClassLoader
()
{
if
(
mbean
instanceof
DynamicWrapperMBean
)
return
((
DynamicWrapperMBean
)
mbean
).
getWrappedClassLoader
();
else
return
mbean
.
getClass
().
getClassLoader
();
}
public
Object
getAttribute
(
String
attribute
)
throws
AttributeNotFoundException
,
MBeanException
,
ReflectionException
{
return
mbean
.
getAttribute
(
attribute
);
}
public
void
setAttribute
(
Attribute
attribute
)
throws
AttributeNotFoundException
,
InvalidAttributeValueException
,
MBeanException
,
ReflectionException
{
mbean
.
setAttribute
(
attribute
);
}
public
AttributeList
setAttributes
(
AttributeList
attributes
)
{
return
mbean
.
setAttributes
(
attributes
);
}
public
Object
invoke
(
String
actionName
,
Object
[]
params
,
String
[]
signature
)
throws
MBeanException
,
ReflectionException
{
return
mbean
.
invoke
(
actionName
,
params
,
signature
);
}
public
MBeanInfo
getMBeanInfo
()
{
return
mbean
.
getMBeanInfo
();
}
public
AttributeList
getAttributes
(
String
[]
attributes
)
{
return
mbean
.
getAttributes
(
attributes
);
}
public
void
removeNotificationListener
(
NotificationListener
listener
,
NotificationFilter
filter
,
Object
handback
)
throws
ListenerNotFoundException
{
nbs
.
removeNotificationListener
(
listener
,
filter
,
handback
);
}
public
void
removeNotificationListener
(
NotificationListener
listener
)
throws
ListenerNotFoundException
{
nbs
.
removeNotificationListener
(
listener
);
}
public
MBeanNotificationInfo
[]
getNotificationInfo
()
{
return
nbs
.
getNotificationInfo
();
}
public
void
addNotificationListener
(
NotificationListener
listener
,
NotificationFilter
filter
,
Object
handback
)
{
nbs
.
addNotificationListener
(
listener
,
filter
,
handback
);
}
public
ObjectName
preRegister
(
MBeanServer
server
,
ObjectName
name
)
throws
Exception
{
if
(
mbr
()
!=
null
)
return
mbr
().
preRegister
(
server
,
name
);
else
return
name
;
}
public
void
postRegister
(
Boolean
registrationDone
)
{
if
(
mbr
()
!=
null
)
mbr
().
postRegister
(
registrationDone
);
}
public
void
preDeregister
()
throws
Exception
{
if
(
mbr
()
!=
null
)
mbr
().
preDeregister
();
}
public
void
postDeregister
()
{
if
(
mbr
()
!=
null
)
mbr
().
postDeregister
();
}
private
MBeanRegistration
mbr
()
{
if
(
mbean
instanceof
MBeanRegistration
)
return
(
MBeanRegistration
)
mbean
;
else
return
null
;
}
}
src/share/classes/com/sun/jmx/mbeanserver/Repository.java
浏览文件 @
0a690d3a
...
...
@@ -29,6 +29,7 @@ import com.sun.jmx.defaults.ServiceName;
import
static
com
.
sun
.
jmx
.
defaults
.
JmxProperties
.
MBEANSERVER_LOGGER
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.List
;
...
...
@@ -39,7 +40,6 @@ import java.util.Set;
import
javax.management.DynamicMBean
;
import
javax.management.InstanceAlreadyExistsException
;
import
javax.management.InstanceNotFoundException
;
import
javax.management.MalformedObjectNameException
;
import
javax.management.ObjectName
;
import
javax.management.QueryExp
;
import
javax.management.RuntimeOperationsException
;
...
...
@@ -52,6 +52,27 @@ import javax.management.RuntimeOperationsException;
*/
public
class
Repository
{
/**
* An interface that allows the caller to get some control
* over the registration.
* @see #addMBean
* @see #remove
*/
public
interface
RegistrationContext
{
/**
* Called by {@link #addMBean}.
* Can throw a RuntimeOperationsException to cancel the
* registration.
*/
public
void
registering
();
/**
* Called by {@link #remove}.
* Any exception thrown by this method will be ignored.
*/
public
void
unregistered
();
}
// Private fields -------------------------------------------->
/**
...
...
@@ -115,7 +136,6 @@ public class Repository {
/**
* Builds a new ObjectNamePattern object from an ObjectName pattern
* constituents.
* @param domain pattern.getDomain().
* @param propertyListPattern pattern.isPropertyListPattern().
* @param propertyValuePattern pattern.isPropertyValuePattern().
* @param canonicalProps pattern.getCanonicalKeyPropertyListString().
...
...
@@ -216,16 +236,6 @@ public class Repository {
}
}
private
void
addNewDomMoi
(
final
DynamicMBean
object
,
final
String
dom
,
final
ObjectName
name
)
{
final
Map
<
String
,
NamedObject
>
moiTb
=
new
HashMap
<
String
,
NamedObject
>();
moiTb
.
put
(
name
.
getCanonicalKeyPropertyListString
(),
new
NamedObject
(
name
,
object
));
domainTb
.
put
(
dom
,
moiTb
);
nbElements
++;
}
/** Match a string against a shell-style pattern. The only pattern
characters recognised are <code>?</code>, standing for any one
character, and <code>*</code>, standing for any string of
...
...
@@ -306,6 +316,50 @@ public class Repository {
}
}
private
void
addNewDomMoi
(
final
DynamicMBean
object
,
final
String
dom
,
final
ObjectName
name
,
final
RegistrationContext
context
)
{
final
Map
<
String
,
NamedObject
>
moiTb
=
new
HashMap
<
String
,
NamedObject
>();
final
String
key
=
name
.
getCanonicalKeyPropertyListString
();
addMoiToTb
(
object
,
name
,
key
,
moiTb
,
context
);
domainTb
.
put
(
dom
,
moiTb
);
nbElements
++;
}
private
void
registering
(
RegistrationContext
context
)
{
if
(
context
==
null
)
return
;
try
{
context
.
registering
();
}
catch
(
RuntimeOperationsException
x
)
{
throw
x
;
}
catch
(
RuntimeException
x
)
{
throw
new
RuntimeOperationsException
(
x
);
}
}
private
void
unregistering
(
RegistrationContext
context
,
ObjectName
name
)
{
if
(
context
==
null
)
return
;
try
{
context
.
unregistered
();
}
catch
(
Exception
x
)
{
// shouldn't come here...
MBEANSERVER_LOGGER
.
log
(
Level
.
FINE
,
"Unexpected exception while unregistering "
+
name
,
x
);
}
}
private
void
addMoiToTb
(
final
DynamicMBean
object
,
final
ObjectName
name
,
final
String
key
,
final
Map
<
String
,
NamedObject
>
moiTb
,
final
RegistrationContext
context
)
{
registering
(
context
);
moiTb
.
put
(
key
,
new
NamedObject
(
name
,
object
));
}
/**
* Retrieves the named object contained in repository
* from the given objectname.
...
...
@@ -355,12 +409,12 @@ public class Repository {
domainTb
=
new
HashMap
<
String
,
Map
<
String
,
NamedObject
>>(
5
);
if
(
domain
!=
null
&&
domain
.
length
()
!=
0
)
this
.
domain
=
domain
;
this
.
domain
=
domain
.
intern
();
// we use == domain later on...
else
this
.
domain
=
ServiceName
.
DOMAIN
;
// Creates a
n new has
table for the default domain
domainTb
.
put
(
this
.
domain
.
intern
()
,
new
HashMap
<
String
,
NamedObject
>());
// Creates a
new hash
table for the default domain
domainTb
.
put
(
this
.
domain
,
new
HashMap
<
String
,
NamedObject
>());
}
/**
...
...
@@ -395,10 +449,21 @@ public class Repository {
/**
* Stores an MBean associated with its object name in the repository.
*
* @param object MBean to be stored in the repository.
* @param name MBean object name.
* @param object MBean to be stored in the repository.
* @param name MBean object name.
* @param context A registration context. If non null, the repository
* will call {@link RegistrationContext#registering()
* context.registering()} from within the repository
* lock, when it has determined that the {@code object}
* can be stored in the repository with that {@code name}.
* If {@link RegistrationContext#registering()
* context.registering()} throws an exception, the
* operation is abandonned, the MBean is not added to the
* repository, and a {@link RuntimeOperationsException}
* is thrown.
*/
public
void
addMBean
(
final
DynamicMBean
object
,
ObjectName
name
)
public
void
addMBean
(
final
DynamicMBean
object
,
ObjectName
name
,
final
RegistrationContext
context
)
throws
InstanceAlreadyExistsException
{
if
(
MBEANSERVER_LOGGER
.
isLoggable
(
Level
.
FINER
))
{
...
...
@@ -431,7 +496,7 @@ public class Repository {
lock
.
writeLock
().
lock
();
try
{
// Domain cannot be JMImplementation if entry does not exist
s
// Domain cannot be JMImplementation if entry does not exist
if
(
!
to_default_domain
&&
dom
.
equals
(
"JMImplementation"
)
&&
domainTb
.
containsKey
(
"JMImplementation"
))
{
...
...
@@ -440,21 +505,21 @@ public class Repository {
"Repository: domain name cannot be JMImplementation"
));
}
// If domain
not already exists
, add it to the hash table
// If domain
does not already exist
, add it to the hash table
final
Map
<
String
,
NamedObject
>
moiTb
=
domainTb
.
get
(
dom
);
if
(
moiTb
==
null
)
{
addNewDomMoi
(
object
,
dom
,
name
);
addNewDomMoi
(
object
,
dom
,
name
,
context
);
return
;
}
// Add instance if not already present
String
cstr
=
name
.
getCanonicalKeyPropertyListString
();
NamedObject
elmt
=
moiTb
.
get
(
cstr
);
if
(
elmt
!=
null
)
{
throw
new
InstanceAlreadyExistsException
(
name
.
toString
());
}
else
{
nbElements
++;
moiTb
.
put
(
cstr
,
new
NamedObject
(
name
,
object
));
// Add instance if not already present
String
cstr
=
name
.
getCanonicalKeyPropertyListString
();
NamedObject
elmt
=
moiTb
.
get
(
cstr
);
if
(
elmt
!=
null
)
{
throw
new
InstanceAlreadyExistsException
(
name
.
toString
());
}
else
{
nbElements
++;
addMoiToTb
(
object
,
name
,
cstr
,
moiTb
,
context
);
}
}
}
finally
{
...
...
@@ -533,7 +598,7 @@ public class Repository {
// ":*", ":[key=value],*" : names in defaultDomain
// "domain:*", "domain:[key=value],*" : names in the specified domain
// Surely one of the most frequent case ... query on the whole world
// Surely one of the most frequent case
s
... query on the whole world
ObjectName
name
;
if
(
pattern
==
null
||
pattern
.
getCanonicalName
().
length
()
==
0
||
...
...
@@ -546,8 +611,7 @@ public class Repository {
// If pattern is not a pattern, retrieve this mbean !
if
(!
name
.
isPattern
())
{
final
NamedObject
no
;
no
=
retrieveNamedObject
(
name
);
final
NamedObject
no
=
retrieveNamedObject
(
name
);
if
(
no
!=
null
)
result
.
add
(
no
);
return
result
;
}
...
...
@@ -577,12 +641,22 @@ public class Repository {
return
result
;
}
if
(!
name
.
isDomainPattern
())
{
final
Map
<
String
,
NamedObject
>
moiTb
=
domainTb
.
get
(
name
.
getDomain
());
if
(
moiTb
==
null
)
return
Collections
.
emptySet
();
if
(
allNames
)
result
.
addAll
(
moiTb
.
values
());
else
addAllMatching
(
moiTb
,
result
,
namePattern
);
return
result
;
}
// Pattern matching in the domain name (*, ?)
char
[]
dom2Match
=
name
.
getDomain
().
toCharArray
();
for
(
String
dom
ain
:
domainTb
.
keySet
())
{
char
[]
theDom
=
dom
ain
.
toCharArray
();
for
(
String
dom
:
domainTb
.
keySet
())
{
char
[]
theDom
=
dom
.
toCharArray
();
if
(
wildmatch
(
theDom
,
dom2Match
))
{
final
Map
<
String
,
NamedObject
>
moiTb
=
domainTb
.
get
(
dom
ain
);
final
Map
<
String
,
NamedObject
>
moiTb
=
domainTb
.
get
(
dom
);
if
(
allNames
)
result
.
addAll
(
moiTb
.
values
());
else
...
...
@@ -599,11 +673,21 @@ public class Repository {
* Removes an MBean from the repository.
*
* @param name name of the MBean to remove.
* @param context A registration context. If non null, the repository
* will call {@link RegistrationContext#unregistered()
* context.unregistered()} from within the repository
* lock, just after the mbean associated with
* {@code name} is removed from the repository.
* If {@link RegistrationContext#unregistered()
* context.unregistered()} is not expected to throw any
* exception. If it does, the exception is logged
* and swallowed.
*
* @exception InstanceNotFoundException The MBean does not exist in
* the repository.
*/
public
void
remove
(
final
ObjectName
name
)
public
void
remove
(
final
ObjectName
name
,
final
RegistrationContext
context
)
throws
InstanceNotFoundException
{
// Debugging stuff
...
...
@@ -645,6 +729,9 @@ public class Repository {
if
(
dom
==
domain
)
domainTb
.
put
(
domain
,
new
HashMap
<
String
,
NamedObject
>());
}
unregistering
(
context
,
name
);
}
finally
{
lock
.
writeLock
().
unlock
();
}
...
...
src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanIntrospector.java
浏览文件 @
0a690d3a
...
...
@@ -35,6 +35,7 @@ import javax.management.IntrospectionException;
import
javax.management.MBeanAttributeInfo
;
import
javax.management.MBeanException
;
import
javax.management.MBeanOperationInfo
;
import
javax.management.ManagedOperation
;
import
javax.management.NotCompliantMBeanException
;
import
javax.management.NotificationBroadcaster
;
import
javax.management.NotificationBroadcasterSupport
;
...
...
@@ -118,22 +119,32 @@ class StandardMBeanIntrospector extends MBeanIntrospector<Method> {
@Override
MBeanAttributeInfo
getMBeanAttributeInfo
(
String
attributeName
,
Method
getter
,
Method
setter
)
{
final
String
description
=
"Attribute exposed for management"
;
try
{
return
new
MBeanAttributeInfo
(
attributeName
,
description
,
getter
,
setter
);
}
catch
(
IntrospectionException
e
)
{
throw
new
RuntimeException
(
e
);
// should not happen
}
Method
getter
,
Method
setter
)
throws
IntrospectionException
{
String
description
=
getAttributeDescription
(
attributeName
,
"Attribute exposed for management"
,
getter
,
setter
);
return
new
MBeanAttributeInfo
(
attributeName
,
description
,
getter
,
setter
);
}
@Override
MBeanOperationInfo
getMBeanOperationInfo
(
String
operationName
,
Method
operation
)
{
final
String
description
=
"Operation exposed for management"
;
return
new
MBeanOperationInfo
(
description
,
operation
);
final
String
defaultDescription
=
"Operation exposed for management"
;
String
description
=
Introspector
.
descriptionForElement
(
operation
);
if
(
description
==
null
)
description
=
defaultDescription
;
int
impact
=
MBeanOperationInfo
.
UNKNOWN
;
ManagedOperation
annot
=
operation
.
getAnnotation
(
ManagedOperation
.
class
);
if
(
annot
!=
null
)
impact
=
annot
.
impact
().
getCode
();
MBeanOperationInfo
mboi
=
new
MBeanOperationInfo
(
description
,
operation
);
return
new
MBeanOperationInfo
(
mboi
.
getName
(),
mboi
.
getDescription
(),
mboi
.
getSignature
(),
mboi
.
getReturnType
(),
impact
,
mboi
.
getDescriptor
());
}
@Override
...
...
src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanSupport.java
浏览文件 @
0a690d3a
...
...
@@ -41,26 +41,24 @@ import javax.management.openmbean.MXBeanMappingFactory;
public
class
StandardMBeanSupport
extends
MBeanSupport
<
Method
>
{
/**
<p>Construct a Standard MBean that wraps the given resource using the
given Standard MBean interface.</p>
@param resource the underlying resource for the new MBean.
@param mbeanInterface the interface to be used to determine
the MBean's management interface.
@param <T> a type parameter that allows the compiler to check
that {@code resource} implements {@code mbeanInterface},
provided that {@code mbeanInterface} is a class constant like
{@code SomeMBean.class}.
@throws IllegalArgumentException if {@code resource} is null or
if it does not implement the class {@code mbeanInterface} or if
that class is not a valid Standard MBean interface.
*/
public
<
T
>
StandardMBeanSupport
(
T
resource
,
Class
<
T
>
mbeanInterface
)
* <p>Construct a Standard MBean that wraps the given resource using the
* given Standard MBean interface.</p>
*
* @param resource the underlying resource for the new MBean.
* @param mbeanInterfaceType the class or interface to be used to determine
* the MBean's management interface. An interface if this is a
* classic Standard MBean; a class if this is a {@code @ManagedResource}.
* @param <T> a type parameter that allows the compiler to check
* that {@code resource} implements {@code mbeanInterfaceType},
* provided that {@code mbeanInterfaceType} is a class constant like
* {@code SomeMBean.class}.
* @throws IllegalArgumentException if {@code resource} is null or
* if it does not implement the class {@code mbeanInterfaceType} or if
* that class is not a valid Standard MBean interface.
*/
public
<
T
>
StandardMBeanSupport
(
T
resource
,
Class
<
T
>
mbeanInterfaceType
)
throws
NotCompliantMBeanException
{
super
(
resource
,
mbeanInterface
,
(
MXBeanMappingFactory
)
null
);
super
(
resource
,
mbeanInterface
Type
,
(
MXBeanMappingFactory
)
null
);
}
@Override
...
...
@@ -86,13 +84,14 @@ public class StandardMBeanSupport extends MBeanSupport<Method> {
@Override
public
MBeanInfo
getMBeanInfo
()
{
MBeanInfo
mbi
=
super
.
getMBeanInfo
();
Class
<?>
resourceClass
=
getResource
().
getClass
();
if
(
StandardMBeanIntrospector
.
isDefinitelyImmutableInfo
(
resourceClass
))
Class
<?>
resourceClass
=
getWrappedObject
().
getClass
();
if
(!
getMBeanInterface
().
isInterface
()
||
StandardMBeanIntrospector
.
isDefinitelyImmutableInfo
(
resourceClass
))
return
mbi
;
return
new
MBeanInfo
(
mbi
.
getClassName
(),
mbi
.
getDescription
(),
mbi
.
getAttributes
(),
mbi
.
getConstructors
(),
mbi
.
getOperations
(),
MBeanIntrospector
.
findNotifications
(
get
Resource
()),
MBeanIntrospector
.
findNotifications
(
get
WrappedObject
()),
mbi
.
getDescriptor
());
}
}
src/share/classes/com/sun/jmx/mbeanserver/Util.java
浏览文件 @
0a690d3a
...
...
@@ -38,6 +38,7 @@ import java.util.Map;
import
java.util.Set
;
import
java.util.SortedMap
;
import
java.util.TreeMap
;
import
java.util.WeakHashMap
;
import
javax.management.MalformedObjectNameException
;
import
javax.management.ObjectName
;
...
...
@@ -71,6 +72,10 @@ public class Util {
return
new
LinkedHashMap
<
K
,
V
>();
}
static
<
K
,
V
>
WeakHashMap
<
K
,
V
>
newWeakHashMap
()
{
return
new
WeakHashMap
<
K
,
V
>();
}
static
<
E
>
Set
<
E
>
newSet
()
{
return
new
HashSet
<
E
>();
}
...
...
src/share/classes/javax/management/BinaryRelQueryExp.java
浏览文件 @
0a690d3a
...
...
@@ -192,6 +192,7 @@ class BinaryRelQueryExp extends QueryEval implements QueryExp {
return
"("
+
exp1
+
") "
+
relOpString
()
+
" ("
+
exp2
+
")"
;
}
@Override
String
toQueryString
()
{
return
exp1
+
" "
+
relOpString
()
+
" "
+
exp2
;
}
...
...
src/share/classes/javax/management/Description.java
0 → 100644
浏览文件 @
0a690d3a
/*
* Copyright 2007 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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.
*/
package
javax.management
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
import
java.util.ResourceBundle
;
/**
* <p>The textual description of an MBean or part of an MBean. This
* description is intended to be displayed to users to help them
* understand what the MBean does. Ultimately it will be the value of
* the {@code getDescription()} method of an {@link MBeanInfo}, {@link
* MBeanAttributeInfo}, or similar.</p>
*
* <p>This annotation applies to Standard MBean interfaces and to
* MXBean interfaces, as well as to MBean classes defined using the
* {@link MBean @MBean} or {@link MXBean @MXBean} annotations. For
* example, a Standard MBean might be defined like this:</p>
*
* <pre>
* <b>{@code @Description}</b>("Application configuration")
* public interface ConfigurationMBean {
* <b>{@code @Description}</b>("Cache size in bytes")
* public int getCacheSize();
* public void setCacheSize(int size);
*
* <b>{@code @Description}</b>("Last time the configuration was changed, " +
* "in milliseconds since 1 Jan 1970")
* public long getLastChangedTime();
*
* <b>{@code @Description}</b>("Save the configuration to a file")
* public void save(
* <b>{@code @Description}</b>("Optional name of the file, or null for the default name")
* String fileName);
* }
* </pre>
*
* <p>The {@code MBeanInfo} for this MBean will have a {@link
* MBeanInfo#getDescription() getDescription()} that is {@code
* "Application configuration"}. It will contain an {@code
* MBeanAttributeInfo} for the {@code CacheSize} attribute that is
* defined by the methods {@code getCacheSize} and {@code
* setCacheSize}, and another {@code MBeanAttributeInfo} for {@code
* LastChangedTime}. The {@link MBeanAttributeInfo#getDescription()
* getDescription()} for {@code CacheSize} will be {@code "Cache size
* in bytes"}. Notice that there is no need to add a
* {@code @Description} to both {@code getCacheSize} and {@code
* setCacheSize} - either alone will do. But if you do add a
* {@code @Description} to both, it must be the same.</p>
*
* <p>The {@code MBeanInfo} will also contain an {@link
* MBeanOperationInfo} where {@link
* MBeanOperationInfo#getDescription() getDescription()} is {@code
* "Save the configuration to a file"}. This {@code
* MBeanOperationInfo} will contain an {@link MBeanParameterInfo}
* where {@link MBeanParameterInfo#getDescription() getDescription()}
* is {@code "Optional name of the file, or null for the default
* name"}.</p>
*
* <p>The {@code @Description} annotation can also be applied to the
* public constructors of the implementation class. Continuing the
* above example, the {@code Configuration} class implementing {@code
* ConfigurationMBean} might look like this:</p>
*
* <pre>
* public class Configuration implements ConfigurationMBean {
* <b>{@code @Description}</b>("A Configuration MBean with the default file name")
* public Configuration() {
* this(DEFAULT_FILE_NAME);
* }
*
* <b>{@code @Description}</b>("A Configuration MBean with a specified file name")
* public Configuration(
* <b>{@code @Description}</b>("Name of the file the configuration is stored in")
* String fileName) {...}
* ...
* }
* </pre>
*
* <p>The {@code @Description} annotation also works in MBeans that
* are defined using the {@code @MBean} or {@code @MXBean} annotation
* on classes. Here is an alternative implementation of {@code
* Configuration} that does not use an {@code ConfigurationMBean}
* interface.</p>
*
* <pre>
* <b>{@code @MBean}</b>
* <b>{@code @Description}</b>("Application configuration")
* public class Configuration {
* <b>{@code @Description}</b>("A Configuration MBean with the default file name")
* public Configuration() {
* this(DEFAULT_FILE_NAME);
* }
*
* <b>{@code @Description}</b>("A Configuration MBean with a specified file name")
* public Configuration(
* <b>{@code @Description}</b>("Name of the file the configuration is stored in")
* String fileName) {...}
*
* <b>{@code @ManagedAttribute}</b>
* <b>{@code @Description}</b>("Cache size in bytes")
* public int getCacheSize() {...}
* <b>{@code @ManagedAttribute}</b>
* public void setCacheSize(int size) {...}
*
* <b>{@code @ManagedOperation}</b>
* <b>{@code @Description}</b>("Last time the configuration was changed, " +
* "in milliseconds since 1 Jan 1970")
* public long getLastChangedTime() {...}
*
* <b>{@code @ManagedOperation}</b>
* <b>{@code @Description}</b>("Save the configuration to a file")
* public void save(
* <b>{@code @Description}</b>("Optional name of the file, or null for the default name")
* String fileName) {...}
* ...
* }
* </pre>
*/
@Documented
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
({
ElementType
.
CONSTRUCTOR
,
ElementType
.
METHOD
,
ElementType
.
PARAMETER
,
ElementType
.
TYPE
})
public
@interface
Description
{
/**
* <p>The description.</p>
*/
String
value
();
/**
* <p>The base name for the {@link ResourceBundle} in which the key given in
* the {@code descriptionResourceKey} field can be found, for example
* {@code "com.example.myapp.MBeanResources"}. If a non-default value
* is supplied for this element, it will appear in the
* <a href="Descriptor.html#descriptionResourceBundleBaseName"><!--
* -->{@code Descriptor}</a> for the annotated item.</p>
*/
@DescriptorKey
(
value
=
"descriptionResourceBundleBaseName"
,
omitIfDefault
=
true
)
String
bundleBaseName
()
default
""
;
/**
* <p>A resource key for the description of this element. In
* conjunction with the {@link #bundleBaseName bundleBaseName},
* this can be used to find a localized version of the description.
* If a non-default value
* is supplied for this element, it will appear in the
* <a href="Descriptor.html#descriptionResourceKey"><!--
* -->{@code Descriptor}</a> for the annotated item.</p>
*/
@DescriptorKey
(
value
=
"descriptionResourceKey"
,
omitIfDefault
=
true
)
String
key
()
default
""
;
}
src/share/classes/javax/management/Descriptor.java
浏览文件 @
0a690d3a
...
...
@@ -38,6 +38,7 @@ import java.util.Arrays;
import
java.util.ResourceBundle
;
import
javax.management.openmbean.CompositeData
;
import
javax.management.openmbean.MXBeanMappingFactory
;
import
javax.management.openmbean.OpenMBeanAttributeInfoSupport
;
import
javax.management.openmbean.OpenMBeanOperationInfoSupport
;
import
javax.management.openmbean.OpenMBeanParameterInfoSupport
;
...
...
@@ -117,21 +118,19 @@ import javax.management.openmbean.OpenType;
* deprecation, for example {@code "1.3 Replaced by the Capacity
* attribute"}.</td>
*
* <tr><td>descriptionResource<br>BundleBaseName</td><td>String</td><td>Any</td>
* <tr id="descriptionResourceBundleBaseName">
* <td>descriptionResource<br>BundleBaseName</td><td>String</td><td>Any</td>
*
* <td>The base name for the {@link ResourceBundle} in which the key given in
* the {@code descriptionResourceKey} field can be found, for example
* {@code "com.example.myapp.MBeanResources"}. The meaning of this
* field is defined by this specification but the field is not set or
* used by the JMX API itself.</td>
* {@code "com.example.myapp.MBeanResources"}.</td>
*
* <tr><td>descriptionResourceKey</td><td>String</td><td>Any</td>
* <tr id="descriptionResourceKey">
* <td>descriptionResourceKey</td><td>String</td><td>Any</td>
*
* <td>A resource key for the description of this element. In
* conjunction with the {@code descriptionResourceBundleBaseName},
* this can be used to find a localized version of the description.
* The meaning of this field is defined by this specification but the
* field is not set or used by the JMX API itself.</td>
* this can be used to find a localized version of the description.</td>
*
* <tr><td>enabled</td><td>String</td>
* <td>MBeanAttributeInfo<br>MBeanNotificationInfo<br>MBeanOperationInfo</td>
...
...
@@ -216,6 +215,14 @@ import javax.management.openmbean.OpenType;
* StandardMBean} class will have this field in its MBeanInfo
* Descriptor.</td>
*
* <tr><td id="mxbeanMappingFactoryClass"><i>mxbeanMappingFactoryClass</i>
* </td><td>String</td>
* <td>MBeanInfo</td>
*
* <td>The name of the {@link MXBeanMappingFactory} class that was used for this
* MXBean, if it was not the {@linkplain MXBeanMappingFactory#DEFAULT default}
* one.</td>
*
* <tr><td><a name="openType"><i>openType</i></a><td>{@link OpenType}</td>
* <td>MBeanAttributeInfo<br>MBeanOperationInfo<br>MBeanParameterInfo</td>
*
...
...
src/share/classes/javax/management/DescriptorFields.java
0 → 100644
浏览文件 @
0a690d3a
/*
* Copyright 2007 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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.
*/
package
javax.management
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Inherited
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* <p>Annotation that adds fields to a {@link Descriptor}. This can be the
* Descriptor for an MBean, or for an attribute, operation, or constructor
* in an MBean, or for a parameter of an operation or constructor.</p>
*
* <p>Consider this Standard MBean interface, for example:</p>
*
* <pre>
* public interface CacheControlMBean {
* <b>@DescriptorFields("units=bytes")</b>
* public long getCacheSize();
* }
* </pre>
*
* <p>When a Standard MBean is made using this interface, the usual rules
* mean that it will have an attribute called {@code CacheSize} of type
* {@code long}. The {@code DescriptorFields} annotation will ensure
* that the {@link MBeanAttributeInfo} for this attribute will have a
* {@code Descriptor} that has a field called {@code units} with
* corresponding value {@code bytes}.</p>
*
* <p>Similarly, if the interface looks like this:</p>
*
* <pre>
* public interface CacheControlMBean {
* <b>@DescriptorFields({"units=bytes", "since=1.5"})</b>
* public long getCacheSize();
* }
* </pre>
*
* <p>then the resulting {@code Descriptor} will contain the following
* fields:</p>
*
* <table border="2">
* <tr><th>Name</th><th>Value</th></tr>
* <tr><td>units</td><td>"bytes"</td></tr>
* <tr><td>since</td><td>"1.5"</td></tr>
* </table>
*
* <p>The {@code @DescriptorFields} annotation can be applied to:</p>
*
* <ul>
* <li>a Standard MBean or MXBean interface;
* <li>a method in such an interface;
* <li>a parameter of a method in a Standard MBean or MXBean interface
* when that method is an operation (not a getter or setter for an attribute);
* <li>a public constructor in the class that implements a Standard MBean
* or MXBean;
* <li>a parameter in such a constructor.
* </ul>
*
* <p>Other uses of the annotation will either fail to compile or be
* ignored.</p>
*
* <p>Interface annotations are checked only on the exact interface
* that defines the management interface of a Standard MBean or an
* MXBean, not on its parent interfaces. Method annotations are
* checked only in the most specific interface in which the method
* appears; in other words, if a child interface overrides a method
* from a parent interface, only {@code @DescriptorFields} annotations in
* the method in the child interface are considered.
*
* <p>The Descriptor fields contributed in this way must be consistent
* with each other and with any fields contributed by {@link
* DescriptorKey @DescriptorKey} annotations. That is, two
* different annotations, or two members of the same annotation, must
* not define a different value for the same Descriptor field. Fields
* from annotations on a getter method must also be consistent with
* fields from annotations on the corresponding setter method.</p>
*
* <p>The Descriptor resulting from these annotations will be merged
* with any Descriptor fields provided by the implementation, such as
* the <a href="Descriptor.html#immutableInfo">{@code
* immutableInfo}</a> field for an MBean. The fields from the annotations
* must be consistent with these fields provided by the implementation.</p>
*
* <h4>{@literal @DescriptorFields and @DescriptorKey}</h4>
*
* <p>The {@link DescriptorKey @DescriptorKey} annotation provides
* another way to use annotations to define Descriptor fields.
* <code>@DescriptorKey</code> requires more work but is also more
* robust, because there is less risk of mistakes such as misspelling
* the name of the field or giving an invalid value.
* <code>@DescriptorFields</code> is more convenient but includes
* those risks. <code>@DescriptorFields</code> is more
* appropriate for occasional use, but for a Descriptor field that you
* add in many places, you should consider a purpose-built annotation
* using <code>@DescriptorKey</code>.
*
* @since 1.7
*/
@Documented
@Inherited
// for @MBean and @MXBean classes
@Target
({
ElementType
.
CONSTRUCTOR
,
ElementType
.
METHOD
,
ElementType
.
PARAMETER
,
ElementType
.
TYPE
})
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
DescriptorFields
{
/**
* <p>The descriptor fields. Each element of the string looks like
* {@code "name=value"}.</p>
*/
public
String
[]
value
();
}
src/share/classes/javax/management/DescriptorKey.java
浏览文件 @
0a690d3a
...
...
@@ -33,6 +33,11 @@ import java.lang.annotation.*;
* an MBean, or for an attribute, operation, or constructor in an
* MBean, or for a parameter of an operation or constructor.</p>
*
* <p>(The {@link DescriptorFields @DescriptorFields} annotation
* provides another way to add fields to a {@code Descriptor}. See
* the documentation for that annotation for a comparison of the
* two possibilities.)</p>
*
* <p>Consider this annotation for example:</p>
*
* <pre>
...
...
@@ -57,7 +62,7 @@ import java.lang.annotation.*;
* <p>When a Standard MBean is made from the {@code CacheControlMBean},
* the usual rules mean that it will have an attribute called
* {@code CacheSize} of type {@code long}. The {@code @Units}
* a
ttribute
, given the above definition, will ensure that the
* a
nnotation
, given the above definition, will ensure that the
* {@link MBeanAttributeInfo} for this attribute will have a
* {@code Descriptor} that has a field called {@code units} with
* corresponding value {@code bytes}.</p>
...
...
@@ -125,12 +130,13 @@ import java.lang.annotation.*;
* the method in the child interface are considered.
*
* <p>The Descriptor fields contributed in this way by different
* annotations on the same program element must be consistent. That
* is, two different annotations, or two members of the same
* annotation, must not define a different value for the same
* Descriptor field. Fields from annotations on a getter method must
* also be consistent with fields from annotations on the
* corresponding setter method.</p>
* annotations on the same program element must be consistent with
* each other and with any fields contributed by a {@link
* DescriptorFields @DescriptorFields} annotation. That is, two
* different annotations, or two members of the same annotation, must
* not define a different value for the same Descriptor field. Fields
* from annotations on a getter method must also be consistent with
* fields from annotations on the corresponding setter method.</p>
*
* <p>The Descriptor resulting from these annotations will be merged
* with any Descriptor fields provided by the implementation, such as
...
...
@@ -169,4 +175,36 @@ import java.lang.annotation.*;
@Target
(
ElementType
.
METHOD
)
public
@interface
DescriptorKey
{
String
value
();
/**
* <p>Do not include this field in the Descriptor if the annotation
* element has its default value. For example, suppose {@code @Units} is
* defined like this:</p>
*
* <pre>
* @Documented
* @Target(ElementType.METHOD)
* @Retention(RetentionPolicy.RUNTIME)
* public @interface Units {
* @DescriptorKey("units")
* String value();
*
* <b>@DescriptorKey(value = "descriptionResourceKey",
* omitIfDefault = true)</b>
* String resourceKey() default "";
*
* <b>@DescriptorKey(value = "descriptionResourceBundleBaseName",
* omitIfDefault = true)</b>
* String resourceBundleBaseName() default "";
* }
* </pre>
*
* <p>Then consider a usage such as {@code @Units("bytes")} or
* {@code @Units(value = "bytes", resourceKey = "")}, where the
* {@code resourceKey} and {@code resourceBundleBaseNames} elements
* have their default values. In this case the Descriptor resulting
* from these annotations will not include a {@code descriptionResourceKey}
* or {@code descriptionResourceBundleBaseName} field.</p>
*/
boolean
omitIfDefault
()
default
false
;
}
src/share/classes/javax/management/DynamicWrapperMBean.java
0 → 100644
浏览文件 @
0a690d3a
/*
* Copyright 2005 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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.
*/
package
javax.management
;
/**
* <p>An MBean can implement this interface to affect how the MBeanServer's
* {@link MBeanServer#getClassLoaderFor getClassLoaderFor} and
* {@link MBeanServer#isInstanceOf isInstanceOf} methods behave.
* If these methods should refer to a wrapped object rather than the
* MBean object itself, then the {@link #getWrappedObject} method should
* return that wrapped object.</p>
*
* @see MBeanServer#getClassLoaderFor
* @see MBeanServer#isInstanceOf
*/
public
interface
DynamicWrapperMBean
extends
DynamicMBean
{
/**
* <p>The resource corresponding to this MBean. This is the object whose
* class name should be reflected by the MBean's
* {@link MBeanServer#getMBeanInfo getMBeanInfo()}.<!--
* -->{@link MBeanInfo#getClassName getClassName()} for example. For a "plain"
* DynamicMBean it will be "this". For an MBean that wraps another
* object, in the manner of {@link javax.management.StandardMBean}, it will be the
* wrapped object.</p>
*
* @return The resource corresponding to this MBean.
*/
public
Object
getWrappedObject
();
/**
* <p>The {@code ClassLoader} for this MBean, which can be used to
* retrieve resources associated with the MBean for example. Usually,
* it will be
* {@link #getWrappedObject()}.{@code getClass().getClassLoader()}.
*
* @return The {@code ClassLoader} for this MBean.
*/
public
ClassLoader
getWrappedClassLoader
();
}
src/share/classes/javax/management/Impact.java
0 → 100644
浏览文件 @
0a690d3a
/*
* Copyright 2007 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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.
*/
package
javax.management
;
/**
* <p>Defines the impact of an MBean operation, in particular whether it
* has an effect on the MBean or simply returns information. This enum
* is used in the {@link ManagedOperation @ManagedOperation} annotation.
* Its {@link #getCode()} method can be used to get an {@code int} suitable
* for use as the {@code impact} parameter in an {@link MBeanOperationInfo}
* constructor.</p>
*/
public
enum
Impact
{
/**
* The operation is read-like: it returns information but does not change
* any state.
* @see MBeanOperationInfo#INFO
*/
INFO
(
MBeanOperationInfo
.
INFO
),
/**
* The operation is write-like: it has an effect but does not return
* any information from the MBean.
* @see MBeanOperationInfo#ACTION
*/
ACTION
(
MBeanOperationInfo
.
ACTION
),
/**
* The operation is both read-like and write-like: it has an effect,
* and it also returns information from the MBean.
* @see MBeanOperationInfo#ACTION_INFO
*/
ACTION_INFO
(
MBeanOperationInfo
.
ACTION_INFO
),
/**
* The impact of the operation is unknown or cannot be expressed
* using one of the other values.
* @see MBeanOperationInfo#UNKNOWN
*/
UNKNOWN
(
MBeanOperationInfo
.
UNKNOWN
);
private
final
int
code
;
/**
* An instance of this enumeration, with the corresponding {@code int}
* code used by the {@link MBeanOperationInfo} constructors.
*
* @param code the code used by the {@code MBeanOperationInfo} constructors.
*/
Impact
(
int
code
)
{
this
.
code
=
code
;
}
/**
* The equivalent {@code int} code used by the {@link MBeanOperationInfo}
* constructors.
* @return the {@code int} code.
*/
public
int
getCode
()
{
return
code
;
}
/**
* Return the {@code Impact} value corresponding to the given {@code int}
* code. The {@code code} is the value that would be used in an
* {@code MBeanOperationInfo} constructor.
*
* @param code the {@code int} code.
*
* @return an {@code Impact} value {@code x} such that
* {@code code == x.}{@link #getCode()}, or {@code Impact.UNKNOWN}
* if there is no such value.
*/
public
static
Impact
forCode
(
int
code
)
{
switch
(
code
)
{
case
MBeanOperationInfo
.
ACTION
:
return
ACTION
;
case
MBeanOperationInfo
.
INFO
:
return
INFO
;
case
MBeanOperationInfo
.
ACTION_INFO
:
return
ACTION_INFO
;
default
:
return
UNKNOWN
;
}
}
}
src/share/classes/javax/management/JMX.java
浏览文件 @
0a690d3a
...
...
@@ -26,6 +26,7 @@
package
javax.management
;
import
com.sun.jmx.mbeanserver.Introspector
;
import
com.sun.jmx.mbeanserver.MBeanInjector
;
import
com.sun.jmx.remote.util.ClassLogger
;
import
java.beans.BeanInfo
;
import
java.beans.PropertyDescriptor
;
...
...
@@ -130,6 +131,7 @@ public class JMX {
* </pre>
*
* @see javax.management.JMX.ProxyOptions
* @see javax.management.StandardMBean.Options
*/
public
static
class
MBeanOptions
implements
Serializable
,
Cloneable
{
private
static
final
long
serialVersionUID
=
-
6380842449318177843L
;
...
...
@@ -739,4 +741,28 @@ public class JMX {
// exactly the string "MXBean" since that would mean there
// was no package name, which is pretty unlikely in practice.
}
/**
* <p>Test if an MBean can emit notifications. An MBean can emit
* notifications if either it implements {@link NotificationBroadcaster}
* (perhaps through its child interface {@link NotificationEmitter}), or
* it uses <a href="MBeanRegistration.html#injection">resource
* injection</a> to obtain an instance of {@link SendNotification}
* through which it can send notifications.</p>
*
* @param mbean an MBean object.
* @return true if the given object is a valid MBean that can emit
* notifications; false if the object is a valid MBean but that
* cannot emit notifications.
* @throws NotCompliantMBeanException if the given object is not
* a valid MBean.
*/
public
static
boolean
isNotificationSource
(
Object
mbean
)
throws
NotCompliantMBeanException
{
if
(
mbean
instanceof
NotificationBroadcaster
)
return
true
;
Object
resource
=
(
mbean
instanceof
DynamicWrapperMBean
)
?
((
DynamicWrapperMBean
)
mbean
).
getWrappedObject
()
:
mbean
;
return
(
MBeanInjector
.
injectsSendNotification
(
resource
));
}
}
src/share/classes/javax/management/MBean.java
0 → 100644
浏览文件 @
0a690d3a
/*
* Copyright 2007 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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.
*/
package
javax.management
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Inherited
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* <p>Indicates that the annotated class is a Standard MBean. A Standard
* MBean class can be defined as in this example:</p>
*
* <pre>
* {@code @MBean}
* public class Configuration {
* {@link ManagedAttribute @ManagedAttribute}
* public int getCacheSize() {...}
* {@code @ManagedAttribute}
* public void setCacheSize(int size);
*
* {@code @ManagedAttribute}
* public long getLastChangedTime();
*
* {@link ManagedOperation @ManagedOperation}
* public void save();
* }
* </pre>
*
* <p>The class must be public. Public methods within the class can be
* annotated with {@code @ManagedOperation} to indicate that they are
* MBean operations. Public getter and setter methods within the class
* can be annotated with {@code @ManagedAttribute} to indicate that they define
* MBean attributes.</p>
*
* <p>If the MBean is to be an MXBean rather than a Standard MBean, then
* the {@link MXBean @MXBean} annotation must be used instead of
* {@code @MBean}.</p>
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
TYPE
)
@Inherited
public
@interface
MBean
{
}
src/share/classes/javax/management/MBeanOperationInfo.java
浏览文件 @
0a690d3a
...
...
@@ -46,25 +46,30 @@ public class MBeanOperationInfo extends MBeanFeatureInfo implements Cloneable {
new
MBeanOperationInfo
[
0
];
/**
* Indicates that the operation is read-like,
* it basically returns information.
* Indicates that the operation is read-like:
* it returns information but does not change any state.
* @see Impact#INFO
*/
public
static
final
int
INFO
=
0
;
/**
* Indicates that the operation is
a write-like,
*
and would modify the MBean in some way, typically by writing some value
*
or changing a configuration.
* Indicates that the operation is
write-like: it has an effect but does
*
not return any information from the MBean.
*
@see Impact#ACTION
*/
public
static
final
int
ACTION
=
1
;
/**
* Indicates that the operation is both read-like and write-like.
* Indicates that the operation is both read-like and write-like:
* it has an effect, and it also returns information from the MBean.
* @see Impact#ACTION_INFO
*/
public
static
final
int
ACTION_INFO
=
2
;
/**
* Indicates that the operation has an "unknown" nature.
* Indicates that the impact of the operation is unknown or cannot be
* expressed using one of the other values.
* @see Impact#UNKNOWN
*/
public
static
final
int
UNKNOWN
=
3
;
...
...
@@ -120,8 +125,9 @@ public class MBeanOperationInfo extends MBeanFeatureInfo implements Cloneable {
* describing the parameters(arguments) of the method. This may be
* null with the same effect as a zero-length array.
* @param type The type of the method's return value.
* @param impact The impact of the method, one of <CODE>INFO,
* ACTION, ACTION_INFO, UNKNOWN</CODE>.
* @param impact The impact of the method, one of
* {@link #INFO}, {@link #ACTION}, {@link #ACTION_INFO},
* {@link #UNKNOWN}.
*/
public
MBeanOperationInfo
(
String
name
,
String
description
,
...
...
@@ -140,8 +146,9 @@ public class MBeanOperationInfo extends MBeanFeatureInfo implements Cloneable {
* describing the parameters(arguments) of the method. This may be
* null with the same effect as a zero-length array.
* @param type The type of the method's return value.
* @param impact The impact of the method, one of <CODE>INFO,
* ACTION, ACTION_INFO, UNKNOWN</CODE>.
* @param impact The impact of the method, one of
* {@link #INFO}, {@link #ACTION}, {@link #ACTION_INFO},
* {@link #UNKNOWN}.
* @param descriptor The descriptor for the operation. This may be null
* which is equivalent to an empty descriptor.
*
...
...
@@ -319,9 +326,14 @@ public class MBeanOperationInfo extends MBeanFeatureInfo implements Cloneable {
for
(
int
i
=
0
;
i
<
classes
.
length
;
i
++)
{
Descriptor
d
=
Introspector
.
descriptorForAnnotations
(
annots
[
i
]);
final
String
pn
=
"p"
+
(
i
+
1
);
params
[
i
]
=
new
MBeanParameterInfo
(
pn
,
classes
[
i
].
getName
(),
""
,
d
);
String
description
=
Introspector
.
descriptionForParameter
(
annots
[
i
]);
if
(
description
==
null
)
description
=
""
;
String
name
=
Introspector
.
nameForParameter
(
annots
[
i
]);
if
(
name
==
null
)
name
=
"p"
+
(
i
+
1
);
params
[
i
]
=
new
MBeanParameterInfo
(
name
,
classes
[
i
].
getName
(),
description
,
d
);
}
return
params
;
...
...
src/share/classes/javax/management/MBeanRegistration.java
浏览文件 @
0a690d3a
...
...
@@ -27,9 +27,101 @@ package javax.management;
/**
* Can be implemented by an MBean in order to
*
<p>
Can be implemented by an MBean in order to
* carry out operations before and after being registered or unregistered from
* the MBean server.
* the MBean Server. An MBean can also implement this interface in order
* to get a reference to the MBean Server and/or its name within that
* MBean Server.</p>
*
* <h4 id="injection">Resource injection</h4>
*
* <p>As an alternative to implementing {@code MBeanRegistration}, if all that
* is needed is the MBean Server or ObjectName then an MBean can use
* <em>resource injection</em>.</p>
*
* <p>If a field in the MBean object has type {@link ObjectName} and has
* the {@link javax.annotation.Resource @Resource} annotation,
* then the {@code ObjectName} under which the MBean is registered is
* assigned to that field during registration. Likewise, if a field has type
* {@link MBeanServer} and the <code>@Resource</code> annotation, then it will
* be set to the {@code MBeanServer} in which the MBean is registered.</p>
*
* <p>For example:</p>
*
* <pre>
* public Configuration implements ConfigurationMBean {
* @Resource
* private volatile MBeanServer mbeanServer;
* @Resource
* private volatile ObjectName objectName;
* ...
* void unregisterSelf() throws Exception {
* mbeanServer.unregisterMBean(objectName);
* }
* }
* </pre>
*
* <p>Resource injection can also be used on fields of type
* {@link SendNotification} to simplify notification sending. Such a field
* will get a reference to an object of type {@code SendNotification} when
* the MBean is registered, and it can use this reference to send notifications.
* For example:</p>
*
* <pre>
* public Configuration implements ConfigurationMBean {
* @Resource
* private volatile SendNotification sender;
* ...
* private void updated() {
* Notification n = new Notification(...);
* sender.sendNotification(n);
* }
* }
* </pre>
*
* <p>A field to be injected must not be static. It is recommended that
* such fields be declared {@code volatile}.</p>
*
* <p>It is also possible to use the <code>@Resource</code> annotation on
* methods. Such a method must have a {@code void} return type and a single
* argument of the appropriate type, for example {@code ObjectName}.</p>
*
* <p>Any number of fields and methods may have the <code>@Resource</code>
* annotation. All fields and methods with type {@code ObjectName}
* (for example) will receive the same {@code ObjectName} value.</p>
*
* <p>Resource injection is available for all types of MBeans, not just
* Standard MBeans.</p>
*
* <p>If an MBean implements the {@link DynamicWrapperMBean} interface then
* resource injection happens on the object returned by that interface's
* {@link DynamicWrapperMBean#getWrappedObject() getWrappedObject()} method
* rather than on the MBean object itself.
*
* <p>Resource injection happens after the {@link #preRegister preRegister}
* method is called (if any), and before the MBean is actually registered
* in the MBean Server. If a <code>@Resource</code> method throws
* an exception, the effect is the same as if {@code preRegister} had
* thrown the exception. In particular it will prevent the MBean from being
* registered.</p>
*
* <p>Resource injection can be used on a field or method where the type
* is a parent of the injected type, if the injected type is explicitly
* specified in the <code>@Resource</code> annotation. For example:</p>
*
* <pre>
* @Resource(type = MBeanServer.class)
* private volatile MBeanServerConnection mbsc;
* </pre>
*
* <p>Formally, suppose <em>R</em> is the type in the <code>@Resource</code>
* annotation and <em>T</em> is the type of the method parameter or field.
* Then one of <em>R</em> and <em>T</em> must be a subtype of the other
* (or they must be the same type). Injection happens if this subtype
* is {@code MBeanServer}, {@code ObjectName}, or {@code SendNotification}.
* Otherwise the <code>@Resource</code> annotation is ignored.</p>
*
* <p>Resource injection in MBeans is new in version 2.0 of the JMX API.</p>
*
* @since 1.5
*/
...
...
@@ -38,12 +130,12 @@ public interface MBeanRegistration {
/**
* Allows the MBean to perform any operations it needs before
* being registered in the MBean
s
erver. If the name of the MBean
* being registered in the MBean
S
erver. If the name of the MBean
* is not specified, the MBean can provide a name for its
* registration. If any exception is raised, the MBean will not be
* registered in the MBean
s
erver.
* registered in the MBean
S
erver.
*
* @param server The MBean
s
erver in which the MBean will be registered.
* @param server The MBean
S
erver in which the MBean will be registered.
*
* @param name The object name of the MBean. This name is null if
* the name parameter to one of the <code>createMBean</code> or
...
...
@@ -57,7 +149,7 @@ public interface MBeanRegistration {
* the returned value.
*
* @exception java.lang.Exception This exception will be caught by
* the MBean
s
erver and re-thrown as an {@link
* the MBean
S
erver and re-thrown as an {@link
* MBeanRegistrationException}.
*/
public
ObjectName
preRegister
(
MBeanServer
server
,
...
...
src/share/classes/javax/management/MBeanServer.java
浏览文件 @
0a690d3a
...
...
@@ -61,7 +61,7 @@ import javax.management.loading.ClassLoaderRepository;
* <CODE>ObjectName</CODE> is: <BR>
* <CODE>JMImplementation:type=MBeanServerDelegate</CODE>.</p>
*
* <p>An object obtained from the {@link
* <p
id="security"
>An object obtained from the {@link
* MBeanServerFactory#createMBeanServer(String) createMBeanServer} or
* {@link MBeanServerFactory#newMBeanServer(String) newMBeanServer}
* methods of the {@link MBeanServerFactory} class applies security
...
...
@@ -661,13 +661,16 @@ public interface MBeanServer extends MBeanServerConnection {
ReflectionException
;
/**
* <p>Return the {@link java.lang.ClassLoader} that was used for
* loading the class of the named MBean.</p>
* <p>Return the {@link java.lang.ClassLoader} that was used for loading
* the class of the named MBean. If the MBean implements the {@link
* DynamicWrapperMBean} interface, then the returned value is the
* result of the {@link DynamicWrapperMBean#getWrappedClassLoader()}
* method.</p>
*
* @param mbeanName The ObjectName of the MBean.
*
* @return The ClassLoader used for that MBean. If <var>l</var>
* is the
MBean's actual ClassLoader
, and <var>r</var> is the
* is the
value specified by the rules above
, and <var>r</var> is the
* returned value, then either:
*
* <ul>
...
...
src/share/classes/javax/management/MBeanServerConnection.java
浏览文件 @
0a690d3a
...
...
@@ -839,6 +839,12 @@ public interface MBeanServerConnection {
*
* <p>Otherwise, the result is false.</p>
*
* <p>If the MBean implements the {@link DynamicWrapperMBean}
* interface, then in the above rules X is the result of the MBean's {@link
* DynamicWrapperMBean#getWrappedObject() getWrappedObject()} method and L
* is the result of its {@link DynamicWrapperMBean#getWrappedClassLoader()
* getWrappedClassLoader()} method.
*
* @param name The <CODE>ObjectName</CODE> of the MBean.
* @param className The name of the class.
*
...
...
src/share/classes/javax/management/MXBean.java
浏览文件 @
0a690d3a
...
...
@@ -27,6 +27,7 @@ package javax.management;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Inherited
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
...
...
@@ -57,11 +58,13 @@ import javax.management.openmbean.TabularDataSupport;
import
javax.management.openmbean.TabularType
;
/**
<p>Annotation to mark a
n interface explicitly as being an MXBean
interface, or as not being an MXBean interface
. By default, an
<p>Annotation to mark a
class or interface explicitly as being an MXBean,
or as not being an MXBean
. By default, an
interface is an MXBean interface if its name ends with {@code
MXBean}, as in {@code SomethingMXBean}. The following interfaces
are MXBean interfaces:</p>
MXBean}, as in {@code SomethingMXBean}. A class is never an MXBean by
default.</p>
<p>The following interfaces are MXBean interfaces:</p>
<pre>
public interface WhatsitMXBean {}
...
...
@@ -82,6 +85,11 @@ import javax.management.openmbean.TabularType;
public interface MisleadingMXBean {}
</pre>
<p>A class can be annotated with {@code @MXBean} to indicate that it
is an MXBean. In this case, its methods should have <code>@{@link
ManagedAttribute}</code> or <code>@{@link ManagedOperation}</code>
annotations, as described for <code>@{@link MBean}</code>.</p>
<h3 id="MXBean-spec">MXBean specification</h3>
<p>The MXBean concept provides a simple way to code an MBean
...
...
@@ -1246,9 +1254,24 @@ public interface Node {
@since 1.6
*/
/*
* This annotation is @Inherited because if an MXBean is defined as a
* class using annotations, then its subclasses are also MXBeans.
* For example:
* @MXBean
* public class Super {
* @ManagedAttribute
* public String getName() {...}
* }
* public class Sub extends Super {}
* Here Sub is an MXBean.
*
* The @Inherited annotation has no effect when applied to an interface.
*/
@Documented
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
TYPE
)
@Inherited
public
@interface
MXBean
{
/**
True if the annotated interface is an MXBean interface.
...
...
src/share/classes/javax/management/ManagedAttribute.java
0 → 100644
浏览文件 @
0a690d3a
/*
* Copyright 2007 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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.
*/
package
javax.management
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* <p>Indicates that a method in an MBean class defines an MBean attribute.
* This annotation must be applied to a public method of a public class
* that is itself annotated with an {@link MBean @MBean} or
* {@link MXBean @MXBean} annotation, or inherits such an annotation from
* a superclass.</p>
*
* <p>The annotated method must be a getter or setter. In other words,
* it must look like one of the following...</p>
*
* <pre>
* <i>T</i> get<i>Foo</i>()
* void set<i>Foo</i>(<i>T</i> param)
* </pre>
*
* <p>...where <i>{@code T}</i> is any type and <i>{@code Foo}</i> is the
* name of the attribute. For any attribute <i>{@code Foo}</i>, if only
* a {@code get}<i>{@code Foo}</i> method has a {@code ManagedAttribute}
* annotation, then <i>{@code Foo}</i> is a read-only attribute. If only
* a {@code set}<i>{@code Foo}</i> method has a {@code ManagedAttribute}
* annotation, then <i>{@code Foo}</i> is a write-only attribute. If
* both {@code get}<i>{@code Foo}</i> and {@code set}<i>{@code Foo}</i>
* methods have the annotation, then <i>{@code Foo}</i> is a read-write
* attribute. In this last case, the type <i>{@code T}</i> must be the
* same in both methods.</p>
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
METHOD
)
@Documented
public
@interface
ManagedAttribute
{
}
src/share/classes/javax/management/ManagedOperation.java
0 → 100644
浏览文件 @
0a690d3a
/*
* Copyright 2007 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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.
*/
package
javax.management
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* <p>Indicates that a method in an MBean class defines an MBean operation.
* This annotation can be applied to:</p>
*
* <ul>
* <li>A public method of a public class
* that is itself annotated with an {@link MBean @MBean} or
* {@link MXBean @MXBean} annotation, or inherits such an annotation from
* a superclass.</li>
* <li>A method of an MBean or MXBean interface.
* </ul>
*
* <p>Every method in an MBean or MXBean interface defines an MBean
* operation even without this annotation, but the annotation allows
* you to specify the impact of the operation:</p>
*
* <pre>
* public interface ConfigurationMBean {
* {@code @ManagedOperation}(impact = {@link Impact#ACTION Impact.ACTION})
* public void save();
* ...
* }
* </pre>
*/
@Retention
(
RetentionPolicy
.
RUNTIME
)
@Target
(
ElementType
.
METHOD
)
@Documented
public
@interface
ManagedOperation
{
/**
* <p>The impact of this operation, as shown by
* {@link MBeanOperationInfo#getImpact()}.
*/
Impact
impact
()
default
Impact
.
UNKNOWN
;
}
src/share/classes/javax/management/NotQueryExp.java
浏览文件 @
0a690d3a
...
...
@@ -91,6 +91,7 @@ class NotQueryExp extends QueryEval implements QueryExp {
return
"not ("
+
exp
+
")"
;
}
@Override
String
toQueryString
()
{
return
"not ("
+
Query
.
toString
(
exp
)
+
")"
;
}
...
...
src/share/classes/javax/management/NotificationBroadcasterSupport.java
浏览文件 @
0a690d3a
...
...
@@ -58,7 +58,8 @@ import com.sun.jmx.remote.util.ClassLogger;
*
* @since 1.5
*/
public
class
NotificationBroadcasterSupport
implements
NotificationEmitter
{
public
class
NotificationBroadcasterSupport
implements
NotificationEmitter
,
SendNotification
{
/**
* Constructs a NotificationBroadcasterSupport where each listener is invoked by the
* thread sending the notification. This constructor is equivalent to
...
...
src/share/classes/javax/management/NotificationInfo.java
0 → 100644
浏览文件 @
0a690d3a
/*
* Copyright 2007 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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.
*/
package
javax.management
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Inherited
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
/**
* <p>Specifies the kinds of notification an MBean can emit. In both the
* following examples, the MBean emits notifications of type
* {@code "com.example.notifs.create"} and of type
* {@code "com.example.notifs.destroy"}:</p>
*
* <pre>
* // Example one: a Standard MBean
* {@code @NotificationInfo}(types={"com.example.notifs.create",
* "com.example.notifs.destroy"})
* public interface CacheMBean {...}
*
* public class Cache implements CacheMBean {...}
* </pre>
*
* <pre>
* // Example two: an annotated MBean
* {@link MBean @MBean}
* {@code @NotificationInfo}(types={"com.example.notifs.create",
* "com.example.notifs.destroy"})
* public class Cache {...}
* </pre>
*
* <p>Each {@code @NotificationInfo} produces an {@link
* MBeanNotificationInfo} inside the {@link MBeanInfo} of each MBean
* to which the annotation applies.</p>
*
* <p>If you need to specify different notification classes, or different
* descriptions for different notification types, then you can group
* several {@code @NotificationInfo} annotations into a containing
* {@link NotificationInfos @NotificationInfos} annotation.
*
* <p>The {@code NotificationInfo} and {@code NotificationInfos}
* annotations can be applied to the MBean implementation class, or to
* any parent class or interface. These annotations on a class take
* precedence over annotations on any superclass or superinterface.
* If an MBean does not have these annotations on its class or any
* superclass, then superinterfaces are examined. It is an error for
* more than one superinterface to have these annotations, unless one
* of them is a child of all the others.</p>
*/
@Documented
@Inherited
@Target
(
ElementType
.
TYPE
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
NotificationInfo
{
/**
* <p>The {@linkplain Notification#getType() notification types}
* that this MBean can emit.</p>
*/
String
[]
types
();
/**
* <p>The class that emitted notifications will have. It is recommended
* that this be {@link Notification}, or one of its standard subclasses
* in the JMX API.</p>
*/
Class
<?
extends
Notification
>
notificationClass
()
default
Notification
.
class
;
/**
* <p>The description of this notification. For example:
*
* <pre>
* {@code @NotificationInfo}(
* types={"com.example.notifs.create"},
* description={@code @Description}("object created"))
* </pre>
*/
Description
description
()
default
@Description
(
""
);
/**
* <p>Additional descriptor fields for the derived {@code
* MBeanNotificationInfo}. They are specified in the same way as
* for the {@link DescriptorFields @DescriptorFields} annotation,
* for example:</p>
* <pre>
* {@code @NotificationInfo}(
* types={"com.example.notifs.create"},
* descriptorFields={"severity=6"})
* </pre>
*/
String
[]
descriptorFields
()
default
{};
}
src/share/classes/javax/management/NotificationInfos.java
0 → 100644
浏览文件 @
0a690d3a
/*
* Copyright 2007 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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.
*/
package
javax.management
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.ElementType
;
import
java.lang.annotation.Inherited
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
import
java.lang.annotation.Target
;
import
javax.management.remote.JMXConnectionNotification
;
/**
* <p>Specifies the kinds of notification an MBean can emit, when this
* cannot be represented by a single {@link NotificationInfo
* @NotificationInfo} annotation.</p>
*
* <p>For example, this annotation specifies that an MBean can emit
* {@link AttributeChangeNotification} and {@link
* JMXConnectionNotification}:</p>
*
* <pre>
* {@code @NotificationInfos}(
* {@code @NotificationInfo}(
* types = {{@link AttributeChangeNotification#ATTRIBUTE_CHANGE}},
* notificationClass = AttributeChangeNotification.class),
* {@code @NotificationInfo}(
* types = {{@link JMXConnectionNotification#OPENED},
* {@link JMXConnectionNotification#CLOSED}},
* notificationClass = JMXConnectionNotification.class)
* )
* </pre>
*
* <p>If an MBean has both {@code NotificationInfo} and {@code
* NotificationInfos} on the same class or interface, the effect is
* the same as if the {@code NotificationInfo} were moved inside the
* {@code NotificationInfos}.</p>
*/
@Documented
@Inherited
@Target
(
ElementType
.
TYPE
)
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
NotificationInfos
{
/**
* <p>The {@link NotificationInfo} annotations.</p>
*/
NotificationInfo
[]
value
();
}
src/share/classes/javax/management/SendNotification.java
0 → 100644
浏览文件 @
0a690d3a
/*
* Copyright 2007 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. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* 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.
*/
package
javax.management
;
/**
* Interface implemented by objects that can be asked to send a notification.
*/
public
interface
SendNotification
{
/**
* Sends a notification.
*
* @param notification The notification to send.
*/
public
void
sendNotification
(
Notification
notification
);
}
src/share/classes/javax/management/StandardEmitterMBean.java
浏览文件 @
0a690d3a
...
...
@@ -25,6 +25,9 @@
package
javax.management
;
import
com.sun.jmx.mbeanserver.MBeanInjector
;
import
static
javax
.
management
.
JMX
.
MBeanOptions
;
/**
* <p>An MBean whose management interface is determined by reflection
* on a Java interface, and that emits notifications.</p>
...
...
@@ -62,7 +65,7 @@ package javax.management;
* @since 1.6
*/
public
class
StandardEmitterMBean
extends
StandardMBean
implements
NotificationEmitter
{
implements
NotificationEmitter
,
SendNotification
{
private
final
NotificationEmitter
emitter
;
private
final
MBeanNotificationInfo
[]
notificationInfo
;
...
...
@@ -76,9 +79,10 @@ public class StandardEmitterMBean extends StandardMBean
* for {@code implementation} and {@code emitter} to be the same object.</p>
*
* <p>If {@code emitter} is an instance of {@code
* NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
* SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
* then the MBean's {@link #sendNotification
* sendNotification} method will call {@code emitter.}{@link
*
NotificationBroadcasterSupport
#sendNotification sendNotification}.</p>
*
SendNotification
#sendNotification sendNotification}.</p>
*
* <p>The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
...
...
@@ -90,20 +94,18 @@ public class StandardEmitterMBean extends StandardMBean
*
* @param implementation the implementation of the MBean interface.
* @param mbeanInterface a Standard MBean interface.
* @param emitter the object that will handle notifications.
* @param emitter the object that will handle notifications. If null,
* a new {@code NotificationEmitter} will be constructed that also
* implements {@link SendNotification}.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
* if the given {@code implementation} does not implement the
* specified interface
, or if {@code emitter} is null
.
* specified interface.
*/
public
<
T
>
StandardEmitterMBean
(
T
implementation
,
Class
<
T
>
mbeanInterface
,
NotificationEmitter
emitter
)
{
super
(
implementation
,
mbeanInterface
,
false
);
if
(
emitter
==
null
)
throw
new
IllegalArgumentException
(
"Null emitter"
);
this
.
emitter
=
emitter
;
this
.
notificationInfo
=
emitter
.
getNotificationInfo
();
this
(
implementation
,
mbeanInterface
,
false
,
emitter
);
}
/**
...
...
@@ -118,9 +120,10 @@ public class StandardEmitterMBean extends StandardMBean
* same object.</p>
*
* <p>If {@code emitter} is an instance of {@code
* NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
* SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
* then the MBean's {@link #sendNotification
* sendNotification} method will call {@code emitter.}{@link
*
NotificationBroadcasterSupport
#sendNotification sendNotification}.</p>
*
SendNotification
#sendNotification sendNotification}.</p>
*
* <p>The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
...
...
@@ -134,21 +137,69 @@ public class StandardEmitterMBean extends StandardMBean
* @param mbeanInterface a Standard MBean interface.
* @param isMXBean If true, the {@code mbeanInterface} parameter
* names an MXBean interface and the resultant MBean is an MXBean.
* @param emitter the object that will handle notifications.
* @param emitter the object that will handle notifications. If null,
* a new {@code NotificationEmitter} will be constructed that also
* implements {@link SendNotification}.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
* if the given {@code implementation} does not implement the
* specified interface
, or if {@code emitter} is null
.
* specified interface.
*/
public
<
T
>
StandardEmitterMBean
(
T
implementation
,
Class
<
T
>
mbeanInterface
,
boolean
isMXBean
,
NotificationEmitter
emitter
)
{
super
(
implementation
,
mbeanInterface
,
isMXBean
);
this
(
implementation
,
mbeanInterface
,
isMXBean
?
MBeanOptions
.
MXBEAN
:
null
,
emitter
);
}
/**
* <p>Make an MBean whose management interface is specified by {@code
* mbeanInterface}, with the given implementation and options, and where
* notifications are handled by the given {@code NotificationEmitter}.
* Options select whether to make a Standard MBean or an MXBean, and
* whether the result of {@link #getWrappedObject()} is the {@code
* StandardEmitterMBean} object or the given implementation. The resultant
* MBean implements the {@code NotificationEmitter} interface by forwarding
* its methods to {@code emitter}. It is legal and useful for {@code
* implementation} and {@code emitter} to be the same object.</p>
*
* <p>If {@code emitter} is an instance of {@code
* SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
* then the MBean's {@link #sendNotification
* sendNotification} method will call {@code emitter.}{@link
* SendNotification#sendNotification sendNotification}.</p>
*
* <p>The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
* {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
* getNotificationInfo()} at the time of construction. If the array
* returned by {@code emitter.getNotificationInfo()} later changes,
* that will have no effect on this object's
* {@code getNotificationInfo()}.</p>
*
* @param implementation the implementation of the MBean interface.
* @param mbeanInterface a Standard MBean interface.
* @param options MBeanOptions that control the operation of the resulting
* MBean.
* @param emitter the object that will handle notifications. If null,
* a new {@code NotificationEmitter} will be constructed that also
* implements {@link SendNotification}.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
* if the given {@code implementation} does not implement the
* specified interface.
*/
public
<
T
>
StandardEmitterMBean
(
T
implementation
,
Class
<
T
>
mbeanInterface
,
MBeanOptions
options
,
NotificationEmitter
emitter
)
{
super
(
implementation
,
mbeanInterface
,
options
);
if
(
emitter
==
null
)
throw
new
IllegalArgumentException
(
"Null emitter"
);
emitter
=
defaultEmitter
(
);
this
.
emitter
=
emitter
;
this
.
notificationInfo
=
emitter
.
getNotificationInfo
();
injectEmitter
();
}
/**
...
...
@@ -159,9 +210,10 @@ public class StandardEmitterMBean extends StandardMBean
* by forwarding its methods to {@code emitter}.</p>
*
* <p>If {@code emitter} is an instance of {@code
* NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
* SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
* then the MBean's {@link #sendNotification
* sendNotification} method will call {@code emitter.}{@link
*
NotificationBroadcasterSupport
#sendNotification sendNotification}.</p>
*
SendNotification
#sendNotification sendNotification}.</p>
*
* <p>The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
...
...
@@ -175,20 +227,17 @@ public class StandardEmitterMBean extends StandardMBean
* the given {@code mbeanInterface}.</p>
*
* @param mbeanInterface a StandardMBean interface.
* @param emitter the object that will handle notifications.
* @param emitter the object that will handle notifications. If null,
* a new {@code NotificationEmitter} will be constructed that also
* implements {@link SendNotification}.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
* if {@code this} does not implement the specified interface, or
* if {@code emitter} is null.
* if {@code this} does not implement the specified interface.
*/
protected
StandardEmitterMBean
(
Class
<?>
mbeanInterface
,
NotificationEmitter
emitter
)
{
super
(
mbeanInterface
,
false
);
if
(
emitter
==
null
)
throw
new
IllegalArgumentException
(
"Null emitter"
);
this
.
emitter
=
emitter
;
this
.
notificationInfo
=
emitter
.
getNotificationInfo
();
this
(
mbeanInterface
,
false
,
emitter
);
}
/**
...
...
@@ -200,9 +249,10 @@ public class StandardEmitterMBean extends StandardMBean
* forwarding its methods to {@code emitter}.</p>
*
* <p>If {@code emitter} is an instance of {@code
* NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
* SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
* then the MBean's {@link #sendNotification
* sendNotification} method will call {@code emitter.}{@link
*
NotificationBroadcasterSupport
#sendNotification sendNotification}.</p>
*
SendNotification
#sendNotification sendNotification}.</p>
*
* <p>The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
...
...
@@ -218,20 +268,86 @@ public class StandardEmitterMBean extends StandardMBean
* @param mbeanInterface a StandardMBean interface.
* @param isMXBean If true, the {@code mbeanInterface} parameter
* names an MXBean interface and the resultant MBean is an MXBean.
* @param emitter the object that will handle notifications.
* @param emitter the object that will handle notifications. If null,
* a new {@code NotificationEmitter} will be constructed that also
* implements {@link SendNotification}.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
* if {@code this} does not implement the specified interface, or
* if {@code emitter} is null.
* if {@code this} does not implement the specified interface.
*/
protected
StandardEmitterMBean
(
Class
<?>
mbeanInterface
,
boolean
isMXBean
,
NotificationEmitter
emitter
)
{
super
(
mbeanInterface
,
isMXBean
);
this
(
mbeanInterface
,
isMXBean
?
MBeanOptions
.
MXBEAN
:
null
,
emitter
);
}
/**
* <p>Make an MBean whose management interface is specified by {@code
* mbeanInterface}, with the given options, and where notifications are
* handled by the given {@code NotificationEmitter}. This constructor can
* be used to make either Standard MBeans or MXBeans. The resultant MBean
* implements the {@code NotificationEmitter} interface by forwarding its
* methods to {@code emitter}.</p>
*
* <p>If {@code emitter} is an instance of {@code
* SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
* then the MBean's {@link #sendNotification
* sendNotification} method will call {@code emitter.}{@link
* SendNotification#sendNotification sendNotification}.</p>
*
* <p>The array returned by {@link #getNotificationInfo()} on the
* new MBean is a copy of the array returned by
* {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
* getNotificationInfo()} at the time of construction. If the array
* returned by {@code emitter.getNotificationInfo()} later changes,
* that will have no effect on this object's
* {@code getNotificationInfo()}.</p>
*
* <p>This constructor must be called from a subclass that implements
* the given {@code mbeanInterface}.</p>
*
* @param mbeanInterface a StandardMBean interface.
* @param options MBeanOptions that control the operation of the resulting
* MBean.
* @param emitter the object that will handle notifications. If null,
* a new {@code NotificationEmitter} will be constructed that also
* implements {@link SendNotification}.
*
* @throws IllegalArgumentException if the {@code mbeanInterface}
* does not follow JMX design patterns for Management Interfaces, or
* if {@code this} does not implement the specified interface.
*/
protected
StandardEmitterMBean
(
Class
<?>
mbeanInterface
,
MBeanOptions
options
,
NotificationEmitter
emitter
)
{
super
(
mbeanInterface
,
options
);
if
(
emitter
==
null
)
throw
new
IllegalArgumentException
(
"Null emitter"
);
emitter
=
defaultEmitter
(
);
this
.
emitter
=
emitter
;
this
.
notificationInfo
=
emitter
.
getNotificationInfo
();
injectEmitter
();
}
private
NotificationEmitter
defaultEmitter
()
{
MBeanNotificationInfo
[]
mbnis
=
getNotificationInfo
();
// Will be null unless getNotificationInfo() is overridden,
// since the notificationInfo field has not been set at this point.
if
(
mbnis
==
null
)
mbnis
=
getMBeanInfo
().
getNotifications
();
return
new
NotificationBroadcasterSupport
(
mbnis
);
}
private
void
injectEmitter
()
{
if
(
emitter
instanceof
SendNotification
)
{
try
{
Object
resource
=
getImplementation
();
SendNotification
send
=
(
SendNotification
)
emitter
;
MBeanInjector
.
injectSendNotification
(
resource
,
send
);
}
catch
(
RuntimeException
e
)
{
throw
e
;
}
catch
(
Exception
e
)
{
throw
new
IllegalArgumentException
(
e
);
}
}
}
public
void
removeNotificationListener
(
NotificationListener
listener
)
...
...
@@ -259,10 +375,10 @@ public class StandardEmitterMBean extends StandardMBean
/**
* <p>Sends a notification.</p>
*
* <p>If the {@code emitter} parameter to the constructor was
an
*
instance of {@code NotificationBroadcasterSupport} then this
*
method will call {@code emitter.}{@link
*
NotificationBroadcasterSupport
#sendNotification
* <p>If the {@code emitter} parameter to the constructor was
*
an instance of {@link SendNotification}, such as {@link
*
NotificationBroadcasterSupport}, then this method will call {@code
*
emitter.}{@link SendNotification
#sendNotification
* sendNotification}.</p>
*
* @param n the notification to send.
...
...
@@ -271,13 +387,12 @@ public class StandardEmitterMBean extends StandardMBean
* constructor was not a {@code NotificationBroadcasterSupport}.
*/
public
void
sendNotification
(
Notification
n
)
{
if
(
emitter
instanceof
NotificationBroadcasterSupport
)
((
NotificationBroadcasterSupport
)
emitter
).
sendNotification
(
n
);
if
(
emitter
instanceof
SendNotification
)
((
SendNotification
)
emitter
).
sendNotification
(
n
);
else
{
final
String
msg
=
"Cannot sendNotification when emitter is not an "
+
"instance of NotificationBroadcasterSupport: "
+
emitter
.
getClass
().
getName
();
"instance of SendNotification: "
+
emitter
.
getClass
().
getName
();
throw
new
ClassCastException
(
msg
);
}
}
...
...
@@ -292,6 +407,7 @@ public class StandardEmitterMBean extends StandardMBean
* @param info The default MBeanInfo derived by reflection.
* @return the MBeanNotificationInfo[] for the new MBeanInfo.
*/
@Override
MBeanNotificationInfo
[]
getNotifications
(
MBeanInfo
info
)
{
return
getNotificationInfo
();
}
...
...
src/share/classes/javax/management/StandardMBean.java
浏览文件 @
0a690d3a
...
...
@@ -27,6 +27,7 @@ package javax.management;
import
com.sun.jmx.mbeanserver.DescriptorCache
;
import
com.sun.jmx.mbeanserver.Introspector
;
import
com.sun.jmx.mbeanserver.MBeanInjector
;
import
com.sun.jmx.mbeanserver.MBeanSupport
;
import
com.sun.jmx.mbeanserver.MXBeanSupport
;
import
com.sun.jmx.mbeanserver.StandardMBeanSupport
;
...
...
@@ -125,7 +126,78 @@ import static javax.management.JMX.MBeanOptions;
*
* @since 1.5
*/
public
class
StandardMBean
implements
DynamicMBean
,
MBeanRegistration
{
public
class
StandardMBean
implements
DynamicWrapperMBean
,
MBeanRegistration
{
/**
* <p>Options controlling the behavior of {@code StandardMBean} instances.</p>
*/
public
static
class
Options
extends
JMX
.
MBeanOptions
{
private
static
final
long
serialVersionUID
=
5107355471177517164L
;
private
boolean
wrappedVisible
;
/**
* <p>Construct an {@code Options} object where all options have
* their default values.</p>
*/
public
Options
()
{}
@Override
public
Options
clone
()
{
return
(
Options
)
super
.
clone
();
}
/**
* <p>Defines whether the {@link StandardMBean#getWrappedObject()
* getWrappedObject} method returns the wrapped object.</p>
*
* <p>If this option is true, then {@code getWrappedObject()} will return
* the same object as {@link StandardMBean#getImplementation()
* getImplementation}. Otherwise, it will return the
* StandardMBean instance itself. The setting of this option
* affects the behavior of {@link MBeanServer#getClassLoaderFor
* MBeanServer.getClassLoaderFor} and {@link MBeanServer#isInstanceOf
* MBeanServer.isInstanceOf}. The default value is false for
* compatibility reasons, but true is a better value for most new code.</p>
*
* @return true if this StandardMBean's {@link
* StandardMBean#getWrappedObject getWrappedObject} returns the wrapped
* object.
*/
public
boolean
isWrappedObjectVisible
()
{
return
this
.
wrappedVisible
;
}
/**
* <p>Set the {@link #isWrappedObjectVisible WrappedObjectVisible} option
* to the given value.</p>
* @param visible the new value.
*/
public
void
setWrappedObjectVisible
(
boolean
visible
)
{
this
.
wrappedVisible
=
visible
;
}
// Canonical objects for each of (MXBean,!MXBean) x (WVisible,!WVisible)
private
static
final
Options
[]
CANONICALS
=
{
new
Options
(),
new
Options
(),
new
Options
(),
new
Options
(),
};
static
{
CANONICALS
[
1
].
setMXBeanMappingFactory
(
MXBeanMappingFactory
.
DEFAULT
);
CANONICALS
[
2
].
setWrappedObjectVisible
(
true
);
CANONICALS
[
3
].
setMXBeanMappingFactory
(
MXBeanMappingFactory
.
DEFAULT
);
CANONICALS
[
3
].
setWrappedObjectVisible
(
true
);
}
@Override
MBeanOptions
[]
canonicals
()
{
return
CANONICALS
;
}
@Override
boolean
same
(
MBeanOptions
opts
)
{
return
(
super
.
same
(
opts
)
&&
opts
instanceof
Options
&&
((
Options
)
opts
).
wrappedVisible
==
wrappedVisible
);
}
}
private
final
static
DescriptorCache
descriptors
=
DescriptorCache
.
getInstance
(
JMX
.
proof
);
...
...
@@ -347,7 +419,7 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
* the management interface associated with the given
* implementation.
* @param options MBeanOptions that control the operation of the resulting
* MBean
, as documented in the {@link MBeanOptions} class
.
* MBean.
* @param <T> Allows the compiler to check
* that {@code implementation} does indeed implement the class
* described by {@code mbeanInterface}. The compiler can only
...
...
@@ -381,7 +453,7 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
* @param mbeanInterface The Management Interface exported by this
* MBean.
* @param options MBeanOptions that control the operation of the resulting
* MBean
, as documented in the {@link MBeanOptions} class
.
* MBean.
*
* @exception IllegalArgumentException if the <var>mbeanInterface</var>
* does not follow JMX design patterns for Management Interfaces, or
...
...
@@ -441,7 +513,67 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
* @see #setImplementation
**/
public
Object
getImplementation
()
{
return
mbean
.
getResource
();
return
mbean
.
getWrappedObject
();
}
/**
* <p>Get the wrapped implementation object or return this object.</p>
*
* <p>For compatibility reasons, this method only returns the wrapped
* implementation object if the {@link Options#isWrappedObjectVisible
* WrappedObjectVisible} option was specified when this StandardMBean
* was created. Otherwise it returns {@code this}.</p>
*
* <p>If you want the MBeanServer's {@link MBeanServer#getClassLoaderFor
* getClassLoaderFor} and {@link MBeanServer#isInstanceOf
* isInstanceOf} methods to refer to the wrapped implementation and
* not this StandardMBean object, then you must set the
* {@code WrappedObjectVisible} option, for example using:</p>
*
* <pre>
* StandardMBean.Options opts = new StandardMBean.Options();
* opts.setWrappedObjectVisible(true);
* StandardMBean mbean = new StandardMBean(impl, MyMBean.class, opts);
* </pre>
*
* @return The wrapped implementation object, or this StandardMBean
* instance.
*/
public
Object
getWrappedObject
()
{
if
(
options
instanceof
Options
&&
((
Options
)
options
).
isWrappedObjectVisible
())
return
getImplementation
();
else
return
this
;
}
/**
* <p>Get the ClassLoader of the wrapped implementation object or of this
* object.</p>
*
* <p>For compatibility reasons, this method only returns the ClassLoader
* of the wrapped implementation object if the {@link
* Options#isWrappedObjectVisible WrappedObjectVisible} option was
* specified when this StandardMBean was created. Otherwise it returns
* {@code this.getClass().getClassLoader()}.</p>
*
* <p>If you want the MBeanServer's {@link MBeanServer#getClassLoaderFor
* getClassLoaderFor} and {@link MBeanServer#isInstanceOf
* isInstanceOf} methods to refer to the wrapped implementation and
* not this StandardMBean object, then you must set the
* {@code WrappedObjectVisible} option, for example using:</p>
*
* <pre>
* StandardMBean.Options opts = new StandardMBean.Options();
* opts.setWrappedObjectVisible(true);
* StandardMBean mbean = new StandardMBean(impl, MyMBean.class, opts);
* </pre>
*
* @return The ClassLoader of the wrapped Cimplementation object, or of
* this StandardMBean instance.
*/
public
ClassLoader
getWrappedClassLoader
()
{
return
getWrappedObject
().
getClass
().
getClassLoader
();
}
/**
...
...
@@ -457,7 +589,7 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
* @return The class of the implementation of this Standard MBean (or MXBean).
**/
public
Class
<?>
getImplementationClass
()
{
return
mbean
.
get
Resource
().
getClass
();
return
mbean
.
get
WrappedObject
().
getClass
();
}
/**
...
...
@@ -559,7 +691,7 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
MBeanSupport
msupport
=
mbean
;
final
MBeanInfo
bi
=
msupport
.
getMBeanInfo
();
final
Object
impl
=
msupport
.
get
Resource
();
final
Object
impl
=
msupport
.
get
WrappedObject
();
final
boolean
immutableInfo
=
immutableInfo
(
this
.
getClass
());
...
...
@@ -1184,6 +1316,7 @@ public class StandardMBean implements DynamicMBean, MBeanRegistration {
public
ObjectName
preRegister
(
MBeanServer
server
,
ObjectName
name
)
throws
Exception
{
mbean
.
register
(
server
,
name
);
MBeanInjector
.
inject
(
mbean
.
getWrappedObject
(),
server
,
name
);
return
name
;
}
...
...
src/share/classes/javax/management/modelmbean/RequiredModelMBean.java
浏览文件 @
0a690d3a
...
...
@@ -23,7 +23,7 @@
* have any questions.
*/
/*
* @author IBM Corp.
* @
(#)
author IBM Corp.
*
* Copyright IBM Corp. 1999-2000. All rights reserved.
*/
...
...
@@ -55,6 +55,7 @@ import javax.management.AttributeChangeNotificationFilter;
import
javax.management.AttributeList
;
import
javax.management.AttributeNotFoundException
;
import
javax.management.Descriptor
;
import
javax.management.DynamicWrapperMBean
;
import
javax.management.InstanceNotFoundException
;
import
javax.management.InvalidAttributeValueException
;
import
javax.management.ListenerNotFoundException
;
...
...
@@ -115,7 +116,7 @@ import sun.reflect.misc.ReflectUtil;
*/
public
class
RequiredModelMBean
implements
ModelMBean
,
MBeanRegistration
,
NotificationEmitter
{
implements
ModelMBean
,
MBeanRegistration
,
NotificationEmitter
,
DynamicWrapperMBean
{
/*************************************/
/* attributes */
...
...
@@ -133,6 +134,9 @@ public class RequiredModelMBean
* and operations will be executed */
private
Object
managedResource
=
null
;
/* true if getWrappedObject returns the wrapped resource */
private
boolean
visible
;
/* records the registering in MBeanServer */
private
boolean
registered
=
false
;
private
transient
MBeanServer
server
=
null
;
...
...
@@ -318,9 +322,13 @@ public class RequiredModelMBean
*
* @param mr Object that is the managed resource
* @param mr_type The type of reference for the managed resource.
* <br>Can be: "ObjectReference", "Handle", "IOR", "EJBHandle",
* or "RMIReference".
* <br>In this implementation only "ObjectReference" is supported.
* <br>Can be: "ObjectReference", "VisibleObjectReference",
* "Handle", "IOR", "EJBHandle", or "RMIReference".
* <br>In this implementation only "ObjectReference" and
* "VisibleObjectReference" are supported. The two
* types are equivalent except for the behavior of the
* {@link #getWrappedObject()} and {@link #getWrappedClassLoader()}
* methods.
*
* @exception MBeanException The initializer of the object has
* thrown an exception.
...
...
@@ -340,10 +348,11 @@ public class RequiredModelMBean
"setManagedResource(Object,String)"
,
"Entry"
);
}
visible
=
"visibleObjectReference"
.
equalsIgnoreCase
(
mr_type
);
// check that the mr_type is supported by this JMXAgent
// only "objectReference" is supported
if
((
mr_type
==
null
)
||
(!
mr_type
.
equalsIgnoreCase
(
"objectReference"
)))
{
if
(!
"objectReference"
.
equalsIgnoreCase
(
mr_type
)
&&
!
visible
)
{
if
(
MODELMBEAN_LOGGER
.
isLoggable
(
Level
.
FINER
))
{
MODELMBEAN_LOGGER
.
logp
(
Level
.
FINER
,
RequiredModelMBean
.
class
.
getName
(),
...
...
@@ -368,6 +377,51 @@ public class RequiredModelMBean
}
}
/**
* <p>Get the managed resource for this Model MBean. For compatibility
* reasons, the managed resource is only returned if the resource type
* specified to {@link #setManagedResource setManagedResource} was {@code
* "visibleObjectReference"}. Otherwise, {@code this} is returned.</p>
*
* @return The value that was specified to {@link #setManagedResource
* setManagedResource}, if the resource type is {@code
* "visibleObjectReference"}. Otherwise, {@code this}.
*/
public
Object
getWrappedObject
()
{
if
(
visible
)
return
managedResource
;
else
return
this
;
}
/**
* <p>Get the ClassLoader of the managed resource for this Model MBean. For
* compatibility reasons, the ClassLoader of the managed resource is only
* returned if the resource type specified to {@link #setManagedResource
* setManagedResource} was {@code "visibleObjectReference"}. Otherwise,
* {@code this.getClass().getClassLoader()} is returned.</p>
*
* @return The ClassLoader of the value that was specified to
* {@link #setManagedResource setManagedResource}, if the resource
* type is {@code "visibleObjectReference"}. Otherwise, {@code
* this.getClass().getClassLoader()}.
*/
public
ClassLoader
getWrappedClassLoader
()
{
return
getWrappedObject
().
getClass
().
getClassLoader
();
}
private
static
boolean
isTrue
(
Descriptor
d
,
String
field
)
{
if
(
d
==
null
)
return
false
;
Object
x
=
d
.
getFieldValue
(
field
);
if
(
x
instanceof
Boolean
)
return
(
Boolean
)
x
;
if
(!(
x
instanceof
String
))
return
false
;
String
s
=
(
String
)
x
;
return
(
"true"
.
equalsIgnoreCase
(
s
)
||
"T"
.
equalsIgnoreCase
(
s
));
}
/**
* <p>Instantiates this MBean instance with the data found for
* the MBean in the persistent store. The data loaded could include
...
...
src/share/classes/javax/management/monitor/package.html
浏览文件 @
0a690d3a
...
...
@@ -38,14 +38,17 @@ have any questions.
so within the access control context of the
{@link javax.management.monitor.Monitor#start} caller.
</p>
<p>
The value being monitored can be a simple value contained within a
complex type. For example, the {@link java.lang.management.MemoryMXBean
MemoryMXBean} defined in
<tt>
java.lang.management
</tt>
has an attribute
<tt>
HeapMemoryUsage
</tt>
of type {@link java.lang.management.MemoryUsage
MemoryUsage}. To monitor the amount of
<i>
used
</i>
memory, described by
the
<tt>
used
</tt>
property of
<tt>
MemoryUsage
</tt>
, you could monitor
"
<tt>
HeapMemoryUsage.used
</tt>
". That string would be the argument to
{@link javax.management.monitor.MonitorMBean#setObservedAttribute(String)
<p
id=
"complex"
>
The value being monitored can be a simple value
contained within a complex type. For example, the {@link
java.lang.management.MemoryMXBean MemoryMXBean} defined in
<tt>
java.lang.management
</tt>
has an attribute
<tt>
HeapMemoryUsage
</tt>
of type {@link
java.lang.management.MemoryUsage MemoryUsage}. To monitor the
amount of
<i>
used
</i>
memory, described by the
<tt>
used
</tt>
property of
<tt>
MemoryUsage
</tt>
, you could monitor
"
<tt>
HeapMemoryUsage.used
</tt>
". That string would be the
argument to {@link
javax.management.monitor.MonitorMBean#setObservedAttribute(String)
setObservedAttribute}.
</p>
<p>
The rules used to interpret an
<tt>
ObservedAttribute
</tt>
like
...
...
src/share/classes/javax/management/package.html
浏览文件 @
0a690d3a
此差异已折叠。
点击以展开。
test/javax/management/Introspector/AnnotatedMBeanTest.java
0 → 100644
浏览文件 @
0a690d3a
此差异已折叠。
点击以展开。
test/javax/management/Introspector/AnnotatedNotificationInfoTest.java
0 → 100644
浏览文件 @
0a690d3a
此差异已折叠。
点击以展开。
test/javax/management/Introspector/MBeanDescriptionTest.java
0 → 100644
浏览文件 @
0a690d3a
此差异已折叠。
点击以展开。
test/javax/management/Introspector/ParameterNameTest.java
0 → 100644
浏览文件 @
0a690d3a
/*
* Copyright 2007 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 %M% %I%
* @bug 6323980
* @summary Test that parameter names can be specified with @Name.
* @author Eamonn McManus
*/
import
javax.management.MBean
;
import
javax.management.MBeanInfo
;
import
javax.management.MBeanOperationInfo
;
import
javax.management.MBeanParameterInfo
;
import
javax.management.MBeanServer
;
import
javax.management.MBeanServerFactory
;
import
javax.management.MXBean
;
import
javax.management.ObjectName
;
import
annot.Name
;
import
javax.management.ManagedOperation
;
public
class
ParameterNameTest
{
public
static
interface
NoddyMBean
{
public
int
add
(
int
x
,
@Name
(
"y"
)
int
y
);
}
public
static
class
Noddy
implements
NoddyMBean
{
public
int
add
(
int
x
,
int
y
)
{
return
x
+
y
;
}
}
public
static
interface
NoddyMXBean
{
public
int
add
(
int
x
,
@Name
(
"y"
)
int
y
);
}
public
static
class
NoddyImpl
implements
NoddyMXBean
{
public
int
add
(
int
x
,
int
y
)
{
return
x
+
y
;
}
}
@MBean
public
static
class
NoddyAnnot
{
@ManagedOperation
public
int
add
(
int
x
,
@Name
(
"y"
)
int
y
)
{
return
x
+
y
;
}
}
@MXBean
public
static
class
NoddyAnnotMX
{
@ManagedOperation
public
int
add
(
int
x
,
@Name
(
"y"
)
int
y
)
{
return
x
+
y
;
}
}
private
static
final
Object
[]
mbeans
=
{
new
Noddy
(),
new
NoddyImpl
(),
new
NoddyAnnot
(),
new
NoddyAnnotMX
(),
};
public
static
void
main
(
String
[]
args
)
throws
Exception
{
MBeanServer
mbs
=
MBeanServerFactory
.
newMBeanServer
();
ObjectName
name
=
new
ObjectName
(
"a:b=c"
);
for
(
Object
mbean
:
mbeans
)
{
System
.
out
.
println
(
"Testing "
+
mbean
.
getClass
().
getName
());
mbs
.
registerMBean
(
mbean
,
name
);
MBeanInfo
mbi
=
mbs
.
getMBeanInfo
(
name
);
MBeanOperationInfo
[]
mbois
=
mbi
.
getOperations
();
assertEquals
(
1
,
mbois
.
length
);
MBeanParameterInfo
[]
mbpis
=
mbois
[
0
].
getSignature
();
assertEquals
(
2
,
mbpis
.
length
);
boolean
mx
=
Boolean
.
parseBoolean
(
(
String
)
mbi
.
getDescriptor
().
getFieldValue
(
"mxbean"
));
assertEquals
(
mx
?
"p0"
:
"p1"
,
mbpis
[
0
].
getName
());
assertEquals
(
"y"
,
mbpis
[
1
].
getName
());
mbs
.
unregisterMBean
(
name
);
}
System
.
out
.
println
(
"TEST PASSED"
);
}
private
static
void
assertEquals
(
Object
expect
,
Object
actual
)
throws
Exception
{
boolean
eq
;
if
(
expect
==
null
)
eq
=
(
actual
==
null
);
else
eq
=
expect
.
equals
(
actual
);
if
(!
eq
)
{
throw
new
Exception
(
"TEST FAILED: expected "
+
expect
+
", found "
+
actual
);
}
}
}
test/javax/management/Introspector/ResourceInjectionTest.java
0 → 100644
浏览文件 @
0a690d3a
此差异已折叠。
点击以展开。
test/javax/management/Introspector/annot/Name.java
0 → 100644
浏览文件 @
0a690d3a
/*
* Copyright 2007 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.
*/
package
annot
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
@Retention
(
RetentionPolicy
.
RUNTIME
)
public
@interface
Name
{
String
value
();
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录