jmx 0.8 → 0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008 Thomas E Enebo <enebo@acm.org>
1
+ Copyright (c) 2008-2012 Thomas E Enebo <tom.enebo@gmail.com>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -5,20 +5,40 @@
5
5
  JMX is a library which allows you to access JMX MBeans as a client or create
6
6
  your own MBeans as a Ruby class.
7
7
 
8
- ## FEATURES/PROBLEMS:
9
-
10
- * Use '-J-Dcom.sun.management.jmxremote' to make jruby process accessible from a jruby command-line
11
-
12
8
  ## SYNOPSIS:
13
9
 
14
10
  Connect to same JVM as client script and look at Memory MBean
15
11
 
12
+ ```ruby
16
13
  require 'jmx'
17
14
 
18
15
  client = JMX.simple_connect(:port => 9999)
19
16
 
20
17
  memory = client["java.lang:type=Memory"]
21
18
  puts memory.attributes
19
+ ```
20
+
21
+ You can also create your own MBeans and register them as well:
22
+
23
+ ```ruby
24
+ require 'jmx'
25
+
26
+ class MyDynamicMBean < RubyDynamicMBean
27
+ rw_attribute :name, :string, "My sample attribute"
28
+ r_attribute :explicit_reader, :int, "Sample int with writer", :my_reader
29
+
30
+ operation "Doubles a value"
31
+ parameter :int, "a", "Value to double"
32
+ returns :int
33
+ def double(a)
34
+ a + a
35
+ end
36
+ end
37
+
38
+ dyna = MyDynamicMBean.new("domain.MySuperBean", "Heh")
39
+ domain = my_server.default_domain
40
+ my_server.register_mbean dyna, "#{@domain}:type=MyDynamicMBean"
41
+ ```
22
42
 
23
43
  ## REQUIREMENTS:
24
44
 
@@ -27,3 +47,8 @@ Connect to same JVM as client script and look at Memory MBean
27
47
  ## INSTALL:
28
48
 
29
49
  * jruby -S gem install jmx
50
+
51
+ ## PROBLEMS:
52
+
53
+ * Use '-J-Dcom.sun.management.jmxremote' to make jruby process accessible from a jruby command-line
54
+
data/lib/jmx.rb CHANGED
@@ -3,44 +3,10 @@ include Java
3
3
  require 'rmi'
4
4
  require 'jmx/dynamic_mbean'
5
5
  require 'jmx/server'
6
-
7
- java_import java.util.ArrayList
8
- java_import javax.management.Attribute
9
- java_import javax.management.MBeanInfo
10
- java_import javax.management.DynamicMBean
11
-
12
- module JMX
13
- java_import javax.management.ObjectName
14
- class ObjectName
15
- def [](key)
16
- get_key_property(key.to_s)
17
- end
18
-
19
- def info(server)
20
- server.getMBeanInfo(self)
21
- end
22
- end
23
- end
24
-
25
- module javax::management::openmbean::CompositeData
26
- include Enumerable
27
-
28
- def [](key)
29
- get(key.to_s)
30
- end
31
-
32
- def method_missing(name, *args)
33
- self[name]
34
- end
35
-
36
- def each
37
- get_composite_type.key_set.each { |key| yield key }
38
- end
39
-
40
- def each_pair
41
- get_composite_type.key_set.each { |key| yield key, get(key) }
42
- end
43
- end
6
+ require 'jmx/object_name'
7
+ require 'jmx/composite_data'
8
+ require 'jmx/mbean_proxy'
9
+ require 'jmx/mbeans'
44
10
 
45
11
  module JMX
46
12
  ##
@@ -74,142 +40,4 @@ module JMX
74
40
  $registry = RMIRegistry.new port
75
41
  @connector = JMX::MBeanServerConnector.new(url, JMX::MBeanServer.new).start
76
42
  end
