jmx 0.8 → 0.9

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.
@@ -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=