jmx4r 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|