77
-
78
- # Holder for beans created from retrieval (namespace protection [tm]).
79
- # This also gives MBeans nicer names when inspected
80
- module MBeans
81
- ##
82
- # Create modules in this namespace for each package in the Java fully
83
- # qualified name and return the deepest module along with the Java class
84
- # name back to the caller.
85
- def self.parent_for(java_class_fqn)
86
- java_class_fqn.split(".").inject(MBeans) do |parent, segment|
87
- # const_defined? will crash later if we don't remove $
88
- segment.gsub!('$', 'Dollar') if segment =~ /\$/
89
- # Note: We are boned if java class name is lower cased
90
- return [parent, segment] if segment =~ /^[A-Z]/
91
-
92
- segment.capitalize!
93
- unless parent.const_defined? segment
94
- parent.const_set segment, Module.new
95
- else
96
- parent.const_get segment
97
- end
98
- end
99
-
100
- end
101
- end
102
-
103
- # Create a Ruby proxy based on the MBean represented by the object_name
104
- class MBeanProxy
105
- # Generate a friendly Ruby proxy for the MBean represented by object_name
106
- def self.generate(server, object_name)
107
- parent, class_name = MBeans.parent_for object_name.info(server).class_name
108
-
109
- if parent.const_defined? class_name
110
- proxy = parent.const_get(class_name)
111
- else
112
- proxy = Class.new MBeanProxy
113
- parent.const_set class_name, proxy
114
- end
115
-
116
- proxy.new(server, object_name)
117
- end
118
-
119
- def initialize(server, object_name)
120
- @server, @object_name = server, object_name
121
- @info = @server.getMBeanInfo(@object_name)
122
-
123
- define_attributes
124
- define_operations
125
- end
126
-
127
- def attributes
128
- @attributes ||= @info.attributes.inject([]) { |s,attr| s << attr.name }
129
- end
130
-
131
- def operations
132
- @operations ||= @info.operations.inject([]) { |s,op| s << op.name }
133
- end
134
-
135
- # Get MBean attribute specified by name. If it is just a plain attribute then
136
- # unwrap the attribute and just return the value.
137
- def [](name)
138
- attribute = @server.getAttribute(@object_name, name.to_s)
139
- return attribute.value if attribute.kind_of? javax.management.Attribute
140
- attribute
141
- end
142
-
143
- # Set MBean attribute specified by name to value
144
- def []=(name, value)
145
- @server.setAttribute @object_name, javax.management.Attribute.new(name.to_s, value)
146
- end
147
-
148
- def add_notification_listener(filter=nil, handback=nil, &listener)
149
- @server.addNotificationListener @object_name, listener, filter, handback
150
- end
151
-
152
- def remove_notification_listener(listener)
153
- @server.removeNotificationListener @object_name, listener
154
- end
155
-
156
- private
157
-
158
- # Define ruby friendly methods for attributes. For odd attribute names or names
159
- # that you want to call with the actual attribute name you can call aref/aset
160
- def define_attributes
161
- @info.attributes.each do |attr|
162
- rname = underscore(attr.name)
163
- self.class.__send__(:define_method, rname) { self[attr.name] } if attr.readable?
164
- self.class.__send__(:define_method, rname + "=") {|v| self[attr.name] = v } if attr.writable?
165
- end
166
- end
167
-
168
- def define_operations
169
- @info.operations.each do |op|
170
- self.class.__send__(:define_method, op.name) do |*args|
171
- jargs, jtypes = java_args(op.signature, args)
172
- @server.invoke @object_name, op.name, jargs, jtypes
173
- end
174
- end
175
- end
176
-
177
- # Given the signature and the parameters supplied do these signatures match.
178
- # Repackage these parameters as Java objects in a primitive object array.
179
- def java_args(signature, params)
180
- return nil if params.nil?
181
-
182
- jtypes = []
183
- jargs = []
184
- params.each_with_index do |param, i|
185
- type = signature[i].get_type
186
- jtypes << type
187
- required_type = JavaClass.for_name(type)
188
-
189
- java_arg = param.to_java(:object)
190
-
191
- if (param.kind_of? Array)
192
- java_arg = param.inject(ArrayList.new) {|l, element| l << element }
193
- end
194
-
195
- jargs << java_arg
196
-
197
- arg_type = java_arg.java_class
198
-
199
- raise TypeError.new("parameter #{signature[i].name} expected to be #{required_type}, but was #{arg_type}") if !required_type.assignable_from? arg_type
200
- end
201
- [jargs.to_java, jtypes.to_java(:string)]
202
- end
203
-
204
- # Convert a collection of java objects to their Java class name equivalents
205
- def java_types(params)
206
- return nil if params.nil?
207
-
208
- params.map {|e| e.class.java_class.name }.to_java(:string)
209
- end
210
-
211
- def underscore(string)
212
- string.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase
213
- end
214
- end
215
43
  end
