jmx4r 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +41 -0
- data/Rakefile +6 -6
- data/examples/class_loading.rb +0 -0
- data/examples/jvm_mngmt.rb +0 -0
- data/examples/logging.rb +0 -0
- data/examples/memory.rb +0 -0
- data/examples/memory_on_many_nodes.rb +0 -0
- data/lib/jmx4r.rb +84 -19
- data/lib/open_data_helper.rb +0 -0
- data/test/tc_attributes.rb +0 -0
- data/test/tc_auth.rb +0 -0
- data/test/tc_composite_data.rb +0 -0
- data/test/tc_connection.rb +16 -1
- data/test/tc_multiple_connections.rb +2 -2
- metadata +20 -15
- data/README.txt +0 -18
data/README.rdoc
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
jmx4r[http://github.com/jmesnil/jmx4r/] is a JMX library for JRuby.
|
2
|
+
|
3
|
+
It can be used to write simple Ruby scripts running on JRuby[http://jruby.org]
|
4
|
+
to manage remote Java applications (e.g. JBoss[http://www.jboss.org],
|
5
|
+
Tomcat[http://tomcat.apache.org/]) using
|
6
|
+
JMX[http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/].
|
7
|
+
|
8
|
+
jmx4r helps to manage Java applications using JMX in a simple and powerful way:
|
9
|
+
* no need to depend on the Java interfaces of the MBean in your management code. This means <em>less deployment issues</em>
|
10
|
+
* Thanks to Ruby metaprogramming toolset, you can <em>treat your MBeans as simple objects</em> and jmx4r hides all the complexity to map them to the javax.management API for you
|
11
|
+
* you can manage your own JVM (e.g. if you're running a Rails on JRuby application) or a remote JVM in the same way
|
12
|
+
|
13
|
+
== Installation
|
14
|
+
|
15
|
+
jruby -S gem install jmx4r
|
16
|
+
|
17
|
+
== Usage
|
18
|
+
|
19
|
+
# To trigger a garbage collection on a Java application:
|
20
|
+
|
21
|
+
require 'rubygems'
|
22
|
+
require 'jmx4r'
|
23
|
+
|
24
|
+
JMX::MBean.establish_connection :host => "localhost", :port => 3000
|
25
|
+
|
26
|
+
memory = JMX::MBean.find_by_name "java.lang:type=Memory"
|
27
|
+
# display verbose GC logs
|
28
|
+
memory.verbose = true
|
29
|
+
# trigger a Garbage Collection
|
30
|
+
memory.gc
|
31
|
+
|
32
|
+
== Help
|
33
|
+
|
34
|
+
* Wiki[http://jmesnil.net/wiki/Jmx4r]
|
35
|
+
* RDoc[http://jmx4r.rubyforge.org/doc/]
|
36
|
+
|
37
|
+
== Source Code
|
38
|
+
|
39
|
+
git clone git://github.com/jmesnil/jmx4r.git
|
40
|
+
|
41
|
+
|
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ require "rubygems"
|
|
6
6
|
|
7
7
|
dir = File.dirname(__FILE__)
|
8
8
|
lib = File.join(dir, "lib", "jmx4r.rb")
|
9
|
-
version = "0.0.
|
9
|
+
version = "0.0.7"
|
10
10
|
|
11
11
|
task :default => [:test]
|
12
12
|
|
@@ -17,9 +17,9 @@ Rake::TestTask.new do |test|
|
|
17
17
|
end
|
18
18
|
|
19
19
|
Rake::RDocTask.new do |rdoc|
|
20
|
-
rdoc.rdoc_files.include( "README.
|
20
|
+
rdoc.rdoc_files.include( "README.rdoc", "LICENSE.txt", "AUTHORS.txt",
|
21
21
|
"lib/" )
|
22
|
-
rdoc.main = "README.
|
22
|
+
rdoc.main = "README.rdoc"
|
23
23
|
rdoc.rdoc_dir = "doc/html"
|
24
24
|
rdoc.title = "jmx4r Documentation"
|
25
25
|
rdoc.options << "-S"
|
@@ -40,16 +40,16 @@ spec = Gem::Specification.new do |spec|
|
|
40
40
|
|
41
41
|
spec.test_files = "test/ts_all.rb"
|
42
42
|
spec.has_rdoc = true
|
43
|
-
spec.extra_rdoc_files = %w{README.
|
43
|
+
spec.extra_rdoc_files = %w{README.rdoc LICENSE.txt}
|
44
44
|
spec.rdoc_options << '--title' << 'jmx4r Documentation' <<
|
45
|
-
'--main' << 'README.
|
45
|
+
'--main' << 'README.rdoc'
|
46
46
|
|
47
47
|
spec.require_path = 'lib'
|
48
48
|
|
49
49
|
spec.author = "Jeff Mesnil"
|
50
50
|
spec.email = "jmesnil@gmail.com"
|
51
51
|
spec.rubyforge_project = "jmx4r"
|
52
|
-
spec.homepage = "http://
|
52
|
+
spec.homepage = "http://jmesnil.net/wiki/Jmx4r"
|
53
53
|
spec.description = <<END_DESC
|
54
54
|
jmx4r is a JMX library for JRuby
|
55
55
|
END_DESC
|
data/examples/class_loading.rb
CHANGED
File without changes
|
data/examples/jvm_mngmt.rb
CHANGED
File without changes
|
data/examples/logging.rb
CHANGED
File without changes
|
data/examples/memory.rb
CHANGED
File without changes
|
File without changes
|
data/lib/jmx4r.rb
CHANGED
@@ -19,8 +19,34 @@ module JMX
|
|
19
19
|
require 'objectname_helper'
|
20
20
|
require 'jruby'
|
21
21
|
|
22
|
+
class MBeanServerConnectionProxy
|
23
|
+
attr_reader :connector
|
24
|
+
|
25
|
+
# Adds a connector attribute to Java's native MBeanServerConnection class.
|
26
|
+
#
|
27
|
+
# The connector attribute can be used to manage the connection (e.g, to close it).
|
28
|
+
# Why this isn't included in the native MBeanServerConnection class is beyond me.
|
29
|
+
#
|
30
|
+
# connector:: JMXConnector instance as returned by JMXConnectorFactory.connect.
|
31
|
+
def initialize(connector)
|
32
|
+
@connector = connector
|
33
|
+
@connection = connector.getMBeanServerConnection
|
34
|
+
end
|
35
|
+
|
36
|
+
# Close the connection (an unfortunate omission from the MBeanServerConnection class, imho)
|
37
|
+
def close
|
38
|
+
@connector.close
|
39
|
+
end
|
40
|
+
|
41
|
+
# Forward all other method messages to the underlying MBeanServerConnection instance.
|
42
|
+
def method_missing(method, *args, &block)
|
43
|
+
@connection.send method, *args, &block
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
22
47
|
class MBean
|
23
48
|
include_class 'java.util.HashMap'
|
49
|
+
include_class 'javax.naming.Context'
|
24
50
|
include_class 'javax.management.Attribute'
|
25
51
|
include_class 'javax.management.ObjectName'
|
26
52
|
include_class 'javax.management.remote.JMXConnector'
|
@@ -28,31 +54,31 @@ module JMX
|
|
28
54
|
include_class 'javax.management.remote.JMXServiceURL'
|
29
55
|
JThread = java.lang.Thread
|
30
56
|
|
31
|
-
attr_reader :object_name, :operations, :attributes
|
57
|
+
attr_reader :object_name, :operations, :attributes, :connection
|
32
58
|
|
33
59
|
# Creates a new MBean.
|
34
60
|
#
|
35
61
|
# object_name:: a string corresponding to a valid ObjectName
|
36
|
-
#
|
62
|
+
# connection:: a connection to a MBean server. If none is passed,
|
37
63
|
# use the global connection created by
|
38
64
|
# MBean.establish_connection
|
39
|
-
def initialize(object_name,
|
40
|
-
@
|
65
|
+
def initialize(object_name, connection=nil)
|
66
|
+
@connection = connection || @@connection
|
41
67
|
@object_name = object_name
|
42
|
-
info = @
|
68
|
+
info = @connection.getMBeanInfo @object_name
|
43
69
|
@attributes = Hash.new
|
44
70
|
info.attributes.each do | mbean_attr |
|
45
71
|
@attributes[mbean_attr.name.snake_case] = mbean_attr.name
|
46
72
|
self.class.instance_eval do
|
47
73
|
define_method mbean_attr.name.snake_case do
|
48
|
-
@
|
74
|
+
@connection.getAttribute @object_name, "#{mbean_attr.name}"
|
49
75
|
end
|
50
76
|
end
|
51
77
|
if mbean_attr.isWritable
|
52
78
|
self.class.instance_eval do
|
53
79
|
define_method "#{mbean_attr.name.snake_case}=" do |value|
|
54
80
|
attr = Attribute.new mbean_attr.name, value
|
55
|
-
@
|
81
|
+
@connection.setAttribute @object_name, attr
|
56
82
|
end
|
57
83
|
end
|
58
84
|
end
|
@@ -67,7 +93,7 @@ module JMX
|
|
67
93
|
def method_missing(method, *args, &block) #:nodoc:
|
68
94
|
if @operations.keys.include?(method.to_s)
|
69
95
|
op_name, param_types = @operations[method.to_s]
|
70
|
-
@
|
96
|
+
@connection.invoke @object_name,
|
71
97
|
op_name,
|
72
98
|
args.to_java(:Object),
|
73
99
|
param_types.to_java(:String)
|
@@ -76,7 +102,7 @@ module JMX
|
|
76
102
|
end
|
77
103
|
end
|
78
104
|
|
79
|
-
@@
|
105
|
+
@@connection = nil
|
80
106
|
|
81
107
|
# establish a connection to a remote MBean server which will
|
82
108
|
# be used by all subsequent MBeans.
|
@@ -89,19 +115,21 @@ module JMX
|
|
89
115
|
# JMX::MBean.establish_connection :port => "node23", :port => 1090
|
90
116
|
# JMX::MBean.establish_connection :port => "node23", :username => "jeff", :password => "secret"
|
91
117
|
def self.establish_connection(args={})
|
92
|
-
@@
|
118
|
+
@@connection ||= create_connection args
|
93
119
|
end
|
94
120
|
|
95
121
|
def self.remove_connection(args={})
|
96
|
-
@@
|
122
|
+
if @@connection
|
123
|
+
@@connection.close rescue nil
|
124
|
+
end
|
125
|
+
@@connection = nil
|
97
126
|
end
|
98
127
|
|
99
128
|
def self.connection(args={})
|
100
129
|
if args.has_key? :host or args.has_key? :port
|
101
130
|
return create_connection(args)
|
102
131
|
else
|
103
|
-
MBean.establish_connection(args)
|
104
|
-
return @@mbsc
|
132
|
+
@@connection ||= MBean.establish_connection(args)
|
105
133
|
end
|
106
134
|
end
|
107
135
|
|
@@ -122,6 +150,8 @@ module JMX
|
|
122
150
|
# [:credentials] custom credentials (if the MBean server requires authentication).
|
123
151
|
# No default. It has precedence over :username and :password (i.e. if
|
124
152
|
# :credentials is specified, :username & :password are ignored)
|
153
|
+
# [:provider_package] use to fill the JMXConnectorFactory::PROTOCOL_PROVIDER_PACKAGES
|
154
|
+
# No default
|
125
155
|
#
|
126
156
|
def self.create_connection(args={})
|
127
157
|
host= args[:host] || "localhost"
|
@@ -129,6 +159,7 @@ module JMX
|
|
129
159
|
username = args[:username]
|
130
160
|
password = args[:password]
|
131
161
|
credentials = args[:credentials]
|
162
|
+
provider_package = args[:provider_package]
|
132
163
|
|
133
164
|
# host & port are not taken into account if url is set (see issue #7)
|
134
165
|
standard_url = "service:jmx:rmi:///jndi/rmi://#{host}:#{port}/jmxrmi"
|
@@ -143,6 +174,12 @@ module JMX
|
|
143
174
|
|
144
175
|
env = HashMap.new
|
145
176
|
env.put(JMXConnector::CREDENTIALS, credentials) if credentials
|
177
|
+
# only fill the Context and JMXConnectorFactory properties if provider_package is set
|
178
|
+
if provider_package
|
179
|
+
env.put(Context::SECURITY_PRINCIPAL, username) if username
|
180
|
+
env.put(Context::SECURITY_CREDENTIALS, password) if password
|
181
|
+
env.put(JMXConnectorFactory::PROTOCOL_PROVIDER_PACKAGES, provider_package)
|
182
|
+
end
|
146
183
|
|
147
184
|
# the context class loader is set to JRuby's classloader when
|
148
185
|
# creating the JMX Connection so that classes loaded using
|
@@ -153,7 +190,7 @@ module JMX
|
|
153
190
|
JThread.current_thread.context_class_loader = JRuby.runtime.getJRubyClassLoader
|
154
191
|
|
155
192
|
connector = JMXConnectorFactory::connect JMXServiceURL.new(url), env
|
156
|
-
connector
|
193
|
+
MBeanServerConnectionProxy.new connector
|
157
194
|
ensure
|
158
195
|
# ... and we reset the previous context class loader
|
159
196
|
JThread.current_thread.context_class_loader = context_class_loader
|
@@ -173,17 +210,45 @@ module JMX
|
|
173
210
|
#
|
174
211
|
def self.find_all_by_name(name, args={})
|
175
212
|
object_name = ObjectName.new(name)
|
176
|
-
|
177
|
-
object_names =
|
178
|
-
object_names.map { |on| MBean.new(on,
|
213
|
+
connection = args[:connection] || MBean.connection(args)
|
214
|
+
object_names = connection.queryNames(object_name, nil)
|
215
|
+
object_names.map { |on| MBean.new(on, connection) }
|
179
216
|
end
|
180
217
|
|
181
218
|
# Same as #find_all_by_name but the ObjectName passed in parameter
|
182
219
|
# can not be a pattern.
|
183
220
|
# Only one single MBean is returned.
|
184
221
|
def self.find_by_name(name, args={})
|
185
|
-
|
186
|
-
MBean.new ObjectName.new(name),
|
222
|
+
connection = args[:connection] || MBean.connection(args)
|
223
|
+
MBean.new ObjectName.new(name), connection
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.pretty_print (object_name, args={})
|
227
|
+
connection = args[:connection] || MBean.connection(args)
|
228
|
+
info = connection.getMBeanInfo ObjectName.new(object_name)
|
229
|
+
puts "object_name: #{object_name}"
|
230
|
+
puts "class: #{info.class_name}"
|
231
|
+
puts "description: #{info.description}"
|
232
|
+
puts "operations:"
|
233
|
+
info.operations.each do | op |
|
234
|
+
puts " #{op.name}"
|
235
|
+
op.signature.each do | param |
|
236
|
+
puts " #{param.name} (#{param.type} #{param.description})"
|
237
|
+
end
|
238
|
+
puts " ----"
|
239
|
+
puts " description: #{op.description}"
|
240
|
+
puts " return_type: #{op.return_type}"
|
241
|
+
puts " impact: #{op.impact}"
|
242
|
+
end
|
243
|
+
puts "attributes:"
|
244
|
+
info.attributes.each do | attr |
|
245
|
+
puts " #{attr.name}"
|
246
|
+
puts " description: #{attr.description}"
|
247
|
+
puts " type: #{attr.type}"
|
248
|
+
puts " readable: #{attr.readable}"
|
249
|
+
puts " writable: #{attr.writable}"
|
250
|
+
puts " is: #{attr.is}"
|
251
|
+
end
|
187
252
|
end
|
188
253
|
end
|
189
254
|
end
|
data/lib/open_data_helper.rb
CHANGED
File without changes
|
data/test/tc_attributes.rb
CHANGED
File without changes
|
data/test/tc_auth.rb
CHANGED
File without changes
|
data/test/tc_composite_data.rb
CHANGED
File without changes
|
data/test/tc_connection.rb
CHANGED
@@ -6,6 +6,7 @@ require "jmx4r"
|
|
6
6
|
require "jconsole"
|
7
7
|
|
8
8
|
class TestConnection < Test::Unit::TestCase
|
9
|
+
|
9
10
|
def teardown
|
10
11
|
JMX::MBean.remove_connection
|
11
12
|
end
|
@@ -25,7 +26,21 @@ class TestConnection < Test::Unit::TestCase
|
|
25
26
|
def test_establish_connection
|
26
27
|
begin
|
27
28
|
JConsole::start
|
28
|
-
JMX::MBean.establish_connection
|
29
|
+
connection = JMX::MBean.establish_connection
|
30
|
+
assert(connection.getMBeanCount > 0)
|
31
|
+
ensure
|
32
|
+
JConsole::stop
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_remove_connection
|
37
|
+
begin
|
38
|
+
JConsole::start
|
39
|
+
connection = JMX::MBean.establish_connection
|
40
|
+
JMX::MBean.remove_connection
|
41
|
+
assert_raise(NativeException) {
|
42
|
+
connection.getMBeanCount
|
43
|
+
}
|
29
44
|
ensure
|
30
45
|
JConsole::stop
|
31
46
|
end
|
@@ -16,7 +16,6 @@ class TestMultipleConnections < Test::Unit::TestCase
|
|
16
16
|
|
17
17
|
def teardown
|
18
18
|
@ports.each do |port|
|
19
|
-
JMX::MBean.remove_connection :port => port
|
20
19
|
JConsole::stop port
|
21
20
|
end
|
22
21
|
end
|
@@ -36,7 +35,7 @@ class TestMultipleConnections < Test::Unit::TestCase
|
|
36
35
|
end
|
37
36
|
|
38
37
|
def test_same_connection
|
39
|
-
mbsc = JMX::MBean.
|
38
|
+
mbsc = JMX::MBean.create_connection :port => @ports[0]
|
40
39
|
|
41
40
|
delegate_1 = JMX::MBean.find_by_name @delegate_on, :connection => mbsc
|
42
41
|
delegate_2 = JMX::MBean.find_by_name @delegate_on, :connection => mbsc
|
@@ -61,6 +60,7 @@ class TestMultipleConnections < Test::Unit::TestCase
|
|
61
60
|
delegate_2 = JMX::MBean.find_by_name @delegate_on
|
62
61
|
|
63
62
|
assert_equal delegate_1.m_bean_server_id, delegate_2.m_bean_server_id
|
63
|
+
JMX::MBean.remove_connection
|
64
64
|
end
|
65
65
|
|
66
66
|
end
|
metadata
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
extensions: []
|
3
|
-
|
3
|
+
|
4
|
+
homepage: http://jmesnil.net/wiki/Jmx4r
|
4
5
|
executables: []
|
5
|
-
|
6
|
-
|
6
|
+
|
7
|
+
version: !ruby/object:Gem::Version
|
8
|
+
version: 0.0.7
|
7
9
|
post_install_message:
|
8
|
-
date:
|
10
|
+
date: 2009-02-11 23:00:00 +00:00
|
9
11
|
files:
|
10
12
|
- examples/class_loading.rb
|
11
13
|
- examples/jvm_mngmt.rb
|
@@ -25,47 +27,50 @@ files:
|
|
25
27
|
- test/tc_multiple_connections.rb
|
26
28
|
- test/ts_all.rb
|
27
29
|
- Rakefile
|
28
|
-
- README.
|
30
|
+
- README.rdoc
|
29
31
|
- LICENSE.txt
|
30
|
-
rubygems_version: 1.
|
32
|
+
rubygems_version: 1.3.1
|
31
33
|
rdoc_options:
|
32
34
|
- --title
|
33
35
|
- jmx4r Documentation
|
34
36
|
- --main
|
35
|
-
- README.
|
37
|
+
- README.rdoc
|
36
38
|
signing_key:
|
37
39
|
cert_chain: []
|
40
|
+
|
38
41
|
name: jmx4r
|
39
42
|
has_rdoc: true
|
40
43
|
platform: ruby
|
41
44
|
summary: jmx4r is a JMX library for JRuby
|
42
45
|
default_executable:
|
43
46
|
bindir: bin
|
44
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
45
48
|
version:
|
46
49
|
requirements:
|
47
50
|
- - '>='
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version:
|
50
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: "0"
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
54
|
version:
|
52
55
|
requirements:
|
53
56
|
- - '>='
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
version:
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
56
59
|
require_paths:
|
57
60
|
- lib
|
58
61
|
specification_version: 2
|
59
62
|
test_files:
|
60
63
|
- test/ts_all.rb
|
61
64
|
dependencies: []
|
65
|
+
|
62
66
|
description: jmx4r is a JMX library for JRuby
|
63
67
|
email: jmesnil@gmail.com
|
64
68
|
authors:
|
65
69
|
- Jeff Mesnil
|
66
70
|
extra_rdoc_files:
|
67
|
-
- README.
|
71
|
+
- README.rdoc
|
68
72
|
- LICENSE.txt
|
69
73
|
requirements: []
|
74
|
+
|
70
75
|
rubyforge_project: jmx4r
|
71
76
|
autorequire:
|
data/README.txt
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
jmx4r is a JMX library for JRuby.
|
2
|
-
|
3
|
-
It can be used to write simple Ruby scripts running on JRuby[http://jruby.org]
|
4
|
-
to manage remote Java applications (e.g. JBoss[http://www.jboss.org],
|
5
|
-
Tomcat[http://tomcat.apache.org/]) using
|
6
|
-
JMX[http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/].
|
7
|
-
|
8
|
-
== Examples
|
9
|
-
|
10
|
-
To trigger a garbage collection on a Java application:
|
11
|
-
|
12
|
-
require 'rubygems'
|
13
|
-
require 'jmx4r'
|
14
|
-
|
15
|
-
JMX::MBean.establish_connection :host => "localhost", :port => 3000
|
16
|
-
memory = JMX::MBean.find_by_name "java.lang:type=Memory"
|
17
|
-
memory.gc
|
18
|
-
|