jmx4r 0.0.8 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +5 -0
- data/Rakefile +1 -1
- data/lib/dynamic_mbean.rb +21 -18
- data/lib/jconsole.rb +20 -9
- data/lib/jdk/jdk4.rb +16 -0
- data/lib/jdk/jdk5.rb +34 -0
- data/lib/jdk/jdk6.rb +69 -0
- data/lib/jdk_helper.rb +69 -0
- data/lib/jmx4r.rb +54 -23
- data/test/tc_attributes.rb +7 -0
- data/test/tc_connection.rb +11 -0
- data/test/tc_dynamic_mbean.rb +49 -0
- data/test/tc_methods.rb +30 -0
- data/test/ts_all.rb +1 -0
- metadata +7 -2
data/README.rdoc
CHANGED
@@ -29,6 +29,11 @@ jmx4r helps to manage Java applications using JMX in a simple and powerful way:
|
|
29
29
|
# trigger a Garbage Collection
|
30
30
|
memory.gc
|
31
31
|
|
32
|
+
# For local processes not publishing jmxrmi ports, instead:
|
33
|
+
|
34
|
+
# connect to the local JConsole process
|
35
|
+
JMX::MBean.establish_connection :command => /jconsole/i
|
36
|
+
|
32
37
|
== Help
|
33
38
|
|
34
39
|
* Wiki[http://jmesnil.net/wiki/Jmx4r]
|
data/Rakefile
CHANGED
data/lib/dynamic_mbean.rb
CHANGED
@@ -3,10 +3,10 @@
|
|
3
3
|
# taken from the 'jmx' gems in jruby-extras
|
4
4
|
|
5
5
|
module JMX
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
java_import javax.management.MBeanParameterInfo
|
7
|
+
java_import javax.management.MBeanOperationInfo
|
8
|
+
java_import javax.management.MBeanAttributeInfo
|
9
|
+
java_import javax.management.MBeanInfo
|
10
10
|
|
11
11
|
# Module that is used to bridge java to ruby and ruby to java types.
|
12
12
|
module JavaTypeAware
|
@@ -99,32 +99,36 @@ module JMX
|
|
99
99
|
# like: user_name= and username. So in your ruby code you can treat the attributes
|
100
100
|
# as "regular" ruby accessors
|
101
101
|
class DynamicMBean
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
102
|
+
java_import javax.management.MBeanOperationInfo
|
103
|
+
java_import javax.management.MBeanAttributeInfo
|
104
|
+
java_import javax.management.DynamicMBean
|
105
|
+
java_import javax.management.MBeanInfo
|
106
106
|
include JMX::JavaTypeAware
|
107
107
|
|
108
108
|
#NOTE this will not be needed when JRuby-3164 is fixed.
|
109
109
|
def self.inherited(cls)
|
110
110
|
cls.send(:include, DynamicMBean)
|
111
111
|
end
|
112
|
+
|
113
|
+
def self.mbean_attributes
|
114
|
+
@mbean_attributes ||= {}
|
115
|
+
end
|
112
116
|
|
113
117
|
# TODO: preserve any original method_added?
|
114
118
|
# TODO: Error handling here when it all goes wrong?
|
115
119
|
def self.method_added(name) #:nodoc:
|
116
|
-
return if
|
117
|
-
|
118
|
-
operations <<
|
119
|
-
|
120
|
+
return if self.mbean_attributes[:op].nil?
|
121
|
+
self.mbean_attributes[:op].name = name
|
122
|
+
operations << self.mbean_attributes[:op].to_jmx
|
123
|
+
self.mbean_attributes[:op] = nil
|
120
124
|
end
|
121
125
|
|
122
126
|
def self.attributes #:nodoc:
|
123
|
-
|
127
|
+
self.mbean_attributes[:attrs] ||= []
|
124
128
|
end
|
125
129
|
|
126
130
|
def self.operations #:nodoc:
|
127
|
-
|
131
|
+
self.mbean_attributes[:ops] ||= []
|
128
132
|
end
|
129
133
|
|
130
134
|
# the <tt>rw_attribute</tt> method is used to declare a JMX read write attribute.
|
@@ -207,7 +211,7 @@ module JMX
|
|
207
211
|
#++
|
208
212
|
def self.operation(description=nil)
|
209
213
|
# Wait to error check until method_added so we can know method name
|
210
|
-
|
214
|
+
self.mbean_attributes[:op] = JMX::Operation.new description
|
211
215
|
end
|
212
216
|
|
213
217
|
# Used to declare a parameter (you can declare more than one in succession) that
|
@@ -220,7 +224,7 @@ module JMX
|
|
220
224
|
# ...
|
221
225
|
# end
|
222
226
|
def self.parameter(type, name=nil, description=nil)
|
223
|
-
|
227
|
+
self.mbean_attributes[:op].parameters << JMX::Parameter.new(type, name, description)
|
224
228
|
end
|
225
229
|
|
226
230
|
# Used to declare the return type of the operation
|
@@ -231,7 +235,7 @@ module JMX
|
|
231
235
|
# ...
|
232
236
|
# end
|
233
237
|
def self.returns(type)
|
234
|
-
|
238
|
+
self.mbean_attributes[:op].return_type = type
|
235
239
|
end
|
236
240
|
|
237
241
|
def initialize(description="")
|
@@ -272,4 +276,3 @@ module JMX
|
|
272
276
|
end
|
273
277
|
|
274
278
|
end
|
275
|
-
|
data/lib/jconsole.rb
CHANGED
@@ -12,7 +12,8 @@ module JConsole
|
|
12
12
|
# By default, no authentication is required to connect to it.
|
13
13
|
#
|
14
14
|
# The args hash accepts 3 keys:
|
15
|
-
# [:port] the port which will be listens to JMX connections
|
15
|
+
# [:port] the port which will be listens to JMX connections.
|
16
|
+
# if the port is 0, jmxrmi port is not published
|
16
17
|
# [:pwd_file] the path to the file containing the authentication credentials
|
17
18
|
# [:access_file] the path to the file containing the authorization credentials
|
18
19
|
#
|
@@ -29,13 +30,19 @@ module JConsole
|
|
29
30
|
cmd =<<-EOCMD.split("\n").join(" ")
|
30
31
|
jconsole
|
31
32
|
-J-Dcom.sun.management.jmxremote
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
EOCMD
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
EOCMD
|
34
|
+
|
35
|
+
if port != 0
|
36
|
+
cmd << <<-EOCMD.split("\n").join(" ")
|
37
|
+
-J-Dcom.sun.management.jmxremote.port=#{port}
|
38
|
+
-J-Dcom.sun.management.jmxremote.ssl=false
|
39
|
+
-J-Dcom.sun.management.jmxremote.authenticate=#{!pwd_file.nil?}
|
40
|
+
EOCMD
|
41
|
+
|
42
|
+
if pwd_file and access_file
|
43
|
+
cmd << " -J-Dcom.sun.management.jmxremote.password.file=#{pwd_file}"
|
44
|
+
cmd << " -J-Dcom.sun.management.jmxremote.access.file=#{access_file}"
|
45
|
+
end
|
39
46
|
end
|
40
47
|
Thread.start { system cmd }
|
41
48
|
sleep 3
|
@@ -46,7 +53,11 @@ EOCMD
|
|
46
53
|
# By default, it will kill the process corresponding to an instance JConsole with
|
47
54
|
# a port on 3000. Another port can be specified in parameter.
|
48
55
|
def JConsole.stop(port=3000)
|
49
|
-
|
56
|
+
ps = "ps a -w -o pid,command | grep -w jconsole"
|
57
|
+
ps << " | grep port=#{port}" if port != 0
|
58
|
+
ps << " | grep -v grep | grep -v ruby | cut -c -5"
|
59
|
+
|
60
|
+
jconsole_pid = `#{ps}`
|
50
61
|
`kill #{jconsole_pid}` if jconsole_pid != ""
|
51
62
|
sleep 1
|
52
63
|
end
|
data/lib/jdk/jdk4.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
module JMX
|
3
|
+
module JDKHelper
|
4
|
+
module JDK4
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def method_missing(method, *args, &block)
|
8
|
+
raise "JDK (>= 5.0) implementation is not available - \
|
9
|
+
maybe only JREs or older JDKs are installed properly."
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
data/lib/jdk/jdk5.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
module JMX
|
3
|
+
module JDKHelper
|
4
|
+
module JDK5
|
5
|
+
include_class 'sun.jvmstat.monitor.HostIdentifier'
|
6
|
+
include_class 'sun.jvmstat.monitor.MonitoredHost'
|
7
|
+
include_class 'sun.jvmstat.monitor.MonitoredVmUtil'
|
8
|
+
include_class 'sun.jvmstat.monitor.VmIdentifier'
|
9
|
+
include_class 'sun.management.ConnectorAddressLink'
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
def find_local_url(command_pattern)
|
14
|
+
host_id = HostIdentifier.new(nil)
|
15
|
+
host = MonitoredHost.get_monitored_host(host_id)
|
16
|
+
|
17
|
+
host.active_vms.each do |vmid_int|
|
18
|
+
vmid = VmIdentifier.new(vmid_int.to_s)
|
19
|
+
vm = host.get_monitored_vm(vmid)
|
20
|
+
command = MonitoredVmUtil.command_line(vm)
|
21
|
+
if command_pattern === command
|
22
|
+
return ConnectorAddressLink.import_from(vmid_int)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
data/lib/jdk/jdk6.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
module JMX
|
3
|
+
module JDKHelper
|
4
|
+
module JDK6
|
5
|
+
include_class 'com.sun.tools.attach.VirtualMachine'
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def find_local_url(command_pattern)
|
9
|
+
target_vmd = VirtualMachine.list.find do |vmd|
|
10
|
+
command_pattern === vmd.display_name
|
11
|
+
end
|
12
|
+
|
13
|
+
if target_vmd
|
14
|
+
local_connector_address(target_vmd)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def local_connector_address(vm_descriptor)
|
21
|
+
vm = VirtualMachine.attach(vm_descriptor)
|
22
|
+
|
23
|
+
address = nil
|
24
|
+
agent_loaded = false
|
25
|
+
|
26
|
+
lambda {
|
27
|
+
address = vm.get_agent_properties.get(
|
28
|
+
"com.sun.management.jmxremote.localConnectorAddress")
|
29
|
+
|
30
|
+
unless address || agent_loaded
|
31
|
+
load_management_agent(vm)
|
32
|
+
agent_loaded = true
|
33
|
+
redo
|
34
|
+
end
|
35
|
+
}.call
|
36
|
+
|
37
|
+
vm.detach
|
38
|
+
|
39
|
+
address
|
40
|
+
end
|
41
|
+
|
42
|
+
def load_management_agent(vm)
|
43
|
+
home =
|
44
|
+
vm.get_system_properties.get_property 'java.home'
|
45
|
+
|
46
|
+
try_load_management_agent(vm, [home, 'jre', 'lib']) or
|
47
|
+
try_load_management_agent(vm, [home, 'lib']) or
|
48
|
+
raise "management agent not found"
|
49
|
+
end
|
50
|
+
|
51
|
+
def try_load_management_agent(vm, path)
|
52
|
+
sep = vm.get_system_properties.get_property 'file.separator'
|
53
|
+
|
54
|
+
path = path.dup
|
55
|
+
path << 'management-agent.jar'
|
56
|
+
|
57
|
+
file = Java::java.io.File.new(path.join(sep))
|
58
|
+
if file.exists
|
59
|
+
vm.load_agent(file.get_canonical_path,
|
60
|
+
"com.sun.management.jmxremote")
|
61
|
+
true
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
data/lib/jdk_helper.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
module JMX
|
3
|
+
module JDKHelper
|
4
|
+
include_class 'java.lang.System'
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def method_missing(method, *args, &block)
|
9
|
+
init unless @jdk
|
10
|
+
@jdk.send method, *args, &block
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def init
|
16
|
+
@jdk =
|
17
|
+
case
|
18
|
+
when has_java_class?("com.sun.tools.attach.VirtualMachine")
|
19
|
+
require "jdk/jdk6"
|
20
|
+
JDK6
|
21
|
+
when has_java_class?('sun.jvmstat.monitor.MonitoredHost')
|
22
|
+
require "jdk/jdk5"
|
23
|
+
JDK5
|
24
|
+
else
|
25
|
+
require "jdk/jdk4"
|
26
|
+
JDK4
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def has_java_class?(name)
|
31
|
+
begin
|
32
|
+
include_class name
|
33
|
+
true
|
34
|
+
rescue
|
35
|
+
retry if load_tools_jar
|
36
|
+
false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def load_tools_jar
|
41
|
+
unless @tools_loaded
|
42
|
+
home = System.get_property 'java.home'
|
43
|
+
paths = [
|
44
|
+
[home, '..', 'lib'],
|
45
|
+
[home, 'lib'],
|
46
|
+
]
|
47
|
+
try_load_jar('tools.jar', paths)
|
48
|
+
@tools_loaded = true
|
49
|
+
true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def try_load_jar(jar_file, paths)
|
54
|
+
sep = System.get_property 'file.separator'
|
55
|
+
paths = paths.dup
|
56
|
+
begin
|
57
|
+
path = paths.shift
|
58
|
+
require path.join(sep) + sep + jar_file
|
59
|
+
true
|
60
|
+
rescue LoadError
|
61
|
+
retry unless paths.empty?
|
62
|
+
false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
data/lib/jmx4r.rb
CHANGED
@@ -18,6 +18,7 @@ module JMX
|
|
18
18
|
require 'dynamic_mbean'
|
19
19
|
require 'open_data_helper'
|
20
20
|
require 'objectname_helper'
|
21
|
+
require 'jdk_helper'
|
21
22
|
require 'jruby'
|
22
23
|
|
23
24
|
class MBeanServerConnectionProxy
|
@@ -57,6 +58,13 @@ module JMX
|
|
57
58
|
|
58
59
|
attr_reader :object_name, :operations, :attributes, :connection
|
59
60
|
|
61
|
+
def metaclass; class << self; self; end; end
|
62
|
+
def meta_def name, &blk
|
63
|
+
metaclass.instance_eval do
|
64
|
+
define_method name, &blk
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
60
68
|
# Creates a new MBean.
|
61
69
|
#
|
62
70
|
# object_name:: a string corresponding to a valid ObjectName
|
@@ -70,19 +78,6 @@ module JMX
|
|
70
78
|
@attributes = Hash.new
|
71
79
|
info.attributes.each do | mbean_attr |
|
72
80
|
@attributes[mbean_attr.name.snake_case] = mbean_attr.name
|
73
|
-
self.class.instance_eval do
|
74
|
-
define_method mbean_attr.name.snake_case do
|
75
|
-
@connection.getAttribute @object_name, "#{mbean_attr.name}"
|
76
|
-
end
|
77
|
-
end
|
78
|
-
if mbean_attr.isWritable
|
79
|
-
self.class.instance_eval do
|
80
|
-
define_method "#{mbean_attr.name.snake_case}=" do |value|
|
81
|
-
attr = Attribute.new mbean_attr.name, value
|
82
|
-
@connection.setAttribute @object_name, attr
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
81
|
end
|
87
82
|
@operations = Hash.new
|
88
83
|
info.operations.each do |mbean_op|
|
@@ -92,12 +87,14 @@ module JMX
|
|
92
87
|
end
|
93
88
|
|
94
89
|
def method_missing(method, *args, &block) #:nodoc:
|
95
|
-
|
96
|
-
|
90
|
+
method_in_snake_case = method.to_s.snake_case # this way Java/JRuby styles are compatible
|
91
|
+
|
92
|
+
if @operations.keys.include?(method_in_snake_case)
|
93
|
+
op_name, param_types = @operations[method_in_snake_case]
|
97
94
|
@connection.invoke @object_name,
|
98
|
-
|
99
|
-
|
100
|
-
|
95
|
+
op_name,
|
96
|
+
args.to_java(:Object),
|
97
|
+
param_types.to_java(:String)
|
101
98
|
else
|
102
99
|
super
|
103
100
|
end
|
@@ -115,6 +112,7 @@ module JMX
|
|
115
112
|
#
|
116
113
|
# JMX::MBean.establish_connection :port => "node23", :port => 1090
|
117
114
|
# JMX::MBean.establish_connection :port => "node23", :username => "jeff", :password => "secret"
|
115
|
+
# JMX::MBean.establish_connection :command => /jconsole/i
|
118
116
|
def self.establish_connection(args={})
|
119
117
|
@@connection ||= create_connection args
|
120
118
|
end
|
@@ -147,6 +145,16 @@ module JMX
|
|
147
145
|
# if the url is specified, the host & port parameters are
|
148
146
|
# not taken into account
|
149
147
|
#
|
148
|
+
# [:command] the pattern matches the command line of the local
|
149
|
+
# JVM process including the MBean server.
|
150
|
+
# (command lines are listed on the connection dialog
|
151
|
+
# in JConsole).
|
152
|
+
# No default.
|
153
|
+
# this feature needs a JDK (>=5) installed on the local
|
154
|
+
# system.
|
155
|
+
# if the command is specified, the host & port or the url
|
156
|
+
# parameters are not taken into account
|
157
|
+
#
|
150
158
|
# [:username] the name of the user (if the MBean server requires authentication).
|
151
159
|
# No default
|
152
160
|
#
|
@@ -168,9 +176,14 @@ module JMX
|
|
168
176
|
credentials = args[:credentials]
|
169
177
|
provider_package = args[:provider_package]
|
170
178
|
|
171
|
-
|
172
|
-
|
173
|
-
|
179
|
+
if args[:command]
|
180
|
+
url = JDKHelper.find_local_url(args[:command]) or
|
181
|
+
raise "no locally attacheable VMs"
|
182
|
+
else
|
183
|
+
# host & port are not taken into account if url is set (see issue #7)
|
184
|
+
standard_url = "service:jmx:rmi:///jndi/rmi://#{host}:#{port}/jmxrmi"
|
185
|
+
url = args[:url] || standard_url
|
186
|
+
end
|
174
187
|
|
175
188
|
unless credentials
|
176
189
|
if !username.nil? and username.length > 0
|
@@ -219,7 +232,7 @@ module JMX
|
|
219
232
|
object_name = ObjectName.new(name)
|
220
233
|
connection = args[:connection] || MBean.connection(args)
|
221
234
|
object_names = connection.queryNames(object_name, nil)
|
222
|
-
object_names.map { |on|
|
235
|
+
object_names.map { |on| create_mbean on, connection }
|
223
236
|
end
|
224
237
|
|
225
238
|
# Same as #find_all_by_name but the ObjectName passed in parameter
|
@@ -227,7 +240,25 @@ module JMX
|
|
227
240
|
# Only one single MBean is returned.
|
228
241
|
def self.find_by_name(name, args={})
|
229
242
|
connection = args[:connection] || MBean.connection(args)
|
230
|
-
|
243
|
+
create_mbean ObjectName.new(name), connection
|
244
|
+
end
|
245
|
+
|
246
|
+
def self.create_mbean(object_name, connection)
|
247
|
+
info = connection.getMBeanInfo object_name
|
248
|
+
mbean = MBean.new object_name, connection
|
249
|
+
# define attribute accessor methods for the mbean
|
250
|
+
info.attributes.each do |mbean_attr|
|
251
|
+
mbean.meta_def mbean_attr.name.snake_case do
|
252
|
+
connection.getAttribute object_name, mbean_attr.name
|
253
|
+
end
|
254
|
+
if mbean_attr.isWritable
|
255
|
+
mbean.meta_def "#{mbean_attr.name.snake_case}=" do |value|
|
256
|
+
attribute = Attribute.new mbean_attr.name, value
|
257
|
+
connection.setAttribute object_name, attribute
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
mbean
|
231
262
|
end
|
232
263
|
|
233
264
|
def self.pretty_print (object_name, args={})
|
data/test/tc_attributes.rb
CHANGED
@@ -34,4 +34,11 @@ class TestAttribute < Test::Unit::TestCase
|
|
34
34
|
def test_non_writable_attribute
|
35
35
|
assert_raise(NoMethodError) { @memory.object_pending_finalization_count = -1 }
|
36
36
|
end
|
37
|
+
|
38
|
+
def test_non_overlapping_attributes
|
39
|
+
assert_raise(NoMethodError) { @memory.logger_names }
|
40
|
+
logging = JMX::MBean.find_by_name "java.util.logging:type=Logging", :connection => ManagementFactory.platform_mbean_server
|
41
|
+
assert_raise(NoMethodError) { logging.verbose }
|
42
|
+
assert_raise(NoMethodError) { @memory.logger_names }
|
43
|
+
end
|
37
44
|
end
|
data/test/tc_connection.rb
CHANGED
@@ -77,4 +77,15 @@ class TestConnection < Test::Unit::TestCase
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
+
def test_establish_connection_local
|
81
|
+
begin
|
82
|
+
JConsole::start :port => 0
|
83
|
+
connection = JMX::MBean.establish_connection \
|
84
|
+
:command => /jconsole/i
|
85
|
+
assert(connection.getMBeanCount > 0)
|
86
|
+
ensure
|
87
|
+
JConsole::stop 0
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
80
91
|
end
|
data/test/tc_dynamic_mbean.rb
CHANGED
@@ -76,4 +76,53 @@ class TestDynamicMBean < Test::Unit::TestCase
|
|
76
76
|
mbean = JMX::MBean.find_by_name "jmx4r:name=OperationInvocationMBean", :connection => mbeanServer
|
77
77
|
assert_equal("oof", mbean.reverse("foo"))
|
78
78
|
end
|
79
|
+
|
80
|
+
class Foo < JMX::DynamicMBean
|
81
|
+
rw_attribute :foo_attr, :string
|
82
|
+
|
83
|
+
operation
|
84
|
+
parameter :string
|
85
|
+
returns :string
|
86
|
+
def foo(arg)
|
87
|
+
"foo #{arg}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class Bar < JMX::DynamicMBean
|
92
|
+
rw_attribute :bar_attr, :string
|
93
|
+
|
94
|
+
operation
|
95
|
+
parameter :string
|
96
|
+
returns :string
|
97
|
+
def bar(arg)
|
98
|
+
"bar #{arg}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def test_separate_dynamic_beans_have_separate_operations_and_attributes
|
103
|
+
mbean_server = ManagementFactory.platform_mbean_server
|
104
|
+
mbean_server.register_mbean Foo.new, ObjectName.new("jmx4r:name=foo")
|
105
|
+
mbean_server.register_mbean Bar.new, ObjectName.new("jmx4r:name=bar")
|
106
|
+
|
107
|
+
foo_mbean = JMX::MBean.find_by_name "jmx4r:name=foo", :connection => mbean_server
|
108
|
+
assert_equal "foo test", foo_mbean.foo("test")
|
109
|
+
assert_raise(NoMethodError){
|
110
|
+
foo_mbean.bar("test")
|
111
|
+
}
|
112
|
+
foo_mbean.foo_attr = "test"
|
113
|
+
assert_equal "test", foo_mbean.foo_attr
|
114
|
+
assert_raise(NoMethodError){
|
115
|
+
foo_mbean.bar_attr = "test"
|
116
|
+
}
|
117
|
+
bar_mbean = JMX::MBean.find_by_name "jmx4r:name=bar", :connection => mbean_server
|
118
|
+
assert_equal "bar test", bar_mbean.bar("test")
|
119
|
+
assert_raise(NoMethodError) {
|
120
|
+
bar_mbean.foo("test")
|
121
|
+
}
|
122
|
+
bar_mbean.bar_attr = "test"
|
123
|
+
assert_equal "test", bar_mbean.bar_attr
|
124
|
+
assert_raise(NoMethodError){
|
125
|
+
bar_mbean.foo_attr = "test"
|
126
|
+
}
|
127
|
+
end
|
79
128
|
end
|
data/test/tc_methods.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Copyright 2007 Jeff Mesnil (http://jmesnil.net)
|
2
|
+
|
3
|
+
require "test/unit"
|
4
|
+
|
5
|
+
require "jmx4r"
|
6
|
+
require "jconsole"
|
7
|
+
|
8
|
+
class TestMethods < Test::Unit::TestCase
|
9
|
+
java_import java.lang.management.ManagementFactory
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@logging = JMX::MBean.find_by_name "java.util.logging:type=Logging", :connection => ManagementFactory.platform_mbean_server
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
JMX::MBean.remove_connection
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_invoke_operation
|
20
|
+
@logging.set_logger_level "global", "FINEST"
|
21
|
+
assert_equal "FINEST", @logging.get_logger_level("global")
|
22
|
+
end
|
23
|
+
|
24
|
+
# make sure we can also use Java name convention
|
25
|
+
def test_invoke_CamelCaseOperation
|
26
|
+
@logging.setLoggerLevel "global", "FINE"
|
27
|
+
assert_equal "FINE", @logging.getLoggerLevel("global")
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/test/ts_all.rb
CHANGED
metadata
CHANGED
@@ -42,14 +42,19 @@ files:
|
|
42
42
|
- examples/runtime_sysprops.rb
|
43
43
|
- lib/dynamic_mbean.rb
|
44
44
|
- lib/jconsole.rb
|
45
|
+
- lib/jdk_helper.rb
|
45
46
|
- lib/jmx4r.rb
|
46
47
|
- lib/objectname_helper.rb
|
47
48
|
- lib/open_data_helper.rb
|
49
|
+
- lib/jdk/jdk4.rb
|
50
|
+
- lib/jdk/jdk5.rb
|
51
|
+
- lib/jdk/jdk6.rb
|
48
52
|
- test/tc_attributes.rb
|
49
53
|
- test/tc_auth.rb
|
50
54
|
- test/tc_composite_data.rb
|
51
55
|
- test/tc_connection.rb
|
52
56
|
- test/tc_dynamic_mbean.rb
|
57
|
+
- test/tc_methods.rb
|
53
58
|
- test/tc_multiple_connections.rb
|
54
59
|
- test/ts_all.rb
|
55
60
|
- Rakefile
|
@@ -68,12 +73,12 @@ requirements: []
|
|
68
73
|
|
69
74
|
authors:
|
70
75
|
- Jeff Mesnil
|
71
|
-
date: 2009-
|
76
|
+
date: 2009-10-21 22:00:00 +00:00
|
72
77
|
platform: ruby
|
73
78
|
test_files:
|
74
79
|
- test/ts_all.rb
|
75
80
|
version: !ruby/object:Gem::Version
|
76
|
-
version: 0.0
|
81
|
+
version: 0.1.0
|
77
82
|
require_paths:
|
78
83
|
- lib
|
79
84
|
dependencies: []
|