@@ -0,0 +1,21 @@
1
+ require 'java'
2
+
3
+ module javax::management::openmbean::CompositeData
4
+ include Enumerable
5
+
6
+ def [](key)
7
+ get(key.to_s)
8
+ end
9
+
10
+ def method_missing(name, *args)
11
+ self[name]
12
+ end
13
+
14
+ def each
15
+ get_composite_type.key_set.each { |key| yield key }
16
+ end
17
+
18
+ def each_pair
19
+ get_composite_type.key_set.each { |key| yield key, get(key) }
20
+ end
21
+ end
@@ -0,0 +1,164 @@
1
+ require 'java'
2
+
3
+ java_import java.util.ArrayList
4
+
5
+ module JMX
6
+ ##
7
+ # Create a Ruby proxy based on the MBean represented by the object_name
8
+ # This proxy will be able to dispatch to the actual MBean to allow it to
9
+ # execute operations and read/update attributes. The primary mechanism
10
+ # for calling attributes or operations is to just call them as if they
11
+ # represented methods on the MBean. For example:
12
+ #
13
+ # memory = client["java.lang:type=Memory"]
14
+ # memory.gc
15
+ # memory.heap_memory_usage.used
16
+ #
17
+ # Here we first call an operation on this Memory heap called 'gc' and then
18
+ # we access an attribute 'heap_memory_usage' (Note: we can use snake-cased
19
+ # naming instead of actual 'HeapMemoryUsage'). In the case of a naming
20
+ # conflict (existing Ruby method, or same-named attribute as MBean operation),
21
+ # there there are long hand mechanisms:
22
+ #
23
+ # memory = client["java.lang:type=Memory"]
24
+ # memory.invoke(:gc)
25
+ # memory[:heap_memory_usage][:used]
26
+ #
27
+ class MBeanProxy
28
+ # Generate a friendly Ruby proxy for the MBean represented by object_name
29
+ def self.generate(server, object_name)
30
+ parent, class_name = MBeans.parent_for object_name.info(server).class_name
31
+
32
+ if parent.const_defined? class_name
33
+ proxy = parent.const_get(class_name)
34
+ else
35
+ proxy = Class.new MBeanProxy
36
+ parent.const_set class_name, proxy
37
+ end
38
+
39
+ proxy.new(server, object_name)
40
+ end
41
+
42
+ def initialize(server, object_name)
43
+ @server, @object_name = server, object_name
44
+ @info = @server.getMBeanInfo(@object_name)
45
+
46
+ define_attributes
47
+ define_operations
48
+ end
49
+
50
+ def attributes
51
+ @attributes ||= @info.attributes.inject([]) { |s,attr| s << attr.name }
52
+ end
53
+
54
+ def operations
55
+ @operations ||= @info.operations.inject([]) { |s,op| s << op.name }
56
+ end
57
+
58
+ ##
59
+ # Get MBean attribute specified by name. If it is just a plain attribute
60
+ # then unwrap the attribute and just return the value.
61
+ def [](name)
62
+ attribute = @server.getAttribute(@object_name, name.to_s)
63
+ return attribute.value if attribute.kind_of? javax.management.Attribute
64
+ attribute
65
+ end
66
+
67
+ ##
68
+ # Set MBean attribute specified by name to value
69
+ def []=(name, value)
70
+ @server.setAttribute @object_name, javax.management.Attribute.new(name.to_s, value)
71
+ end
72
+
73
+ ##
74
+ # Invoke an operation. A NoMethodError will be thrown if this MBean
75
+ # cannot respond to the operation.
76
+ #
77
+ # FIXME: Add scoring to pick best match instead of first found
78
+ def invoke(name, *params)
79
+ op = @info.operations.find { |o| o.name == name.to_s }
80
+
81
+ raise NoMethodError.new("No such operation #{name}") unless op
82
+
83
+ jargs, jtypes = java_args(op.signature, params)
84
+ @server.invoke @object_name, op.name, jargs, jtypes
85
+ end
86
+
87
+ def add_notification_listener(filter=nil, handback=nil, &listener)
88
+ @server.addNotificationListener @object_name, listener, filter, handback
89
+ end
90
+
91
+ def remove_notification_listener(listener)
92
+ @server.removeNotificationListener @object_name, listener
93
+ end
94
+
95
+ private
96
+
97
+ # Define ruby friendly methods for attributes. For odd attribute names or
98
+ # names that you want to call with the actual attribute name you can call
99
+ # aref/aset ([], []=).
100
+ def define_attributes
101
+ @info.attributes.each do |attr|
102
+ rname = underscore(attr.name)
103
+ self.class.__send__(:define_method, rname) { self[attr.name] } if attr.readable?
104
+ self.class.__send__(:define_method, rname + "=") {|v| self[attr.name] = v } if attr.writable?
105
+ end
106
+ end
107
+
108
+ # Define ruby friendly methods for operations. For name conflicts you
109
+ # should call 'invoke(op_name, *args)'
110
+ def define_operations
111
+ @info.operations.each do |op|
112
+ self.class.__send__(:define_method, op.name) do |*params|
113
+ jargs, jtypes = java_args(op.signature, params)
114
+ @server.invoke @object_name, op.name, jargs, jtypes
115
+ end
116
+ end
117
+ end
118
+
119
+ PRIMITIVE_JAVA_TYPES = {
120
+ 'int' => Java::java.lang.Integer,
121
+ 'short' => Java::java.lang.Short,
122
+ 'float' => Java::java.lang.Float,
123
+ 'boolean' => Java::java.lang.Boolean
124
+ }
125
+
126
+ # Given the signature and the parameters supplied do these signatures match.
127
+ # Repackage these parameters as Java objects in a primitive object array.
128
+ def java_args(signature, params)
129
+ return nil if params.nil?
130
+
131
+ jtypes = []
132
+ jargs = []
133
+ params.each_with_index do |param, i|
134
+ type = signature[i].get_type
135
+ jtypes << type
136
+ required_type = JavaClass.for_name(type)
137
+ java_type = PRIMITIVE_JAVA_TYPES[required_type.name] || :object
138
+ java_arg = param.to_java(java_type)
139
+
140
+ if (param.kind_of? Array)
141
+ java_arg = param.inject(ArrayList.new) {|l, element| l << element }
142
+ end
143
+
144
+ jargs << java_arg
145
+
146
+ arg_type = java_arg.java_class
147
+
148
+ raise TypeError.new("parameter #{signature[i].name} expected to be #{required_type}, but was #{arg_type}") if !required_type.assignable_from? arg_type
149
+ end
150
+ [jargs.to_java, jtypes.to_java(:string)]
151
+ end
152
+
153
+ # Convert a collection of java objects to their Java class name equivalents
154
+ def java_types(params)
155
+ return nil if params.nil?
156
+
157
+ params.map {|e| e.class.java_class.name }.to_java(:string)
158
+ end
159
+
160
+ def underscore(string)
161
+ string.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,28 @@
1
+ require 'java'
2
+
3
+ module JMX
4
+ # Holder for beans created from retrieval (namespace protection [tm]).
5
+ # This also gives MBeans nicer names when inspected
6
+ module MBeans
7
+ ##
8
+ # Create modules in this namespace for each package in the Java fully
9
+ # qualified name and return the deepest module along with the Java class
10
+ # name back to the caller.
11
+ def self.parent_for(java_class_fqn)
12
+ java_class_fqn.split(".").inject(MBeans) do |parent, segment|
13
+ # const_defined? will crash later if we don't remove $
14
+ segment.gsub!('$', 'Dollar') if segment =~ /\$/
15
+ # Note: We are boned if java class name is lower cased
16
+ return [parent, segment] if segment =~ /^[A-Z]/
17
+
18
+ segment.capitalize!
19
+ unless parent.const_defined? segment
20
+ parent.const_set segment, Module.new
21
+ else
22
+ parent.const_get segment
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+ module JMX
2
+ module RubyNotificationEmitter
3
+ java_import javax.management.MBeanNotificationInfo
4
+
5
+ include javax.management.NotificationEmitter
6
+
7
+ def listeners
8
+ @listener ||= {}
9
+ end
10
+
11
+ # NotificationListener listener, NotificationFilter filter, Object handback
12
+ def addNotificationListener(listener, filter, handback)
13
+ listeners[listener] = [filter, handback]
14
+ end
15
+
16
+ def getNotificationInfo
17
+ [].to_java MBeanNotificationInfo
18
+ end
19
+
20
+ # NotificationListener listener, NotificationFilter filter, Object handback
21
+ def removeNotificationListener(listener, filter=nil, handback=nil)
22
+ found = false
23
+ listeners.delete_if do |clistener, (cfilter, chandback)|
24
+ v = listener == clistener && filter == cfilter && handback == chandback
25
+ found = true if v
26
+ v
27
+ end
28
+ raise javax.management.ListenerNotFoundException.new unless found
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,22 @@
1
+ require 'java'
2
+ java_import javax.management.ObjectName
3
+
4
+ class ObjectName
5
+ def [](key)
6
+ get_key_property(key.to_s)
7
+ end
8
+
9
+ def info(server)
10
+ server.getMBeanInfo(self)
11
+ end
12
+
13
+ ##
14
+ # Make a new ObjectName unless it is already one
15
+ def self.make(name)
16
+ return name if name.kind_of? ObjectName
17
+
18
+ ObjectName.new name
19
+ rescue Exception
20
+ raise ArgumentError.new("Invalid ObjectName #{$!.message}")
21
+ end
22
+ end
@@ -1,3 +1,5 @@
1
+ require 'jmx/object_name'
2
+
1
3
  module JMX
