javaobj 0.1

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/install.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'rbconfig'
2
+ require 'find'
3
+ require 'ftools'
4
+
5
+ include Config
6
+
7
+ $ruby = CONFIG['ruby_install_name']
8
+
9
+ $sitedir = CONFIG["sitelibdir"]
10
+ unless $sitedir
11
+ version = CONFIG["MAJOR"]+"."+CONFIG["MINOR"]
12
+ $libdir = File.join(CONFIG["libdir"], "ruby", version)
13
+ $sitedir = $:.find {|x| x =~ /site_ruby/}
14
+ if !$sitedir
15
+ $sitedir = File.join($libdir, "site_ruby")
16
+ elsif $sitedir !~ Regexp.quote(version)
17
+ $sitedir = File.join($sitedir, version)
18
+ end
19
+ end
20
+
21
+ if (destdir = ENV['DESTDIR'])
22
+ $sitedir = destdir + $sitedir
23
+ File::makedirs($sitedir)
24
+ end
25
+
26
+ rake_dest = File.join($sitedir, "rake")
27
+ File::makedirs(rake_dest, true)
28
+ File::chmod(0755, rake_dest)
29
+
30
+ # The library files
31
+
32
+ files = Dir.chdir('lib') { Dir['**/*.rb'] }
33
+
34
+ for fn in files
35
+ fn_dir = File.dirname(fn)
36
+ target_dir = File.join($sitedir, fn_dir)
37
+ if ! File.exist?(target_dir)
38
+ File.makedirs(target_dir)
39
+ end
40
+ File::install(File.join('lib', fn), File.join($sitedir, fn), 0644, true)
41
+ end
42
+
data/lib/javaobs.rb ADDED
@@ -0,0 +1,502 @@
1
+
2
+ require 'delegate'
3
+
4
+ module Java
5
+ class JavaField
6
+ attr_reader :name, :type
7
+ attr_accessor :subtype
8
+
9
+ def initialize(name, type)
10
+ @name = name
11
+ @type = type
12
+ @subtype = nil
13
+ end
14
+
15
+ def inspect
16
+ "<JavaField: #{@name}:#{@type.chr}:#{@subtype}>"
17
+ end
18
+ end
19
+
20
+ class JavaClass
21
+ attr_accessor :superClass, :rubyClass
22
+ attr_reader :name, :uid, :fields, :javaName, :flags, :arrayType
23
+
24
+ def initialize(name, uid, flags)
25
+ @name = @javaName = name
26
+ ind = name.rindex('.')
27
+ @name = name.slice(ind + 1..name.length) if ind
28
+ @flags = flags
29
+ @uid = uid
30
+ @fields = []
31
+ @arrayType = name[1] if name[0] == ?[
32
+ end
33
+
34
+ def addField(field)
35
+ @fields << field
36
+ end
37
+
38
+ def to_s
39
+ @name
40
+ end
41
+ end
42
+
43
+ module JavaObject
44
+ def javaClass
45
+ @javaClass
46
+ end
47
+ end
48
+
49
+ class Date < SimpleDelegator
50
+ extend JavaObject
51
+
52
+ def initialize
53
+ super(Time)
54
+ end
55
+
56
+ def time=(time)
57
+ case time
58
+ when Time
59
+ __setobj__(time)
60
+
61
+ when String
62
+ t, = time.unpack("Q")
63
+ __setobj__(Time.at(t / 1000, (t % 1000) * 1000))
64
+ end
65
+ end
66
+
67
+ def data
68
+ t = __getobj__.tv_sec * 1000 + __getobj__.tv_usec / 1000
69
+ [t].pack("Q")
70
+ end
71
+ end
72
+
73
+ class JavaArray < Array
74
+ extend JavaObject
75
+ end
76
+
77
+ module ObjectStream
78
+ STREAM_MAGIC = 0xACED
79
+ STREAM_VERSION = 5
80
+
81
+ TC_NULL = 0x70
82
+ TC_REFERENCE = 0x71
83
+ TC_CLASSDESC = 0x72
84
+ TC_OBJECT = 0x73
85
+ TC_STRING = 0x74
86
+ TC_ARRAY = 0x75
87
+ TC_CLASS = 0x76
88
+ TC_BLOCKDATA = 0x77
89
+ TC_ENDBLOCKDATA = 0x78
90
+ TC_RESET = 0x79
91
+ TC_BLOCKDATALONG = 0x7A
92
+ TC_EXCEPTION = 0x7B
93
+ TC_LONGSTRING = 0x7C
94
+ TC_PROXYCLASSDESC = 0x7D
95
+
96
+ SC_WRITE_METHOD = 0x01
97
+ SC_SERIALIZABLE = 0x02
98
+ SC_EXTERNALIZABLE = 0x04
99
+ SC_BLOCKDATA = 0x08
100
+
101
+ PRIM_BYTE = 66 # 'B'
102
+ PRIM_CHAR = 67 # 'C'
103
+ PRIM_DOUBLE = 68 # 'D'
104
+ PRIM_FLOAT = 70 # 'F'
105
+ PRIM_INT = 73 # 'I'
106
+ PRIM_LONG = 74 # 'J'
107
+ PRIM_SHORT = 83 # 'S'
108
+ PRIM_BOOL = 90 # 'Z'
109
+
110
+ PRIM_ARRAY = 91 # '['
111
+ PRIM_OBJECT = 76 # 'L'
112
+ end
113
+
114
+ class ObjectInputStream
115
+ include ObjectStream
116
+
117
+ def readByte; @str.read(1)[0]; end
118
+ def readUShort; @str.read(2).unpack("n")[0]; end
119
+ def readShort; @str.read(2).unpack("s")[0]; end
120
+ def readInt; @str.read(4).unpack("i")[0]; end
121
+ def readDouble; @str.read(8).unpack("G")[0]; end
122
+ def readFloat; @str.read(4).unpack("g")[0]; end
123
+ def readString; @str.read(readShort); end
124
+ def readBool; @str.read(1)[0] != 0; end
125
+ def readUID; @str.read(8); end
126
+ def readLong; @str.read(8).unpack("Q").first; end
127
+
128
+ def readBlockData
129
+ byte = readByte
130
+ size = nil
131
+ case byte
132
+ when TC_BLOCKDATA
133
+ size = readByte
134
+
135
+ when TC_BLOCKDATALONG
136
+ size = readInt
137
+
138
+ else
139
+ raise "Expecting TC_BLOCKDATA" unless byte == TC_BLOCKDATA
140
+ end
141
+
142
+ data = @str.read(size)
143
+ byte = readByte
144
+ raise "Unexpected byte #{byte}" unless byte == TC_ENDBLOCKDATA
145
+ data
146
+ end
147
+
148
+ def readFields(klass)
149
+ fieldCount = readShort
150
+ 1.upto(fieldCount) do
151
+ type = readByte
152
+ name = readString
153
+ field = JavaField.new(name, type)
154
+
155
+ # Check for array and object types
156
+ if type == PRIM_OBJECT || type == PRIM_ARRAY
157
+ field.subtype = readObject
158
+ end
159
+ klass.addField(field)
160
+ end
161
+ end
162
+
163
+ def readClassAnnotation
164
+ ebd = readByte
165
+ raise "We do not handle annotations!" unless ebd == TC_ENDBLOCKDATA
166
+ end
167
+
168
+ def readClassDesc
169
+ name = readString
170
+ uid = readUID
171
+ flags = readByte
172
+ klass = JavaClass.new(name, uid, flags)
173
+
174
+ @objects << klass
175
+
176
+ readFields(klass)
177
+ readClassAnnotation
178
+
179
+ klass.superClass = readObject
180
+
181
+ # Create Ruby object representing class
182
+ if name == 'java.util.Date'
183
+ rclass = Java::Date
184
+ rclass.class_eval "@javaClass = klass"
185
+ klass.rubyClass = rclass
186
+ elsif name =~ /^[A-Z.]+/i
187
+ unless Java.constants.index(klass.name)
188
+ rclass = Java.module_eval "#{klass.name} = Class.new(#{klass.superClass.to_s})"
189
+ else
190
+ rclass = Java.const_get(klass.name)
191
+ end
192
+
193
+ unless rclass.methods.index('javaClass')
194
+ rclass.class_eval "extend JavaObject"
195
+ end
196
+
197
+ rclass.class_eval "@javaClass = klass"
198
+ vars = klass.fields.map do |f|
199
+ ':' + f.name
200
+ end
201
+ rclass.class_eval "attr_accessor #{vars.join(',')}"
202
+ klass.rubyClass = rclass
203
+ else
204
+ # Arrays
205
+ newName = 'JavaArray' + klass.name[1..klass.name.length]
206
+ unless Java.constants.index(newName)
207
+ rclass = Java.module_eval "#{newName} = Class.new(JavaArray)"
208
+ else
209
+ rclass = Java.const_get(newName)
210
+ end
211
+ rclass.class_eval "@javaClass = klass"
212
+ klass.rubyClass = rclass
213
+ end
214
+
215
+ klass
216
+ end
217
+
218
+ def readArray(klass)
219
+ size = readInt
220
+ a = klass.rubyClass.new
221
+ type = klass.arrayType
222
+ 1.upto(size) do
223
+ a << readType(type)
224
+ end
225
+ a
226
+ end
227
+
228
+ def readType(type, arrayType = nil, field = nil)
229
+ case type
230
+ when PRIM_BYTE
231
+ readByte
232
+
233
+ when PRIM_CHAR
234
+ readByte
235
+
236
+ when PRIM_DOUBLE
237
+ readDouble
238
+
239
+ when PRIM_FLOAT
240
+ readFloat
241
+
242
+ when PRIM_INT
243
+ readInt
244
+
245
+ when PRIM_LONG
246
+ readLong
247
+
248
+ when PRIM_SHORT
249
+ readShort
250
+
251
+ when PRIM_BOOL
252
+ readBool
253
+
254
+ when PRIM_OBJECT, PRIM_ARRAY
255
+ readObject
256
+
257
+ else
258
+ raise "Unknown type #{type}"
259
+ end
260
+ end
261
+
262
+ def readClassData(klass, object = nil)
263
+ # Handle special case for Date
264
+ if object == nil
265
+ if (klass.javaName == 'java.util.Date')
266
+ object = Java::Date.new
267
+ else
268
+ object = klass.rubyClass.new()
269
+ end
270
+ @objects << object
271
+ end
272
+
273
+ readClassData(klass.superClass, object) if (klass.superClass)
274
+
275
+ if klass.flags == SC_SERIALIZABLE
276
+ klass.fields.each do |f|
277
+ v = readType(f.type, f.subtype, f)
278
+ object.send((f.name + '=').intern, v)
279
+ end
280
+ else
281
+ data = readBlockData
282
+ object.time = data
283
+ end
284
+
285
+ object
286
+ end
287
+
288
+ def readObject
289
+ object = nil
290
+ byte = readByte
291
+ case byte
292
+ when TC_OBJECT
293
+ klass = readObject
294
+ object = readClassData(klass)
295
+
296
+ when TC_REFERENCE
297
+ readShort
298
+ object = @objects[readShort]
299
+
300
+ when TC_ARRAY
301
+ klass = readObject
302
+ object = readArray(klass)
303
+ @objects << object
304
+
305
+ when TC_STRING
306
+ object = readString
307
+ @objects << object
308
+
309
+ when TC_CLASSDESC
310
+ object = readClassDesc
311
+
312
+ when TC_NULL
313
+ object = nil
314
+
315
+ else
316
+ raise "Unexpected byte #{byte} at #{@str.pos}"
317
+ end
318
+
319
+ object
320
+ end
321
+
322
+ def initialize(str)
323
+ @str = str
324
+ magic = readUShort
325
+ streamVersion = readShort
326
+ @objects = []
327
+
328
+ raise "Bad stream #{magic.to_s(16)}:#{streamVersion.to_s(16)}" if magic != STREAM_MAGIC ||
329
+ streamVersion != STREAM_VERSION
330
+
331
+ end
332
+
333
+ def readObjects
334
+ objs = []
335
+ until (@str.eof)
336
+ objs << readObject
337
+ end
338
+ objs
339
+ end
340
+ end
341
+
342
+ class ObjectOutputStream
343
+ include ObjectStream
344
+
345
+ def writeByte(b); @str.putc b; end
346
+ def writeUShort(s); @str.write [s].pack("n"); end
347
+ def writeShort(s); @str.write [s].pack("s"); end
348
+ def writeInt(i); @str.write [i].pack("i"); end
349
+ def writeDouble(d); @str.write [d].pack("G"); end
350
+ def writeFloat(f); @str.write [f].pack("g"); end
351
+ def writeString(s); writeShort(s.length); @str.write s; end
352
+ def writeBool(b); writeByte(b ? 1 : 0); end
353
+ def writeUID(u); @str.write u; end
354
+ def writeLong(l); @str.write [l].pack("Q"); end
355
+
356
+ def nextHandle
357
+ h = @nextHandle
358
+ @nextHandle += 1
359
+ h
360
+ end
361
+
362
+ def writeArray(klass, v)
363
+ type = klass.arrayType
364
+ writeInt(v.length)
365
+ v.each do |e|
366
+ writeType(type, e)
367
+ end
368
+ end
369
+
370
+ def writeBlockData(data)
371
+ if (data.length <= 255)
372
+ writeByte(TC_BLOCKDATA)
373
+ writeByte(data.length)
374
+ else
375
+ writeByte(TC_BLOCKDATALONG)
376
+ writeInt(data.length)
377
+ end
378
+
379
+ @str.write data
380
+ writeByte(TC_ENDBLOCKDATA)
381
+ end
382
+
383
+ def writeType(type, v)
384
+ case type
385
+ when PRIM_BYTE
386
+ writeByte(v)
387
+
388
+ when PRIM_CHAR
389
+ writeByte(v)
390
+
391
+ when PRIM_DOUBLE
392
+ writeDouble(v)
393
+
394
+ when PRIM_FLOAT
395
+ writeFloat(v)
396
+
397
+ when PRIM_INT
398
+ writeInt(v)
399
+
400
+ when PRIM_LONG
401
+ writeLong(v)
402
+
403
+ when PRIM_SHORT
404
+ writeShort(v)
405
+
406
+ when PRIM_BOOL
407
+ writeBool(v)
408
+
409
+ when PRIM_OBJECT, PRIM_ARRAY
410
+ writeObject(v)
411
+
412
+ else
413
+ raise "Unknown type #{type}"
414
+ end
415
+ end
416
+
417
+ def writeClassDesc(klass)
418
+ @handles[klass] = nextHandle
419
+
420
+ writeString klass.javaName
421
+ writeUID klass.uid
422
+ writeByte klass.flags
423
+
424
+ writeShort(klass.fields.length)
425
+ klass.fields.each do |f|
426
+ writeByte(f.type)
427
+ writeString(f.name)
428
+ writeObject(f.subtype) if f.subtype
429
+ end
430
+
431
+ writeByte(TC_ENDBLOCKDATA) # Annotations
432
+ writeObject(klass.superClass)
433
+ end
434
+
435
+ def writeObjectData(klass, obj)
436
+ writeObjectData(klass.superClass, obj) if klass.superClass
437
+
438
+ if klass.flags == SC_SERIALIZABLE
439
+ klass.fields.each do |f|
440
+ v = obj.send(f.name.intern)
441
+ writeType(f.type, v)
442
+ end
443
+ else
444
+ writeBlockData(obj.data)
445
+ end
446
+ end
447
+
448
+ def writeObject(obj)
449
+ unless obj
450
+ writeByte(TC_NULL)
451
+ else
452
+ handle = @handles[obj]
453
+ if (handle)
454
+ writeByte(TC_REFERENCE)
455
+ writeShort(0x007E)
456
+ writeShort(handle)
457
+ else
458
+ case obj
459
+ when JavaClass
460
+ writeByte(TC_CLASSDESC)
461
+ writeClassDesc(obj)
462
+
463
+ when JavaArray
464
+ writeByte(TC_ARRAY)
465
+ writeObject(obj.class.javaClass)
466
+ writeArray(obj.class.javaClass, obj)
467
+ @handles[obj] = nextHandle
468
+
469
+ when String
470
+ writeByte(TC_STRING)
471
+ writeString(obj)
472
+ @handles[obj] = nextHandle
473
+
474
+ else
475
+ writeByte(TC_OBJECT)
476
+ klass = obj.class.javaClass
477
+ writeObject(klass)
478
+ @handles[obj] = nextHandle
479
+ writeObjectData(klass, obj)
480
+
481
+ end
482
+ end
483
+ end
484
+ end
485
+
486
+ def writeObjects(objs)
487
+ objs.each do |o|
488
+ writeObject o
489
+ end
490
+ end
491
+
492
+ def initialize(str)
493
+ @str = str
494
+ @handles = {}
495
+ @nextHandle = 0
496
+
497
+ writeUShort(STREAM_MAGIC)
498
+ writeShort(STREAM_VERSION)
499
+ end
500
+ end
501
+ end
502
+
data/rakefile ADDED
@@ -0,0 +1,64 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/contrib/rubyforgepublisher'
8
+
9
+ PKG_BUILD = '1'
10
+ PKG_NAME = 'javaobj'
11
+ PKG_VERSION = '0.1'
12
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
13
+
14
+ RELEASE_NAME = "REL #{PKG_VERSION}"
15
+ RUBY_FORGE_PROJECT = "javaobj"
16
+ RUBY_FORGE_USER = "wsobel"
17
+
18
+ desc "Default Task"
19
+ task :default => [ :test ]
20
+
21
+ Rake::TestTask.new do |t|
22
+ t.libs << "test"
23
+ t.test_files = Dir.glob( "test/test.rb" )
24
+ t.verbose = true
25
+ end
26
+
27
+ Rake::RDocTask.new do |rdoc|
28
+ rdoc.rdoc_dir = 'doc'
29
+ rdoc.title = "Java Objects"
30
+ rdoc.options << '--line-numbers' << '--inline-source'
31
+ rdoc.template = "#{ENV['template']}.rb" if ENV['template']
32
+ rdoc.rdoc_files.include('lib/**/*.rb')
33
+ end
34
+
35
+ dist_dirs = [ "lib", "test", "examples" ]
36
+
37
+ spec = Gem::Specification.new do |s|
38
+ s.platform = Gem::Platform::RUBY
39
+ s.name = PKG_NAME
40
+ s.version = PKG_VERSION
41
+ s.summary = "Decode Java Serialized Objects to Ruby Objects."
42
+ s.description = %q{Takes Java serialized objects in a file or stream and creates Ruby wrapper objects and decodes. The package can also write Java objects once UUID is read from sample.}
43
+
44
+ s.author = "William Sobel"
45
+ s.email = "willsobel@mac.com"
46
+ s.rubyforge_project = "javaobj"
47
+ s.homepage = "http://www.rubyforge.org"
48
+
49
+ s.has_rdoc = true
50
+ s.requirements << 'none'
51
+
52
+ s.require_path = 'lib'
53
+
54
+ s.files = [ "rakefile", "install.rb" ]
55
+ dist_dirs.each do |dir|
56
+ s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
57
+ end
58
+ end
59
+
60
+ Rake::GemPackageTask.new(spec) do |p|
61
+ p.gem_spec = spec
62
+ p.need_tar = true
63
+ p.need_zip = true
64
+ end
data/test/Test.class ADDED
Binary file
data/test/Test.java ADDED
@@ -0,0 +1,50 @@
1
+ import java.io.*;
2
+ import java.util.Date;
3
+
4
+ public class Test implements Serializable
5
+ {
6
+ int a;
7
+ int b;
8
+ long c;
9
+ String d;
10
+ int e[];
11
+
12
+ public void setA(int x) { a = x; }
13
+ public void setB(int x) { b = x; }
14
+ public void setC(long l) { c = l; }
15
+ public void setD(String s) { d = s; }
16
+ public void setE(int x[]) { e = x; }
17
+
18
+ public static void main(String args[])
19
+ {
20
+ Test t = new Test();
21
+ t.setA(1);
22
+ t.setB(2);
23
+ t.setC(1000000000000000L);
24
+ t.setD("Hello");
25
+ int a[] = new int[20];
26
+ for (int i = 0; i < 20; i++)
27
+ {
28
+ a[i] = i;
29
+ }
30
+
31
+ t.setE(a);
32
+
33
+ try
34
+ {
35
+ FileOutputStream fos = new FileOutputStream("t.tmp");
36
+ ObjectOutputStream oos = new ObjectOutputStream(fos);
37
+
38
+ oos.writeObject(t);
39
+ oos.writeObject(new Date());
40
+ oos.close();
41
+ }
42
+
43
+ catch (Throwable x)
44
+ {
45
+ System.err.println(x);
46
+ }
47
+
48
+ System.exit(0);
49
+ }
50
+ }
data/test/test.rb ADDED
@@ -0,0 +1,79 @@
1
+
2
+ $testdir = File.dirname(__FILE__)
3
+ $: << "#{$testdir}/../lib"
4
+
5
+ require 'javaobs'
6
+ require 'test/unit'
7
+
8
+ class JavaTest < Test::Unit::TestCase
9
+
10
+ def setup
11
+ system("javac #{$testdir}/Test.java")
12
+ system("java -classpath #{$testdir} Test")
13
+ end
14
+
15
+ def teardown
16
+ File.unlink('t.tmp')
17
+ File.unlink('t.tmp.new')
18
+ end
19
+
20
+ def test_read
21
+ orig = ''
22
+ objs = nil
23
+ File.open("t.tmp") do |f|
24
+ f.binmode
25
+
26
+ orig = f.read
27
+ f.seek(0)
28
+
29
+ os = Java::ObjectInputStream.new(f)
30
+ assert os
31
+ objs = os.readObjects
32
+ assert objs
33
+ end
34
+
35
+ obj1, obj2 = objs
36
+ assert_equal obj1.a, 1
37
+ assert_equal obj1.b, 2
38
+ assert_equal obj1.c, 1000000000000000
39
+ assert_equal obj1.d, "Hello"
40
+ obj1.e.each_with_index { |v, i| assert_equal v, i }
41
+ assert_equal obj2.class, Java::Date
42
+ end
43
+
44
+ def test_write
45
+ orig = ''
46
+ objs = nil
47
+ File.open("t.tmp") do |f|
48
+ f.binmode
49
+
50
+ orig = f.read
51
+ f.seek(0)
52
+
53
+ os = Java::ObjectInputStream.new(f)
54
+ assert os
55
+ objs = os.readObjects
56
+ assert objs
57
+ end
58
+
59
+ File.open('t.tmp.new', 'w') do |f|
60
+ f.binmode
61
+
62
+ os = Java::ObjectOutputStream.new(f)
63
+ os.writeObjects(objs)
64
+ end
65
+
66
+ mine = File.open('t.tmp.new').read
67
+ assert_equal mine, orig
68
+ end
69
+ end
70
+
71
+
72
+ if $0 == __FILE__
73
+ suite = Test::Unit::TestSuite.new('DataSource')
74
+ ObjectSpace.each_object(Class) do |klass|
75
+ suite << klass.suite if (Test::Unit::TestCase > klass)
76
+ end
77
+ require 'test/unit/ui/console/testrunner'
78
+ Test::Unit::UI::Console::TestRunner.run(suite).passed?
79
+ end
metadata ADDED
@@ -0,0 +1,50 @@
1
+ !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: javaobj
5
+ version: !ruby/object:Gem::Version
6
+ version: "0.1"
7
+ date: 2006-04-16 00:00:00 -07:00
8
+ summary: Decode Java Serialized Objects to Ruby Objects.
9
+ require_paths:
10
+ - lib
11
+ email: willsobel@mac.com
12
+ homepage: http://www.rubyforge.org
13
+ rubyforge_project: javaobj
14
+ description: Takes Java serialized objects in a file or stream and creates Ruby wrapper objects and decodes. The package can also write Java objects once UUID is read from sample.
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ authors:
29
+ - William Sobel
30
+ files:
31
+ - rakefile
32
+ - install.rb
33
+ - lib/javaobs.rb
34
+ - test/Test.class
35
+ - test/Test.java
36
+ - test/test.rb
37
+ test_files: []
38
+
39
+ rdoc_options: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ executables: []
44
+
45
+ extensions: []
46
+
47
+ requirements:
48
+ - none
49
+ dependencies: []
50
+