Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
ca1683b0
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看板
提交
ca1683b0
编写于
9月 12, 2008
作者:
D
dfuchs
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6747983: jmx namespace: unspecified self-link detection logic
Reviewed-by: emcmanus
上级
672a5836
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
42 addition
and
574 deletion
+42
-574
src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java
...e/classes/com/sun/jmx/namespace/NamespaceInterceptor.java
+3
-223
src/share/classes/javax/management/namespace/JMXRemoteNamespace.java
...lasses/javax/management/namespace/JMXRemoteNamespace.java
+2
-110
test/javax/management/namespace/JMXNamespaceTest.java
test/javax/management/namespace/JMXNamespaceTest.java
+37
-241
未找到文件。
src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java
浏览文件 @
ca1683b0
...
...
@@ -25,22 +25,15 @@
package
com.sun.jmx.namespace
;
import
com.sun.jmx.defaults.JmxProperties
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.UUID
;
import
java.util.logging.Logger
;
import
javax.management.Attribute
;
import
javax.management.AttributeList
;
import
javax.management.MBeanServer
;
import
javax.management.MBeanServerConnection
;
import
javax.management.MalformedObjectNameException
;
import
javax.management.ObjectName
;
import
javax.management.QueryExp
;
import
javax.management.namespace.JMXNamespaces
;
import
javax.management.namespace.JMXNamespace
;
import
javax.management.namespace.JMXNamespacePermission
;
...
...
@@ -54,8 +47,6 @@ import javax.management.namespace.JMXNamespacePermission;
*/
public
class
NamespaceInterceptor
extends
HandlerInterceptor
<
JMXNamespace
>
{
private
static
final
Logger
PROBE_LOG
=
Logger
.
getLogger
(
JmxProperties
.
NAMESPACE_LOGGER
+
".probe"
);
// The target name space in which the NamepsaceHandler is mounted.
private
final
String
targetNs
;
...
...
@@ -64,21 +55,6 @@ public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
private
final
ObjectNameRouter
proc
;
/**
* Internal hack. The JMXRemoteNamespace can be closed and reconnected.
* Each time the JMXRemoteNamespace connects, a probe should be sent
* to detect cycle. The MBeanServer exposed by JMXRemoteNamespace thus
* implements the DynamicProbe interface, which makes it possible for
* this handler to know that it should send a new probe.
*
* XXX: TODO this probe thing is way too complex and fragile.
* This *must* go away or be replaced by something simpler.
* ideas are welcomed.
**/
public
static
interface
DynamicProbe
{
public
boolean
isProbeRequested
();
}
/**
* Creates a new instance of NamespaceInterceptor
*/
...
...
@@ -100,164 +76,6 @@ public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
", namespace="
+
this
.
targetNs
+
")"
;
}
/*
* XXX: TODO this probe thing is way too complex and fragile.
* This *must* go away or be replaced by something simpler.
* ideas are welcomed.
*/
private
volatile
boolean
probed
=
false
;
private
volatile
ObjectName
probe
;
// Query Pattern that we will send through the source server in order
// to detect self-linking namespaces.
//
// XXX: TODO this probe thing is way too complex and fragile.
// This *must* go away or be replaced by something simpler.
// ideas are welcomed.
final
ObjectName
makeProbePattern
(
ObjectName
probe
)
throws
MalformedObjectNameException
{
// we could probably link the probe pattern with the probe - e.g.
// using the UUID as key in the pattern - but is it worth it? it
// also has some side effects on the context namespace - because
// such a probe may get rejected by the jmx.context// namespace.
//
// The trick here is to devise a pattern that is not likely to
// be blocked by intermediate levels. Querying for all namespace
// handlers in the source (or source namespace) is more likely to
// achieve this goal.
//
return
ObjectName
.
getInstance
(
"*"
+
JMXNamespaces
.
NAMESPACE_SEPARATOR
+
":"
+
JMXNamespace
.
TYPE_ASSIGNMENT
);
}
// tell whether the name pattern corresponds to what might have been
// sent as a probe.
// XXX: TODO this probe thing is way too complex and fragile.
// This *must* go away or be replaced by something simpler.
// ideas are welcomed.
final
boolean
isProbePattern
(
ObjectName
name
)
{
final
ObjectName
p
=
probe
;
if
(
p
==
null
)
return
false
;
try
{
return
String
.
valueOf
(
name
).
endsWith
(
targetNs
+
JMXNamespaces
.
NAMESPACE_SEPARATOR
+
"*"
+
JMXNamespaces
.
NAMESPACE_SEPARATOR
+
":"
+
JMXNamespace
.
TYPE_ASSIGNMENT
);
}
catch
(
RuntimeException
x
)
{
// should not happen.
PROBE_LOG
.
finest
(
"Ignoring unexpected exception in self link detection: "
+
x
);
return
false
;
}
}
// The first time a request reaches this NamespaceInterceptor, the
// interceptor will send a probe to detect whether the underlying
// JMXNamespace links to itslef.
//
// One way to create such self-linking namespace would be for instance
// to create a JMXNamespace whose getSourceServer() method would return:
// JMXNamespaces.narrowToNamespace(getMBeanServer(),
// getObjectName().getDomain())
//
// If such an MBeanServer is returned, then any call to that MBeanServer
// will trigger an infinite loop.
// There can be even trickier configurations if remote connections are
// involved.
//
// In order to prevent this from happening, the NamespaceInterceptor will
// send a probe, in an attempt to detect whether it will receive it at
// the other end. If the probe is received, an exception will be thrown
// in order to break the recursion. The probe is only sent once - when
// the first request to the namespace occurs. The DynamicProbe interface
// can also be used by a Sun JMXNamespace implementation to request the
// emission of a probe at any time (see JMXRemoteNamespace
// implementation).
//
// Probes work this way: the NamespaceInterceptor sets a flag and sends
// a queryNames() request. If a queryNames() request comes in when the flag
// is on, then it deduces that there is a self-linking loop - and instead
// of calling queryNames() on the source MBeanServer of the JMXNamespace
// handler (which would cause the loop to go on) it breaks the recursion
// by returning the probe ObjectName.
// If the NamespaceInterceptor receives the probe ObjectName as result of
// its original sendProbe() request it knows that it has been looping
// back on itslef and throws an IOException...
//
//
// XXX: TODO this probe thing is way too complex and fragile.
// This *must* go away or be replaced by something simpler.
// ideas are welcomed.
//
final
void
sendProbe
(
MBeanServerConnection
msc
)
throws
IOException
{
try
{
PROBE_LOG
.
fine
(
"Sending probe"
);
// This is just to prevent any other thread to modify
// the probe while the detection cycle is in progress.
//
final
ObjectName
probePattern
;
// we don't want to synchronize on this - we use targetNs
// because it's non null and final.
synchronized
(
targetNs
)
{
probed
=
false
;
if
(
probe
!=
null
)
{
throw
new
IOException
(
"concurent connection in progress"
);
}
final
String
uuid
=
UUID
.
randomUUID
().
toString
();
final
String
endprobe
=
JMXNamespaces
.
NAMESPACE_SEPARATOR
+
uuid
+
":type=Probe,key="
+
uuid
;
final
ObjectName
newprobe
=
ObjectName
.
getInstance
(
endprobe
);
probePattern
=
makeProbePattern
(
newprobe
);
probe
=
newprobe
;
}
try
{
PROBE_LOG
.
finer
(
"Probe query: "
+
probePattern
+
" expecting: "
+
probe
);
final
Set
<
ObjectName
>
res
=
msc
.
queryNames
(
probePattern
,
null
);
final
ObjectName
expected
=
probe
;
PROBE_LOG
.
finer
(
"Probe res: "
+
res
);
if
(
res
.
contains
(
expected
))
{
throw
new
IOException
(
"namespace "
+
targetNs
+
" is linking to itself: "
+
"cycle detected by probe"
);
}
}
catch
(
SecurityException
x
)
{
PROBE_LOG
.
finer
(
"Can't check for cycles: "
+
x
);
// can't do anything....
}
catch
(
RuntimeException
x
)
{
PROBE_LOG
.
finer
(
"Exception raised by queryNames: "
+
x
);
throw
x
;
}
finally
{
probe
=
null
;
}
}
catch
(
MalformedObjectNameException
x
)
{
final
IOException
io
=
new
IOException
(
"invalid name space: probe failed"
);
io
.
initCause
(
x
);
throw
io
;
}
PROBE_LOG
.
fine
(
"Probe returned - no cycles"
);
probed
=
true
;
}
// allows a Sun implementation JMX Namespace, such as the
// JMXRemoteNamespace, to control when a probe should be sent.
//
// XXX: TODO this probe thing is way too complex and fragile.
// This *must* go away or be replaced by something simpler.
// ideas are welcomed.
private
boolean
isProbeRequested
(
Object
o
)
{
if
(
o
instanceof
DynamicProbe
)
return
((
DynamicProbe
)
o
).
isProbeRequested
();
return
false
;
}
/**
* This method will send a probe to detect self-linking name spaces.
* A self linking namespace is a namespace that links back directly
...
...
@@ -277,29 +95,9 @@ public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
* (see JMXRemoteNamespace implementation).
*/
private
MBeanServer
connection
()
{
try
{
final
MBeanServer
c
=
super
.
source
();
if
(
probe
!=
null
)
// should not happen
throw
new
RuntimeException
(
"connection is being probed"
);
if
(
probed
==
false
||
isProbeRequested
(
c
))
{
try
{
// Should not happen if class well behaved.
// Never probed. Force it.
//System.err.println("sending probe for " +
// "target="+targetNs+", source="+srcNs);
sendProbe
(
c
);
}
catch
(
IOException
io
)
{
throw
new
RuntimeException
(
io
.
getMessage
(),
io
);
}
}
if
(
c
!=
null
)
{
return
c
;
}
}
catch
(
RuntimeException
x
)
{
throw
x
;
}
final
MBeanServer
c
=
super
.
source
();
if
(
c
!=
null
)
return
c
;
// should not come here
throw
new
NullPointerException
(
"getMBeanServerConnection"
);
}
...
...
@@ -315,24 +113,6 @@ public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
return
super
.
source
();
}
/**
* Calls {@link MBeanServerConnection#queryNames queryNames}
* on the underlying
* {@link #getMBeanServerConnection MBeanServerConnection}.
**/
@Override
public
final
Set
<
ObjectName
>
queryNames
(
ObjectName
name
,
QueryExp
query
)
{
// XXX: TODO this probe thing is way too complex and fragile.
// This *must* go away or be replaced by something simpler.
// ideas are welcomed.
PROBE_LOG
.
finer
(
"probe is: "
+
probe
+
" pattern is: "
+
name
);
if
(
probe
!=
null
&&
isProbePattern
(
name
))
{
PROBE_LOG
.
finer
(
"Return probe: "
+
probe
);
return
Collections
.
singleton
(
probe
);
}
return
super
.
queryNames
(
name
,
query
);
}
@Override
protected
ObjectName
toSource
(
ObjectName
targetName
)
throws
MalformedObjectNameException
{
...
...
src/share/classes/javax/management/namespace/JMXRemoteNamespace.java
浏览文件 @
ca1683b0
...
...
@@ -28,11 +28,9 @@ package javax.management.namespace;
import
com.sun.jmx.defaults.JmxProperties
;
import
com.sun.jmx.mbeanserver.Util
;
import
com.sun.jmx.namespace.JMXNamespaceUtils
;
import
com.sun.jmx.namespace.NamespaceInterceptor.DynamicProbe
;
import
com.sun.jmx.remote.util.EnvHelp
;
import
java.io.IOException
;
import
java.security.AccessControlException
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.concurrent.atomic.AtomicLong
;
...
...
@@ -44,9 +42,7 @@ import javax.management.AttributeChangeNotification;
import
javax.management.InstanceNotFoundException
;
import
javax.management.ListenerNotFoundException
;
import
javax.management.MBeanNotificationInfo
;
import
javax.management.MBeanPermission
;
import
javax.management.MBeanServerConnection
;
import
javax.management.MalformedObjectNameException
;
import
javax.management.Notification
;
import
javax.management.NotificationBroadcasterSupport
;
import
javax.management.NotificationEmitter
;
...
...
@@ -118,9 +114,6 @@ public class JMXRemoteNamespace
*/
private
static
final
Logger
LOG
=
JmxProperties
.
NAMESPACE_LOGGER
;
private
static
final
Logger
PROBE_LOG
=
Logger
.
getLogger
(
JmxProperties
.
NAMESPACE_LOGGER_NAME
+
".probe"
);
// This connection listener is used to listen for connection events from
// the underlying JMXConnector. It is used in particular to maintain the
...
...
@@ -153,8 +146,7 @@ public class JMXRemoteNamespace
// because the one that is actually used is the one supplied by the
// override of getMBeanServerConnection().
private
static
class
JMXRemoteNamespaceDelegate
extends
MBeanServerConnectionWrapper
implements
DynamicProbe
{
extends
MBeanServerConnectionWrapper
{
private
volatile
JMXRemoteNamespace
parent
=
null
;
JMXRemoteNamespaceDelegate
()
{
...
...
@@ -180,9 +172,6 @@ public class JMXRemoteNamespace
}
public
boolean
isProbeRequested
()
{
return
this
.
parent
.
isProbeRequested
();
}
}
private
static
final
MBeanNotificationInfo
connectNotification
=
...
...
@@ -201,7 +190,6 @@ public class JMXRemoteNamespace
private
volatile
MBeanServerConnection
server
=
null
;
private
volatile
JMXConnector
conn
=
null
;
private
volatile
ClassLoader
defaultClassLoader
=
null
;
private
volatile
boolean
probed
;
/**
* Creates a new instance of {@code JMXRemoteNamespace}.
...
...
@@ -241,9 +229,6 @@ public class JMXRemoteNamespace
// handles (dis)connection events
this
.
listener
=
new
ConnectionListener
();
// XXX TODO: remove the probe, or simplify it.
this
.
probed
=
false
;
}
/**
...
...
@@ -274,10 +259,6 @@ public class JMXRemoteNamespace
return
optionsMap
;
}
boolean
isProbeRequested
()
{
return
probed
==
false
;
}
public
void
addNotificationListener
(
NotificationListener
listener
,
NotificationFilter
filter
,
Object
handback
)
{
broadcaster
.
addNotificationListener
(
listener
,
filter
,
handback
);
...
...
@@ -603,26 +584,7 @@ public class JMXRemoteNamespace
}
public
void
connect
()
throws
IOException
{
if
(
conn
!=
null
)
{
try
{
// This is much too fragile. It must go away!
PROBE_LOG
.
finest
(
"Probing again..."
);
triggerProbe
(
getMBeanServerConnection
());
}
catch
(
Exception
x
)
{
close
();
Throwable
cause
=
x
;
// if the cause is a security exception - rethrows it...
while
(
cause
!=
null
)
{
if
(
cause
instanceof
SecurityException
)
throw
(
SecurityException
)
cause
;
cause
=
cause
.
getCause
();
}
throw
new
IOException
(
"connection failed: cycle?"
,
x
);
}
}
LOG
.
fine
(
"connecting..."
);
// TODO remove these traces
// System.err.println(getInitParameter()+" connecting");
final
Map
<
String
,
Object
>
env
=
new
HashMap
<
String
,
Object
>(
getEnvMap
());
try
{
...
...
@@ -652,79 +614,9 @@ public class JMXRemoteNamespace
throw
x
;
}
// XXX Revisit here
// Note from the author: This business of switching connection is
// incredibly complex. Isn't there any means to simplify it?
//
switchConnection
(
conn
,
aconn
,
msc
);
try
{
triggerProbe
(
msc
);
}
catch
(
Exception
x
)
{
close
();
Throwable
cause
=
x
;
// if the cause is a security exception - rethrows it...
while
(
cause
!=
null
)
{
if
(
cause
instanceof
SecurityException
)
throw
(
SecurityException
)
cause
;
cause
=
cause
.
getCause
();
}
throw
new
IOException
(
"connection failed: cycle?"
,
x
);
}
LOG
.
fine
(
"connected."
);
}
// If this is a self-linking namespace, this method should trigger
// the emission of a probe in the wrapping NamespaceInterceptor.
// The first call to source() in the wrapping NamespaceInterceptor
// causes the emission of the probe.
//
// Note: the MBeanServer returned by getSourceServer
// (our private JMXRemoteNamespaceDelegate inner class)
// implements a sun private interface (DynamicProbe) which is
// used by the NamespaceInterceptor to determine whether it should
// send a probe or not.
// We needed this interface here because the NamespaceInterceptor
// has otherwise no means to knows that this object has just
// connected, and that a new probe should be sent.
//
// Probes work this way: the NamespaceInterceptor sets a flag and sends
// a queryNames() request. If a queryNames() request comes in when the flag
// is on, then it deduces that there is a self-linking loop - and instead
// of calling queryNames() on the JMXNamespace (which would cause the
// loop to go on) it breaks the recursion by returning the probe ObjectName.
// If the NamespaceInterceptor receives the probe ObjectName as result of
// its original queryNames() it knows that it has been looping back on
// itslef and throws an Exception - which will be raised through this
// method, thus preventing the connection to be established...
//
// More info in the com.sun.jmx.namespace.NamespaceInterceptor class
//
// XXX: TODO this probe thing is way too complex and fragile.
// This *must* go away or be replaced by something simpler.
// ideas are welcomed.
//
private
void
triggerProbe
(
final
MBeanServerConnection
msc
)
throws
MalformedObjectNameException
,
IOException
{
// Query Pattern that we will send through the source server in order
// to detect self-linking namespaces.
//
//
final
ObjectName
pattern
;
pattern
=
ObjectName
.
getInstance
(
"*"
+
JMXNamespaces
.
NAMESPACE_SEPARATOR
+
":"
+
JMXNamespace
.
TYPE_ASSIGNMENT
);
probed
=
false
;
try
{
msc
.
queryNames
(
pattern
,
null
);
probed
=
true
;
}
catch
(
AccessControlException
x
)
{
// if we have an MBeanPermission missing then do nothing...
if
(!(
x
.
getPermission
()
instanceof
MBeanPermission
))
throw
x
;
PROBE_LOG
.
finer
(
"Can't check for cycles: "
+
x
);
probed
=
false
;
// no need to do it again...
}
LOG
.
fine
(
"connected."
);
}
public
void
close
()
throws
IOException
{
...
...
test/javax/management/namespace/JMXNamespaceTest.java
浏览文件 @
ca1683b0
...
...
@@ -35,7 +35,6 @@
* NamespaceController.java NamespaceControllerMBean.java
* @run main/othervm JMXNamespaceTest
*/
import
java.io.IOException
;
import
java.lang.management.ManagementFactory
;
import
java.lang.management.MemoryMXBean
;
import
java.lang.reflect.InvocationTargetException
;
...
...
@@ -52,10 +51,10 @@ import javax.management.InvalidAttributeValueException;
import
javax.management.JMX
;
import
javax.management.MBeanServer
;
import
javax.management.MBeanServerConnection
;
import
javax.management.MBeanServerFactory
;
import
javax.management.NotificationEmitter
;
import
javax.management.ObjectInstance
;
import
javax.management.ObjectName
;
import
javax.management.RuntimeOperationsException
;
import
javax.management.StandardMBean
;
import
javax.management.namespace.JMXNamespaces
;
import
javax.management.namespace.JMXNamespace
;
...
...
@@ -155,7 +154,7 @@ public class JMXNamespaceTest {
}
}
p
rivate
static
class
SimpleTestConf
{
p
ublic
static
class
SimpleTestConf
{
public
final
Wombat
wombat
;
public
final
StandardMBean
mbean
;
public
final
String
dirname
;
...
...
@@ -457,259 +456,56 @@ public class JMXNamespaceTest {
}
}
/**
* Test cycle detection.
* mkdir test ; cd test ; ln -s . kanga ; ln -s kanga/kanga/roo/kanga roo
* touch kanga/roo/wombat
**/
public
static
void
probeKangaRooTest
(
String
[]
args
)
{
final
SimpleTestConf
conf
;
public
static
void
verySimpleTest
(
String
[]
args
)
{
System
.
err
.
println
(
"verySimpleTest: starting"
);
try
{
conf
=
new
SimpleTestConf
(
args
);
try
{
final
JMXServiceURL
url
=
new
JMXServiceURL
(
"rmi"
,
"localHost"
,
0
);
final
Map
<
String
,
Object
>
empty
=
Collections
.
emptyMap
();
final
JMXConnectorServer
server
=
JMXConnectorServerFactory
.
newJMXConnectorServer
(
url
,
empty
,
conf
.
server
);
server
.
start
();
final
JMXServiceURL
address
=
server
.
getAddress
();
final
JMXConnector
client
=
JMXConnectorFactory
.
connect
(
address
,
empty
);
final
String
[]
signature
=
{
JMXServiceURL
.
class
.
getName
(),
Map
.
class
.
getName
(),
};
final
Object
[]
params
=
{
address
,
null
,
};
final
MBeanServerConnection
c
=
client
.
getMBeanServerConnection
();
// ln -s . kanga
final
ObjectName
dirName1
=
new
ObjectName
(
"kanga//:type=JMXNamespace"
);
c
.
createMBean
(
JMXRemoteTargetNamespace
.
class
.
getName
(),
dirName1
,
params
,
signature
);
c
.
invoke
(
dirName1
,
"connect"
,
null
,
null
);
try
{
// ln -s kanga//kanga//roo//kanga roo
final
JMXNamespace
local
=
new
JMXNamespace
(
new
MBeanServerConnectionWrapper
(
null
,
JMXNamespaceTest
.
class
.
getClassLoader
()){
@Override
protected
MBeanServerConnection
getMBeanServerConnection
()
{
return
JMXNamespaces
.
narrowToNamespace
(
c
,
"kanga//kanga//roo//kanga"
);
}
});
final
ObjectName
dirName2
=
new
ObjectName
(
"roo//:type=JMXNamespace"
);
conf
.
server
.
registerMBean
(
local
,
dirName2
);
System
.
out
.
println
(
dirName2
+
" created!"
);
try
{
// touch kanga/roo/wombat
final
ObjectName
wombatName1
=
new
ObjectName
(
"kanga//roo//"
+
conf
.
wombatName
);
final
WombatMBean
wombat1
=
JMX
.
newMBeanProxy
(
c
,
wombatName1
,
WombatMBean
.
class
);
final
String
newCaption
=
"I am still the same old wombat"
;
Exception
x
=
null
;
try
{
wombat1
.
setCaption
(
newCaption
);
}
catch
(
RuntimeOperationsException
r
)
{
x
=
r
.
getTargetException
();
System
.
out
.
println
(
"Got expected exception: "
+
x
);
// r.printStackTrace();
}
if
(
x
==
null
)
throw
new
RuntimeException
(
"cycle not detected!"
);
}
finally
{
c
.
unregisterMBean
(
dirName2
);
}
}
finally
{
c
.
unregisterMBean
(
dirName1
);
client
.
close
();
server
.
stop
();
}
}
finally
{
conf
.
close
();
}
System
.
err
.
println
(
"probeKangaRooTest PASSED"
);
final
MBeanServer
srv
=
MBeanServerFactory
.
createMBeanServer
();
srv
.
registerMBean
(
new
JMXNamespace
(
JMXNamespaces
.
narrowToNamespace
(
srv
,
"foo"
)),
JMXNamespaces
.
getNamespaceObjectName
(
"foo"
));
throw
new
Exception
(
"Excpected IllegalArgumentException not raised."
);
}
catch
(
IllegalArgumentException
x
)
{
System
.
err
.
println
(
"verySimpleTest: got expected exception: "
+
x
);
}
catch
(
Exception
x
)
{
System
.
err
.
println
(
"
probeKangaRoo
Test FAILED: "
+
x
);
System
.
err
.
println
(
"
verySimple
Test FAILED: "
+
x
);
x
.
printStackTrace
();
throw
new
RuntimeException
(
x
);
}
System
.
err
.
println
(
"verySimpleTest: PASSED"
);
}
/**
* Test cycle detection 2.
* mkdir test ; cd test ; ln -s . roo ; ln -s roo/roo kanga
* touch kanga/roo/wombat ; rm roo ; ln -s kanga roo ;
* touch kanga/roo/wombat
*
**/
public
static
void
probeKangaRooCycleTest
(
String
[]
args
)
{
final
SimpleTestConf
conf
;
try
{
conf
=
new
SimpleTestConf
(
args
);
Exception
failed
=
null
;
try
{
final
JMXServiceURL
url
=
new
JMXServiceURL
(
"rmi"
,
"localHost"
,
0
);
final
Map
<
String
,
Object
>
empty
=
Collections
.
emptyMap
();
final
JMXConnectorServer
server
=
JMXConnectorServerFactory
.
newJMXConnectorServer
(
url
,
empty
,
conf
.
server
);
server
.
start
();
final
JMXServiceURL
address
=
server
.
getAddress
();
final
JMXConnector
client
=
JMXConnectorFactory
.
connect
(
address
,
empty
);
final
String
[]
signature
=
{
JMXServiceURL
.
class
.
getName
(),
Map
.
class
.
getName
(),
};
final
String
[]
signature2
=
{
JMXServiceURL
.
class
.
getName
(),
Map
.
class
.
getName
(),
String
.
class
.
getName
()
};
final
Object
[]
params
=
{
address
,
Collections
.
emptyMap
(),
};
final
Object
[]
params2
=
{
address
,
null
,
"kanga"
,
};
final
MBeanServerConnection
c
=
client
.
getMBeanServerConnection
();
// ln -s . roo
final
ObjectName
dirName1
=
new
ObjectName
(
"roo//:type=JMXNamespace"
);
c
.
createMBean
(
JMXRemoteTargetNamespace
.
class
.
getName
(),
dirName1
,
params
,
signature
);
c
.
invoke
(
dirName1
,
"connect"
,
null
,
null
);
try
{
final
Map
<
String
,
Object
>
emptyMap
=
Collections
.
emptyMap
();
final
JMXNamespace
local
=
new
JMXNamespace
(
new
MBeanServerConnectionWrapper
(
JMXNamespaces
.
narrowToNamespace
(
c
,
"roo//roo//"
),
JMXNamespaceTest
.
class
.
getClassLoader
()))
{
};
// ln -s roo/roo kanga
final
ObjectName
dirName2
=
new
ObjectName
(
"kanga//:type=JMXNamespace"
);
conf
.
server
.
registerMBean
(
local
,
dirName2
);
System
.
out
.
println
(
dirName2
+
" created!"
);
try
{
// touch kanga/roo/wombat
final
ObjectName
wombatName1
=
new
ObjectName
(
"kanga//roo//"
+
conf
.
wombatName
);
final
WombatMBean
wombat1
=
JMX
.
newMBeanProxy
(
c
,
wombatName1
,
WombatMBean
.
class
);
final
String
newCaption
=
"I am still the same old wombat"
;
wombat1
.
setCaption
(
newCaption
);
// rm roo
c
.
unregisterMBean
(
dirName1
);
// ln -s kanga roo
System
.
err
.
println
(
"**** Creating "
+
dirName1
+
" ****"
);
c
.
createMBean
(
JMXRemoteTargetNamespace
.
class
.
getName
(),
dirName1
,
params2
,
signature2
);
System
.
err
.
println
(
"**** Created "
+
dirName1
+
" ****"
);
Exception
x
=
null
;
try
{
// touch kanga/roo/wombat
wombat1
.
setCaption
(
newCaption
+
" I hope"
);
}
catch
(
RuntimeOperationsException
r
)
{
x
=(
Exception
)
r
.
getCause
();
System
.
out
.
println
(
"Got expected exception: "
+
x
);
//r.printStackTrace();
}
if
(
x
==
null
)
throw
new
RuntimeException
(
"should have failed!"
);
x
=
null
;
try
{
// ls kanga/roo/wombat
System
.
err
.
println
(
"**** Connecting "
+
dirName1
+
" ****"
);
JMX
.
newMBeanProxy
(
c
,
dirName1
,
JMXRemoteNamespaceMBean
.
class
).
connect
();
System
.
err
.
println
(
"**** Connected "
+
dirName1
+
" ****"
);
}
catch
(
IOException
r
)
{
x
=
r
;
System
.
out
.
println
(
"Got expected exception: "
+
x
);
//r.printStackTrace();
}
System
.
err
.
println
(
"**** Expected Exception Not Raised ****"
);
if
(
x
==
null
)
{
System
.
out
.
println
(
dirName1
+
" contains: "
+
c
.
queryNames
(
new
ObjectName
(
dirName1
.
getDomain
()+
"*:*"
),
null
));
throw
new
RuntimeException
(
"cycle not detected!"
);
}
}
catch
(
Exception
t
)
{
if
(
failed
==
null
)
failed
=
t
;
}
finally
{
c
.
unregisterMBean
(
dirName2
);
}
}
finally
{
try
{
c
.
unregisterMBean
(
dirName1
);
}
catch
(
Exception
t
)
{
if
(
failed
==
null
)
failed
=
t
;
System
.
err
.
println
(
"Failed to unregister "
+
dirName1
+
": "
+
t
);
}
try
{
client
.
close
();
}
catch
(
Exception
t
)
{
if
(
failed
==
null
)
failed
=
t
;
System
.
err
.
println
(
"Failed to close client: "
+
t
);
}
try
{
server
.
stop
();
}
catch
(
Exception
t
)
{
if
(
failed
==
null
)
failed
=
t
;
System
.
err
.
println
(
"Failed to stop server: "
+
t
);
}
}
}
finally
{
try
{
conf
.
close
();
}
catch
(
Exception
t
)
{
if
(
failed
==
null
)
failed
=
t
;
System
.
err
.
println
(
"Failed to stop server: "
+
t
);
}
}
if
(
failed
!=
null
)
throw
failed
;
System
.
err
.
println
(
"probeKangaRooCycleTest PASSED"
);
public
static
void
verySimpleTest2
(
String
[]
args
)
{
System
.
err
.
println
(
"verySimpleTest2: starting"
);
try
{
final
MBeanServer
srv
=
MBeanServerFactory
.
createMBeanServer
();
final
JMXConnectorServer
cs
=
JMXConnectorServerFactory
.
newJMXConnectorServer
(
new
JMXServiceURL
(
"rmi"
,
null
,
0
),
null
,
srv
);
cs
.
start
();
final
JMXConnector
cc
=
JMXConnectorFactory
.
connect
(
cs
.
getAddress
());
srv
.
registerMBean
(
new
JMXNamespace
(
new
MBeanServerConnectionWrapper
(
JMXNamespaces
.
narrowToNamespace
(
cc
.
getMBeanServerConnection
(),
"foo"
))),
JMXNamespaces
.
getNamespaceObjectName
(
"foo"
));
throw
new
Exception
(
"Excpected IllegalArgumentException not raised."
);
}
catch
(
IllegalArgumentException
x
)
{
System
.
err
.
println
(
"verySimpleTest2: got expected exception: "
+
x
);
}
catch
(
Exception
x
)
{
System
.
err
.
println
(
"
probeKangaRooCycleTest
FAILED: "
+
x
);
System
.
err
.
println
(
"
verySimpleTest2
FAILED: "
+
x
);
x
.
printStackTrace
();
throw
new
RuntimeException
(
x
);
}
System
.
err
.
println
(
"verySimpleTest2: PASSED"
);
}
public
static
void
main
(
String
[]
args
)
{
simpleTest
(
args
);
recursiveTest
(
args
);
probeKangaRoo
Test
(
args
);
probeKangaRooCycleTest
(
args
);
verySimple
Test
(
args
);
verySimpleTest2
(
args
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录