2
4
  # The MBeanServer represents a connection to an MBean server
3
5
  # rather than an actual MBean server. Depending upon how
@@ -33,7 +35,7 @@ module JMX
33
35
  end
34
36
 
35
37
  def [](object_name)
36
- name = make_object_name object_name
38
+ name = ObjectName.make object_name
37
39
 
38
40
  unless @server.isRegistered(name)
39
41
  raise NoSuchBeanError.new("No name: #{object_name}")
@@ -45,7 +47,7 @@ module JMX
45
47
  end
46
48
 
47
49
  def []=(class_name, object_name)
48
- name = make_object_name object_name
50
+ name = ObjectName.make object_name
49
51
 
50
52
  @server.createMBean class_name, name, nil, nil
51
53
 
@@ -65,19 +67,17 @@ module JMX
65
67
  end
66
68
 
67
69
  def query_names(name=nil, query=nil)
68
- object_name = name.nil? ? nil : make_object_name(name)
70
+ object_name = name.nil? ? nil : ObjectName.make(name)
69
71
 
70
72
  @server.query_names(object_name, query)
71
73
  end
72
74
 
73
75
  def unregister_mbean(object_name)
74
- name = make_object_name object_name
75
- @server.unregisterMBean(name)
76
-
76
+ @server.unregisterMBean(ObjectName.make(object_name))
77
77
  end
78
78
 
79
79
  def register_mbean(object, object_name)
80
- name = make_object_name object_name
80
+ name = ObjectName.make(object_name)
81
81
  @server.registerMBean(object, name)
82
82
  MBeanProxy.generate(@server, name)
83
83
  end
@@ -85,16 +85,6 @@ module JMX
85
85
  def self.find(agent_id=nil)
86
86
  MBeanServerFactory.findMBeanServer(agent_id)
87
87
  end
88
-
89
- private
90
-
91
- def make_object_name(object_name)
92
- return object_name if object_name.kind_of? ObjectName
93
-
94
- ObjectName.new object_name
95
- rescue Exception
96
- raise ArgumentError.new("Invalid ObjectName #{$!.message}")
97
- end
98
88
  end
99
89
 
100
90
  class NoSuchBeanError < RuntimeError
@@ -0,0 +1,15 @@
1
+ module JMX
2
+ module StringUtils
3
+ def snakecase(string)
4
+ string.to_s.gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase
5
+ end
6
+
7
+ def camelcase(string)
8
+ if string =~ /_/
9
+ string.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }
10
+ else
11
+ string.to_s
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module JMX
2
- VERSION = "0.8"
2
+ VERSION = "0.9"
3
3
  end
@@ -71,6 +71,23 @@ class JMXConnectorClientTest < Test::Unit::TestCase
71
71
 
72
72
  assert(heap1.to_i >= heap2.to_i, "GC did not collect")
73
73
  end
74
+
75
+ def test_simple_operation
76
+ memory = @client["java.lang:type=Memory"]
77
+
78
+ heap1 = memory[:HeapMemoryUsage][:used]
79
+ memory.invoke(:gc)
80
+ heap2 = memory[:HeapMemoryUsage][:used]
81
+
82
+ assert(heap1.to_i >= heap2.to_i, "GC did not collect")
83
+ end
84
+
85
+ def test_primitive_return_operation
86
+ threading = @client["java.lang:type=Threading"]
87
+ a_thread_id = threading[:AllThreadIds][0]
88
+
89
+ assert_not_nil threading.getThreadCpuTime(a_thread_id)
90
+ end
74
91
 
75
92
  def test_query_names
76
93
  names = @client.query_names("java.lang:type=MemoryPool,*")
metadata CHANGED
@@ -1,83 +1,106 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: jmx
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 8
8
- version: "0.8"
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: '0.9'
9
6
  platform: ruby
10
- authors:
7
+ authors:
11
8
  - Thomas E. Enebo
12
- autorequire:
9
+ autorequire:
13
10
  bindir: bin
14
11
  cert_chain: []
15
-
16
- date: 2012-04-20 00:00:00 -05:00
17
- default_executable:
12
+ date: 2012-06-11 00:00:00.000000000 Z
18
13
  dependencies: []
19
-
20
14
  description: Access and create MBeans in a friendly Ruby syntax
21
15
  email: tom.enebo@gmail.com
22
16
  executables: []
23
-
24
17
  extensions: []
25
-
26
18
  extra_rdoc_files: []
27
-
28
- files:
29
- - .gitignore
30
- - History.txt
31
- - LICENSE.txt
32
- - Manifest.txt
33
- - README.md
34
- - Rakefile
35
- - jmx.gemspec
36
- - lib/jmx.rb
37
- - lib/jmx/dynamic_mbean.rb
38
- - lib/jmx/server.rb
39
- - lib/jmx/version.rb
40
- - lib/rmi.rb
41
- - nbproject/private/private.xml
42
- - nbproject/project.properties
43
- - nbproject/project.xml
44
- - samples/memory.rb
45
- - test/jmx_attribute_test.rb
46
- - test/jmx_client_test.rb
47
- - test/jmx_mangling_test.rb
48
- - test/jmx_server_test.rb
49
- has_rdoc: true
19
+ files:
20
+ - !binary |-
21
+ LmdpdGlnbm9yZQ==
22
+ - !binary |-
23
+ SGlzdG9yeS50eHQ=
24
+ - !binary |-
25
+ TElDRU5TRS50eHQ=
26
+ - !binary |-
27
+ TWFuaWZlc3QudHh0
28
+ - !binary |-
29
+ UkVBRE1FLm1k
30
+ - !binary |-
31
+ UmFrZWZpbGU=
32
+ - !binary |-
33
+ am14LmdlbXNwZWM=
34
+ - !binary |-
35
+ bGliL2pteC5yYg==
36
+ - !binary |-
37
+ bGliL2pteC9jb21wb3NpdGVfZGF0YS5yYg==
38
+ - !binary |-
39
+ bGliL2pteC9keW5hbWljX21iZWFuLnJi
40
+ - !binary |-
41
+ bGliL2pteC9tYmVhbl9wcm94eS5yYg==
42
+ - !binary |-
43
+ bGliL2pteC9tYmVhbnMucmI=
44
+ - !binary |-
45
+ bGliL2pteC9ub3RpZmllci5yYg==
46
+ - !binary |-
47
+ bGliL2pteC9vYmplY3RfbmFtZS5yYg==
48
+ - !binary |-
49
+ bGliL2pteC9zZXJ2ZXIucmI=
50
+ - !binary |-
51
+ bGliL2pteC91dGlsL3N0cmluZ191dGlscy5yYg==
52
+ - !binary |-
53
+ bGliL2pteC92ZXJzaW9uLnJi
54
+ - !binary |-
55
+ bGliL3JtaS5yYg==
56
+ - !binary |-
57
+ bmJwcm9qZWN0L3ByaXZhdGUvcHJpdmF0ZS54bWw=
58
+ - !binary |-
59
+ bmJwcm9qZWN0L3Byb2plY3QucHJvcGVydGllcw==
60
+ - !binary |-
61
+ bmJwcm9qZWN0L3Byb2plY3QueG1s
62
+ - !binary |-
63
+ c2FtcGxlcy9tZW1vcnkucmI=
64
+ - !binary |-
65
+ dGVzdC9qbXhfYXR0cmlidXRlX3Rlc3QucmI=
66
+ - !binary |-
67
+ dGVzdC9qbXhfY2xpZW50X3Rlc3QucmI=
68
+ - !binary |-
69
+ dGVzdC9qbXhfbWFuZ2xpbmdfdGVzdC5yYg==
70
+ - !binary |-
71
+ dGVzdC9qbXhfc2VydmVyX3Rlc3QucmI=
50
72
  homepage: http://github.com/enebo/jmx
51
73
  licenses: []
52
-
53
- post_install_message:
74
+ post_install_message:
54
75
  rdoc_options: []
55
-
56
- require_paths:
76
+ require_paths:
57
77
  - lib
58
- required_ruby_version: !ruby/object:Gem::Requirement
59
- requirements:
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- segments:
63
- - 0
64
- version: "0"
65
- required_rubygems_version: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- segments:
70
- - 0
71
- version: "0"
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: !binary |-
83
+ MA==
84
+ none: false
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: !binary |-
90
+ MA==
91
+ none: false
72
92
  requirements: []
73
-
74
93
  rubyforge_project: jmx
75
- rubygems_version: 1.3.6
76
- signing_key:
94
+ rubygems_version: 1.8.24
95
+ signing_key:
77
96
  specification_version: 3
78
97
  summary: Access and create MBeans in a friendly Ruby syntax
79
- test_files:
80
- - test/jmx_attribute_test.rb
81
- - test/jmx_client_test.rb
82
- - test/jmx_mangling_test.rb
83
- - test/jmx_server_test.rb
98
+ test_files:
99
+ - !binary |-
100
+ dGVzdC9qbXhfYXR0cmlidXRlX3Rlc3QucmI=
101
+ - !binary |-
102
+ dGVzdC9qbXhfY2xpZW50X3Rlc3QucmI=
103
+ - !binary |-
104
+ dGVzdC9qbXhfbWFuZ2xpbmdfdGVzdC5yYg==
105
+ - !binary |-
106
+ dGVzdC9qbXhfc2VydmVyX3Rlc3QucmI=