jruby-memcached 0.5.0 → 0.5.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/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ Gemfile.lock
1
2
  *.gem
2
3
  *.rbc
3
4
  .bundle
@@ -23,3 +24,8 @@ target/surefire
23
24
  target/dependency-reduced-pom.xml
24
25
  target/original-spymemcached-ext-0.0.1.jar
25
26
  target/original-xmemcached-ext-0.0.1.jar
27
+
28
+ .idea/
29
+ out/
30
+ spymemcached-ext.iml
31
+ src/main/Main.iml
@@ -1,3 +1,17 @@
1
+ ## 0.5.0 (Aug 22, 2012)
2
+
3
+ Bugfixes:
4
+
5
+ - fix Memcached increment/decrement, which works with MarshalTranscoder
6
+ now
7
+
8
+ Features:
9
+
10
+ - update spymemcached to 2.8.3, which set shouldOptimize as false by
11
+ default
12
+ - add Memcached::ATimeoutOccurred exception
13
+ - accept exception_retry_limit option
14
+
1
15
  ## 0.4.1 (Aug 17, 2012)
2
16
 
3
17
  Bugfixes:
data/README.md CHANGED
@@ -35,6 +35,17 @@ You can get multiple values at once:
35
35
  $cache.get ['test', 'test2', 'missing']
36
36
  #=> {"test" => "hello", "test2" => "hello"}
37
37
 
38
+ You can set a counter and increment it. Note that you must initialize it
39
+ with an integer, encoded as an unmarshalled ASCII string:
40
+
41
+ $cache.increment 'counter' #=> 1
42
+ $cache.increment 'counter' #=> 2
43
+ $cache.get('counter').to_i #=> 2
44
+
45
+ You can get some server stats:
46
+
47
+ $cache.stats #=> {..., :bytes_written=>[62], :version=>["1.2.4"] ...}
48
+
38
49
  ## Rails
39
50
 
40
51
  # config/environment.rb
@@ -1,3 +1,3 @@
1
1
  class Memcached
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.1"
3
3
  end
data/pom.xml CHANGED
@@ -1,66 +1,81 @@
1
1
  <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3
- <modelVersion>4.0.0</modelVersion>
2
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3
+ <modelVersion>4.0.0</modelVersion>
4
4
 
5
- <groupId>net.spy</groupId>
6
- <artifactId>spymemcached-ext</artifactId>
7
- <version>0.0.1</version>
8
- <packaging>jar</packaging>
5
+ <groupId>net.spy</groupId>
6
+ <artifactId>spymemcached-ext</artifactId>
7
+ <version>0.0.1</version>
8
+ <packaging>jar</packaging>
9
9
 
10
- <name>spymemcached-ext</name>
11
- <url>http://maven.apache.org</url>
10
+ <name>spymemcached-ext</name>
11
+ <url>http://maven.apache.org</url>
12
12
 
13
- <properties>
14
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15
- </properties>
13
+ <properties>
14
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15
+ </properties>
16
16
 
17
- <repositories>
18
- <repository>
19
- <id>spymemcached</id>
20
- <name>spymemcached extention</name>
21
- <layout>default</layout>
22
- <url>http://files.couchbase.com/maven2/</url>
23
- <snapshots>
24
- <enabled>false</enabled>
25
- </snapshots>
26
- </repository>
27
- </repositories>
17
+ <repositories>
18
+ <repository>
19
+ <id>spymemcached</id>
20
+ <name>spymemcached extention</name>
21
+ <layout>default</layout>
22
+ <url>http://files.couchbase.com/maven2/</url>
23
+ <snapshots>
24
+ <enabled>false</enabled>
25
+ </snapshots>
26
+ </repository>
27
+ </repositories>
28
28
 
29
- <dependencies>
30
- <dependency>
31
- <groupId>org.jruby</groupId>
32
- <artifactId>jruby</artifactId>
33
- <version>1.6.7.2</version>
34
- </dependency>
35
- <dependency>
36
- <groupId>spy</groupId>
37
- <artifactId>spymemcached</artifactId>
38
- <version>2.8.3</version>
39
- </dependency>
40
- </dependencies>
29
+ <dependencies>
30
+ <dependency>
31
+ <groupId>junit</groupId>
32
+ <artifactId>junit</artifactId>
33
+ <version>4.10</version>
34
+ <scope>test</scope>
35
+ </dependency>
36
+ <dependency>
37
+ <groupId>org.jruby</groupId>
38
+ <artifactId>jruby</artifactId>
39
+ <version>1.6.7.2</version>
40
+ </dependency>
41
+ <dependency>
42
+ <groupId>spy</groupId>
43
+ <artifactId>spymemcached</artifactId>
44
+ <version>2.8.3</version>
45
+ </dependency>
46
+ </dependencies>
41
47
 
42
- <build>
43
- <plugins>
44
- <plugin>
45
- <groupId>org.apache.maven.plugins</groupId>
46
- <artifactId>maven-shade-plugin</artifactId>
47
- <version>1.6</version>
48
- <executions>
49
- <execution>
50
- <phase>package</phase>
51
- <goals>
52
- <goal>shade</goal>
53
- </goals>
54
- <configuration>
55
- <artifactSet>
56
- <excludes>
57
- <exclude>org.jruby:jruby</exclude>
58
- </excludes>
59
- </artifactSet>
60
- </configuration>
61
- </execution>
62
- </executions>
63
- </plugin>
64
- </plugins>
65
- </build>
48
+ <build>
49
+ <plugins>
50
+ <plugin>
51
+ <groupId>org.apache.maven.plugins</groupId>
52
+ <artifactId>maven-surefire-plugin</artifactId>
53
+ <version>2.12.2</version>
54
+ <configuration>
55
+ <parallel>methods</parallel>
56
+ <threadCount>10</threadCount>
57
+ </configuration>
58
+ </plugin>
59
+ <plugin>
60
+ <groupId>org.apache.maven.plugins</groupId>
61
+ <artifactId>maven-shade-plugin</artifactId>
62
+ <version>1.6</version>
63
+ <executions>
64
+ <execution>
65
+ <phase>package</phase>
66
+ <goals>
67
+ <goal>shade</goal>
68
+ </goals>
69
+ <configuration>
70
+ <artifactSet>
71
+ <excludes>
72
+ <exclude>org.jruby:jruby</exclude>
73
+ </excludes>
74
+ </artifactSet>
75
+ </configuration>
76
+ </execution>
77
+ </executions>
78
+ </plugin>
79
+ </plugins>
80
+ </build>
66
81
  </project>
@@ -19,11 +19,15 @@ describe Memcached do
19
19
  end
20
20
 
21
21
  it "should raise error with unsupported option hash" do
22
- lambda { Memcached.new("127.0.0.1:11211", :hash => :unknown) }.should raise_error(Memcached::NotSupport)
22
+ expect { Memcached.new("127.0.0.1:11211", :hash => :unknown) }.to raise_error(Memcached::NotSupport)
23
23
  end
24
24
 
25
25
  it "should raise error with unsupported option distribution" do
26
- lambda { Memcached.new("127.0.0.1:11211", :distribution => :unknown) }.should raise_error(Memcached::NotSupport)
26
+ expect { Memcached.new("127.0.0.1:11211", :distribution => :unknown) }.to raise_error(Memcached::NotSupport)
27
+ end
28
+
29
+ it "should ignore nil value" do
30
+ expect { Memcached.new("127.0.0.1:11211", :prefix => nil) }.not_to raise_error
27
31
  end
28
32
  end
29
33
 
@@ -47,7 +51,7 @@ describe Memcached do
47
51
 
48
52
  it "should get missing" do
49
53
  @memcached.delete "key" rescue nil
50
- lambda { @memcached.get "key" }.should raise_error(Memcached::NotFound)
54
+ expect { @memcached.get "key" }.to raise_error(Memcached::NotFound)
51
55
  end
52
56
 
53
57
  context "multiget" do
@@ -74,7 +78,7 @@ describe Memcached do
74
78
  @memcached.set "key", "value", 1
75
79
  @memcached.get("key").should == "value"
76
80
  sleep 1
77
- lambda { @memcached.get("key") }.should raise_error(Memcached::NotFound)
81
+ expect { @memcached.get("key") }.to raise_error(Memcached::NotFound)
78
82
  end
79
83
  end
80
84
 
@@ -87,7 +91,7 @@ describe Memcached do
87
91
 
88
92
  it "should not add existing key" do
89
93
  @memcached.set "key", "value"
90
- lambda { @memcached.add "key", "value" }.should raise_error(Memcached::NotStored)
94
+ expect { @memcached.add "key", "value" }.to raise_error(Memcached::NotStored)
91
95
  end
92
96
 
93
97
  it "should add expiry" do
@@ -95,7 +99,7 @@ describe Memcached do
95
99
  @memcached.add "key", "value", 1
96
100
  @memcached.get "key"
97
101
  sleep 1
98
- lambda { @memcached.get "key" }.should raise_error(Memcached::NotFound)
102
+ expect { @memcached.get "key" }.to raise_error(Memcached::NotFound)
99
103
  end
100
104
  end
101
105
 
@@ -108,8 +112,8 @@ describe Memcached do
108
112
 
109
113
  it "should not replace with new key" do
110
114
  @memcached.delete "key" rescue nil
111
- lambda { @memcached.replace "key", "value" }.should raise_error(Memcached::NotStored)
112
- lambda { @memcached.get "key" }.should raise_error(Memcached::NotFound)
115
+ expect { @memcached.replace "key", "value" }.to raise_error(Memcached::NotStored)
116
+ expect { @memcached.get "key" }.to raise_error(Memcached::NotFound)
113
117
  end
114
118
  end
115
119
 
@@ -117,12 +121,12 @@ describe Memcached do
117
121
  it "should delete with existing key" do
118
122
  @memcached.set "key", "value"
119
123
  @memcached.delete "key"
120
- lambda { @memcached.get "key" }.should raise_error(Memcached::NotFound)
124
+ expect { @memcached.get "key" }.to raise_error(Memcached::NotFound)
121
125
  end
122
126
 
123
127
  it "should not delete with new key" do
124
128
  @memcached.delete "key" rescue nil
125
- lambda { @memcached.delete "key" }.should raise_error(Memcached::NotFound)
129
+ expect { @memcached.delete "key" }.to raise_error(Memcached::NotFound)
126
130
  end
127
131
  end
128
132
 
@@ -176,8 +180,8 @@ describe Memcached do
176
180
  @memcached.set "key1", "value2"
177
181
  @memcached.set "key2", "value2"
178
182
  @memcached.flush
179
- lambda { @memcached.get "key1" }.should raise_error(Memcached::NotFound)
180
- lambda { @memcached.get "key2" }.should raise_error(Memcached::NotFound)
183
+ expect { @memcached.get "key1" }.to raise_error(Memcached::NotFound)
184
+ expect { @memcached.get "key2" }.to raise_error(Memcached::NotFound)
181
185
  end
182
186
  end
183
187
 
@@ -209,7 +213,7 @@ describe Memcached do
209
213
  it "should delete with prefix_key" do
210
214
  @prefix_memcached.set "key", "value"
211
215
  @prefix_memcached.delete "key"
212
- lambda { @memcached.get("jrubykey") }.should raise_error(Memcached::NotFound)
216
+ expect { @memcached.get("jrubykey") }.to raise_error(Memcached::NotFound)
213
217
  end
214
218
 
215
219
  it "should multiget with prefix_key" do
@@ -227,48 +231,5 @@ describe Memcached do
227
231
  end
228
232
  end
229
233
  end
230
-
231
- context "timeout" do
232
- before(:all) do
233
- @memcached = Memcached.new("127.0.0.1:11211")
234
- @timeout_memcached = Memcached.new("127.0.0.1:11211", :timeout => 1, :exception_retry_limit => 0)
235
- end
236
- after(:all) do
237
- @timeout_memcached.quit
238
- @memcached.quit
239
- end
240
-
241
- it "should set timeout" do
242
- lambda { @timeout_memcached.set "key", "new_value" }.should raise_error(Memcached::ATimeoutOccurred)
243
- end
244
-
245
- it "should add timeout" do
246
- @memcached.delete "key" rescue nil
247
- lambda { @timeout_memcached.add "key", "new_value" }.should raise_error(Memcached::ATimeoutOccurred)
248
- end
249
-
250
- it "should replace timeout" do
251
- @memcached.set "key", "value"
252
- lambda { @timeout_memcached.replace "key", "new_value" }.should raise_error(Memcached::ATimeoutOccurred)
253
- end
254
-
255
- it "should delete timeout" do
256
- @memcached.set "key", "value"
257
- lambda { @timeout_memcached.delete "key" }.should raise_error(Memcached::ATimeoutOccurred)
258
- end
259
-
260
- it "should get timeout" do
261
- @memcached.set "key", "value"
262
- lambda { @timeout_memcached.get "key" }.should raise_error(Memcached::ATimeoutOccurred)
263
- end
264
-
265
- it "should increment timeout" do
266
- lambda { @timeout_memcached.increment "intkey" }.should raise_error(Memcached::ATimeoutOccurred)
267
- end
268
-
269
- it "should decrement timeout" do
270
- lambda { @timeout_memcached.decrement "intkey" }.should raise_error(Memcached::ATimeoutOccurred)
271
- end
272
- end
273
234
  end
274
235
  end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ # This is a stupid way to test timeout cases.
4
+ #
5
+ # Originally, I want to mock MemcachedClient methods to throw OperationTimeout, like
6
+ #
7
+ # MemcachedClient.any_instance.stubs(:get).raises(OperationTimeout)
8
+ # lambda { @timeout_memcached.get "key" }.should raise_error(Memcached::ATimeoutOccurred)
9
+ #
10
+ # But it doesn't work.
11
+ #
12
+ # The current solution is to call @timeout_memcahced.get in an infinite loop until a
13
+ # Memcached::ATimeoutOccurred raised. It works, but really slow down the tests, I hate it.
14
+ #
15
+ # If you have a better solution, please let me know flyerhzm at gmail dot com, thanks.
16
+ describe Memcached do
17
+ before(:all) do
18
+ @memcached = Memcached.new("127.0.0.1:11211")
19
+ @timeout_memcached = Memcached.new("127.0.0.1:11211", :timeout => 1, :exception_retry_limit => 0)
20
+ end
21
+
22
+ after(:all) do
23
+ @timeout_memcached.quit
24
+ @memcached.quit
25
+ end
26
+
27
+ it "should set timeout" do
28
+ lambda {
29
+ while true
30
+ @timeout_memcached.set "key", "new_value"
31
+ end
32
+ }.should raise_error(Memcached::ATimeoutOccurred)
33
+ end
34
+
35
+ it "should add timeout" do
36
+ lambda {
37
+ while true
38
+ @memcached.delete "key" rescue nil
39
+ @timeout_memcached.add "key", "new_value"
40
+ end
41
+ }.should raise_error(Memcached::ATimeoutOccurred)
42
+ end
43
+
44
+ it "should replace timeout" do
45
+ @memcached.set "key", "value"
46
+ lambda {
47
+ while true
48
+ @timeout_memcached.replace "key", "new_value"
49
+ end
50
+ }.should raise_error(Memcached::ATimeoutOccurred)
51
+ end
52
+
53
+ it "should delete timeout" do
54
+ lambda {
55
+ while true
56
+ @memcached.set "key", "value"
57
+ @timeout_memcached.delete "key"
58
+ end
59
+ }.should raise_error(Memcached::ATimeoutOccurred)
60
+ end
61
+
62
+ it "should get timeout" do
63
+ @memcached.set "key", "value"
64
+ lambda {
65
+ while true
66
+ @timeout_memcached.get "key"
67
+ end
68
+ }.should raise_error(Memcached::ATimeoutOccurred)
69
+ end
70
+
71
+ it "should increment timeout" do
72
+ lambda {
73
+ while true
74
+ @timeout_memcached.increment "intkey"
75
+ end
76
+ }.should raise_error(Memcached::ATimeoutOccurred)
77
+ end
78
+
79
+ it "should decrement timeout" do
80
+ lambda {
81
+ while true
82
+ @timeout_memcached.decrement "intkey"
83
+ end
84
+ }.should raise_error(Memcached::ATimeoutOccurred)
85
+ end
86
+ end
@@ -1,7 +1,6 @@
1
1
  package com.openfeint.memcached;
2
2
 
3
3
  import com.openfeint.memcached.error.Error;
4
- import com.openfeint.memcached.error.NotFound;
5
4
  import com.openfeint.memcached.transcoder.MarshalTranscoder;
6
5
  import com.openfeint.memcached.transcoder.MarshalZlibTranscoder;
7
6
  import net.spy.memcached.AddrUtil;
@@ -30,6 +29,7 @@ import java.net.InetSocketAddress;
30
29
  import java.net.SocketAddress;
31
30
  import java.util.ArrayList;
32
31
  import java.util.List;
32
+ import java.util.HashMap;
33
33
  import java.util.Map;
34
34
  import java.util.concurrent.ExecutionException;
35
35
 
@@ -59,11 +59,14 @@ public class Memcached extends RubyObject {
59
59
  @JRubyMethod(name = "initialize", optional = 2)
60
60
  public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
61
61
  Ruby ruby = context.getRuntime();
62
- RubyHash options;
62
+ Map<String, String> options = new HashMap<String, String>();
63
63
  if (args.length > 1) {
64
- options = args[1].convertToHash();
65
- } else {
66
- options = new RubyHash(ruby);
64
+ RubyHash arguments = args[1].convertToHash();
65
+ for (Object key : arguments.keySet()) {
66
+ if (arguments.get(key) != null) {
67
+ options.put(key.toString(), arguments.get(key).toString());
68
+ }
69
+ }
67
70
  }
68
71
  List<String> servers = new ArrayList<String>();
69
72
  if (args.length > 0) {
@@ -102,8 +105,8 @@ public class Memcached extends RubyObject {
102
105
  int retry = 0;
103
106
  while (true) {
104
107
  try {
105
- boolean result = (Boolean) client.add(key, expiry, value, transcoder).get();
106
- if (result == false) {
108
+ Boolean result = (Boolean) client.add(key, expiry, value, transcoder).get();
109
+ if (!result) {
107
110
  throw Error.newNotStored(ruby, "not stored");
108
111
  }
109
112
  return context.nil;
@@ -115,7 +118,6 @@ public class Memcached extends RubyObject {
115
118
  throw Error.newATimeoutOccurred(ruby, e.getLocalizedMessage());
116
119
  }
117
120
  retry++;
118
- continue;
119
121
  } else {
120
122
  throw ruby.newRuntimeError(e.getLocalizedMessage());
121
123
  }
@@ -126,7 +128,6 @@ public class Memcached extends RubyObject {
126
128
  throw Error.newATimeoutOccurred(ruby, e.getLocalizedMessage());
127
129
  }
128
130
  retry++;
129
- continue;
130
131
  } else {
131
132
  throw ruby.newRuntimeError(e.getLocalizedMessage());
132
133
  }
@@ -145,8 +146,8 @@ public class Memcached extends RubyObject {
145
146
  int retry = 0;
146
147
  while (true) {
147
148
  try {
148
- boolean result = (Boolean) client.replace(key, expiry, value, transcoder).get();
149
- if (result == false) {
149
+ Boolean result = (Boolean) client.replace(key, expiry, value, transcoder).get();
150
+ if (!result) {
150
151
  throw Error.newNotStored(ruby, "not stored");
151
152
  }
152
153
  return context.nil;
@@ -158,7 +159,6 @@ public class Memcached extends RubyObject {
158
159
  throw Error.newATimeoutOccurred(ruby, e.getLocalizedMessage());
159
160
  }
160
161
  retry++;
161
- continue;
162
162
  } else {
163
163
  throw ruby.newRuntimeError(e.getLocalizedMessage());
164
164
  }
@@ -169,7 +169,6 @@ public class Memcached extends RubyObject {
169
169
  throw Error.newATimeoutOccurred(ruby, e.getLocalizedMessage());
170
170
  }
171
171
  retry++;
172
- continue;
173
172
  } else {
174
173
  throw ruby.newRuntimeError(e.getLocalizedMessage());
175
174
  }
@@ -188,8 +187,8 @@ public class Memcached extends RubyObject {
188
187
  int retry = 0;
189
188
  while (true) {
190
189
  try {
191
- boolean result = (Boolean) client.set(key, expiry, value, transcoder).get();
192
- if (result == false) {
190
+ Boolean result = (Boolean) client.set(key, expiry, value, transcoder).get();
191
+ if (!result) {
193
192
  throw Error.newNotStored(ruby, "not stored");
194
193
  }
195
194
  return context.nil;
@@ -201,7 +200,6 @@ public class Memcached extends RubyObject {
201
200
  throw Error.newATimeoutOccurred(ruby, e.getLocalizedMessage());
202
201
  }
203
202
  retry++;
204
- continue;
205
203
  } else {
206
204
  throw ruby.newRuntimeError(e.getLocalizedMessage());
207
205
  }
@@ -212,7 +210,6 @@ public class Memcached extends RubyObject {
212
210
  throw Error.newATimeoutOccurred(ruby, e.getLocalizedMessage());
213
211
  }
214
212
  retry++;
215
- continue;
216
213
  } else {
217
214
  throw ruby.newRuntimeError(e.getLocalizedMessage());
218
215
  }
@@ -244,10 +241,10 @@ public class Memcached extends RubyObject {
244
241
  } else if (keys instanceof RubyArray) {
245
242
  RubyHash results = RubyHash.newHash(ruby);
246
243
 
247
- Map<String, IRubyObject> bulkResults = client.getBulk(getFullKeys(keys.convertToArray()), transcoder);
244
+ Map<String, IRubyObject> bulkResults = (Map<String, IRubyObject>) client.getBulk(getFullKeys(keys.convertToArray()), transcoder);
248
245
  for (String key : (List<String>) keys.convertToArray()) {
249
246
  if (bulkResults.containsKey(getFullKey(key))) {
250
- results.put(key, (IRubyObject) bulkResults.get(getFullKey(key)));
247
+ results.put(key, bulkResults.get(getFullKey(key)));
251
248
  }
252
249
  }
253
250
  return results;
@@ -255,11 +252,13 @@ public class Memcached extends RubyObject {
255
252
  } catch (RaiseException e) {
256
253
  throw e;
257
254
  } catch (OperationTimeoutException e) {
258
- throw Error.newATimeoutOccurred(ruby, e.getLocalizedMessage());
255
+ if (retry == exceptionRetryLimit) {
256
+ throw Error.newATimeoutOccurred(ruby, e.getLocalizedMessage());
257
+ }
258
+ retry++;
259
259
  } catch (RuntimeException e) {
260
260
  throw ruby.newRuntimeError(e.getLocalizedMessage());
261
261
  }
262
- return context.nil;
263
262
  }
264
263
  }
265
264
 
@@ -279,7 +278,6 @@ public class Memcached extends RubyObject {
279
278
  throw Error.newATimeoutOccurred(ruby, e.getLocalizedMessage());
280
279
  }
281
280
  retry++;
282
- continue;
283
281
  }
284
282
  }
285
283
  }
@@ -300,7 +298,6 @@ public class Memcached extends RubyObject {
300
298
  throw Error.newATimeoutOccurred(ruby, e.getLocalizedMessage());
301
299
  }
302
300
  retry++;
303
- continue;
304
301
  }
305
302
  }
306
303
  }
@@ -312,7 +309,7 @@ public class Memcached extends RubyObject {
312
309
  while (true) {
313
310
  try {
314
311
  boolean result = client.delete(getFullKey(key.toString())).get();
315
- if (result == false) {
312
+ if (!result) {
316
313
  throw Error.newNotFound(ruby, "not found");
317
314
  }
318
315
  return context.nil;
@@ -324,7 +321,6 @@ public class Memcached extends RubyObject {
324
321
  throw Error.newATimeoutOccurred(ruby, e.getLocalizedMessage());
325
322
  }
326
323
  retry++;
327
- continue;
328
324
  } else {
329
325
  throw ruby.newRuntimeError(e.getLocalizedMessage());
330
326
  }
@@ -335,7 +331,6 @@ public class Memcached extends RubyObject {
335
331
  throw Error.newATimeoutOccurred(ruby, e.getLocalizedMessage());
336
332
  }
337
333
  retry++;
338
- continue;
339
334
  } else {
340
335
  throw ruby.newRuntimeError(e.getLocalizedMessage());
341
336
  }
@@ -385,7 +380,7 @@ public class Memcached extends RubyObject {
385
380
  return ttl;
386
381
  }
387
382
 
388
- protected IRubyObject init(ThreadContext context, List<String> servers, RubyHash options) {
383
+ protected IRubyObject init(ThreadContext context, List<String> servers, Map<String, String> opts) {
389
384
  Ruby ruby = context.getRuntime();
390
385
  List<InetSocketAddress> addresses = AddrUtil.getAddresses(servers);
391
386
  try {
@@ -393,40 +388,39 @@ public class Memcached extends RubyObject {
393
388
 
394
389
  String distributionValue = "ketama";
395
390
  String hashValue = "fnv1_32";
396
- RubyBoolean binaryValue = ruby.getFalse();
397
- RubyBoolean shouldOptimize = ruby.getFalse();
391
+ boolean binaryValue = false;
392
+ boolean shouldOptimize = false;
398
393
  String transcoderValue = null;
399
- if (!options.isEmpty()) {
400
- RubyHash opts = options.convertToHash();
401
- if (opts.containsKey(ruby.newSymbol("distribution"))) {
402
- distributionValue = opts.get(ruby.newSymbol("distribution")).toString();
394
+ if (!opts.isEmpty()) {
395
+ if (opts.containsKey("distribution")) {
396
+ distributionValue = opts.get("distribution");
403
397
  }
404
- if (opts.containsKey(ruby.newSymbol("hash"))) {
405
- hashValue = opts.get(ruby.newSymbol("hash")).toString();
398
+ if (opts.containsKey("hash")) {
399
+ hashValue = opts.get("hash");
406
400
  }
407
- if (opts.containsKey(ruby.newSymbol("binary_protocol"))) {
408
- binaryValue = (RubyBoolean) opts.get(ruby.newSymbol("binary_protocol"));
401
+ if (opts.containsKey("binary_protocol")) {
402
+ binaryValue = Boolean.parseBoolean(opts.get("binary_protocol"));
409
403
  }
410
- if (opts.containsKey(ruby.newSymbol("should_optimize"))) {
411
- shouldOptimize = (RubyBoolean) opts.get(ruby.newSymbol("should_optimize"));
404
+ if (opts.containsKey("should_optimize")) {
405
+ shouldOptimize = Boolean.parseBoolean(opts.get("should_optimize"));
412
406
  }
413
- if (opts.containsKey(ruby.newSymbol("default_ttl"))) {
414
- ttl = Integer.parseInt(opts.get(ruby.newSymbol("default_ttl")).toString());
407
+ if (opts.containsKey("default_ttl")) {
408
+ ttl = Integer.parseInt(opts.get("default_ttl"));
415
409
  }
416
- if (opts.containsKey(ruby.newSymbol("timeout"))) {
417
- timeout = Integer.parseInt(opts.get(ruby.newSymbol("timeout")).toString());
410
+ if (opts.containsKey("timeout")) {
411
+ timeout = Integer.parseInt(opts.get("timeout"));
418
412
  }
419
- if (opts.containsKey(ruby.newSymbol("exception_retry_limit"))) {
420
- exceptionRetryLimit = Integer.parseInt(opts.get(ruby.newSymbol("exception_retry_limit")).toString());
413
+ if (opts.containsKey("exception_retry_limit")) {
414
+ exceptionRetryLimit = Integer.parseInt(opts.get("exception_retry_limit"));
421
415
  }
422
- if (opts.containsKey(ruby.newSymbol("namespace"))) {
423
- prefixKey = opts.get(ruby.newSymbol("namespace")).toString();
416
+ if (opts.containsKey("namespace")) {
417
+ prefixKey = opts.get("namespace");
424
418
  }
425
- if (opts.containsKey(ruby.newSymbol("prefix_key"))) {
426
- prefixKey = opts.get(ruby.newSymbol("prefix_key")).toString();
419
+ if (opts.containsKey("prefix_key")) {
420
+ prefixKey = opts.get("prefix_key");
427
421
  }
428
- if (opts.containsKey(ruby.newSymbol("transcoder"))) {
429
- transcoderValue = opts.get(ruby.newSymbol("transcoder")).toString();
422
+ if (opts.containsKey("transcoder")) {
423
+ transcoderValue = opts.get("transcoder");
430
424
  }
431
425
  }
432
426
 
@@ -455,10 +449,10 @@ public class Memcached extends RubyObject {
455
449
  throw Error.newNotSupport(ruby, "hash not support");
456
450
  }
457
451
 
458
- if (ruby.getTrue() == binaryValue) {
452
+ if (binaryValue) {
459
453
  builder.setProtocol(Protocol.BINARY);
460
454
  }
461
- if (ruby.getTrue() == shouldOptimize) {
455
+ if (shouldOptimize) {
462
456
  builder.setShouldOptimize(true);
463
457
  }
464
458
 
@@ -474,11 +468,11 @@ public class Memcached extends RubyObject {
474
468
  builder.setTranscoder(transcoder);
475
469
 
476
470
  client = new MemcachedClient(builder.build(), addresses);
477
- } catch (IOException ioe) {
478
- throw ruby.newIOErrorFromException(ioe);
479
- }
480
471
 
481
- return context.nil;
472
+ return context.nil;
473
+ } catch (IOException e) {
474
+ throw ruby.newIOErrorFromException(e);
475
+ }
482
476
  }
483
477
 
484
478
  private int getExpiry(IRubyObject[] args) {
@@ -6,7 +6,6 @@ import org.jruby.RubyBoolean;
6
6
  import org.jruby.RubyClass;
7
7
  import org.jruby.RubyHash;
8
8
  import org.jruby.RubyFixnum;
9
- import org.jruby.RubyObject;
10
9
  import org.jruby.RubyString;
11
10
  import org.jruby.anno.JRubyClass;
12
11
  import org.jruby.anno.JRubyMethod;
@@ -17,6 +16,8 @@ import org.jruby.runtime.builtin.IRubyObject;
17
16
 
18
17
  import java.util.ArrayList;
19
18
  import java.util.List;
19
+ import java.util.HashMap;
20
+ import java.util.Map;
20
21
 
21
22
  @JRubyClass(name = "Memcached::Rails", parent = "Memcached")
22
23
  public class Rails extends Memcached {
@@ -31,12 +32,7 @@ public class Rails extends Memcached {
31
32
  @JRubyMethod(name = "initialize", rest = true)
32
33
  public IRubyObject initialize(ThreadContext context, IRubyObject[] args) {
33
34
  Ruby ruby = context.getRuntime();
34
- RubyHash opts;
35
- if (args[args.length - 1] instanceof RubyHash) {
36
- opts = (RubyHash) args[args.length - 1];
37
- } else {
38
- opts = new RubyHash(ruby);
39
- }
35
+
40
36
  List<String> servers = new ArrayList<String>();
41
37
  for (IRubyObject arg : args) {
42
38
  if (arg instanceof RubyString) {
@@ -45,20 +41,30 @@ public class Rails extends Memcached {
45
41
  servers.addAll((List<String>) arg.convertToArray());
46
42
  }
47
43
  }
48
- if (servers.isEmpty()) {
49
- IRubyObject serverNames = (IRubyObject) opts.get(ruby.newSymbol("servers"));
50
- servers.addAll((List<String>) serverNames.convertToArray());
44
+
45
+ Map<String, String> options = new HashMap<String, String>();
46
+ if (args[args.length - 1] instanceof RubyHash) {
47
+ RubyHash arguments = args[args.length - 1].convertToHash();
48
+ for (Object key : arguments.keySet()) {
49
+ if (!"servers".equals(key.toString())) {
50
+ options.put(key.toString(), arguments.get(key).toString());
51
+ }
52
+ }
53
+ if (servers.isEmpty()) {
54
+ IRubyObject serverNames = (IRubyObject) arguments.get(ruby.newSymbol("servers"));
55
+ servers.addAll((List<String>) serverNames.convertToArray());
56
+ }
51
57
  }
52
- if (opts.containsKey(ruby.newSymbol("namespace"))) {
53
- opts.put(ruby.newSymbol("prefix_key"), opts.get(ruby.newSymbol("namespace")));
58
+ if (options.containsKey("namespace")) {
59
+ options.put("prefix_key", options.get("namespace"));
54
60
  }
55
- if (opts.containsKey(ruby.newSymbol("namespace_separator"))) {
56
- opts.put(ruby.newSymbol("prefix_delimiter"), opts.get(ruby.newSymbol("namespace_separator")));
61
+ if (options.containsKey("namespace_separator")) {
62
+ options.put("prefix_delimiter", options.get("namespace_separator"));
57
63
  }
58
- if (opts.containsKey(ruby.newSymbol("string_return_types"))) {
64
+ if (options.containsKey("string_return_types")) {
59
65
  stringReturnTypes = true;
60
66
  }
61
- return super.init(context, servers, opts);
67
+ return super.init(context, servers, options);
62
68
  }
63
69
 
64
70
  @JRubyMethod(name = "active?")
@@ -72,7 +78,6 @@ public class Rails extends Memcached {
72
78
 
73
79
  @JRubyMethod(name = { "get", "[]" }, required = 1, optional = 1)
74
80
  public IRubyObject get(ThreadContext context, IRubyObject[] args) {
75
- Ruby ruby = context.getRuntime();
76
81
  IRubyObject key = args[0];
77
82
  RubyBoolean notRaw = notRaw(context, args, 1);
78
83
  try {
@@ -87,8 +92,6 @@ public class Rails extends Memcached {
87
92
 
88
93
  @JRubyMethod(name = "read", required = 1, optional = 1)
89
94
  public IRubyObject read(ThreadContext context, IRubyObject[] args) {
90
- Ruby ruby = context.getRuntime();
91
- RubyBoolean not_raw = ruby.getTrue();
92
95
  IRubyObject key = args[0];
93
96
  RubyBoolean notRaw = notRaw(context, args, 1);
94
97
  return get(context, new IRubyObject[] { key, notRaw });
@@ -107,7 +110,6 @@ public class Rails extends Memcached {
107
110
 
108
111
  @JRubyMethod(name = "get_multi", required = 1, optional = 1)
109
112
  public IRubyObject getMulti(ThreadContext context, IRubyObject[] args) {
110
- Ruby ruby = context.getRuntime();
111
113
  IRubyObject keys = args[0];
112
114
  RubyBoolean notRaw = notRaw(context, args, 1);
113
115
  return super.get(context, new IRubyObject[] { keys, notRaw });
@@ -130,7 +132,6 @@ public class Rails extends Memcached {
130
132
 
131
133
  @JRubyMethod(name = "write", required = 2, optional = 1)
132
134
  public IRubyObject write(ThreadContext context, IRubyObject[] args) {
133
- Ruby ruby = context.getRuntime();
134
135
  IRubyObject key = args[0];
135
136
  IRubyObject value = args[1];
136
137
  RubyFixnum ttl = getTTL(context, args, 2);
@@ -229,9 +230,8 @@ public class Rails extends Memcached {
229
230
  Ruby ruby = context.getRuntime();
230
231
  RubyBoolean notRaw = ruby.getTrue();
231
232
  if (args.length > index) {
232
- if (args[index] instanceof RubyBoolean && ruby.getTrue() == (RubyBoolean) args[index]) {
233
- notRaw = ruby.getFalse();
234
- } else if (args[index] instanceof RubyHash && ruby.getTrue() == ((RubyHash) args[index]).get(ruby.newSymbol("raw"))) {
233
+ if ((args[index] instanceof RubyBoolean && ruby.getTrue() == args[index]) ||
234
+ (args[index] instanceof RubyHash && ruby.getTrue() == ((RubyHash) args[index]).get(ruby.newSymbol("raw")))) {
235
235
  notRaw = ruby.getFalse();
236
236
  }
237
237
  }
@@ -1,21 +1,17 @@
1
1
  package com.openfeint.memcached.transcoder;
2
2
 
3
- import com.jcraft.jzlib.ZOutputStream;
4
- import com.jcraft.jzlib.ZInputStream;
5
3
  import com.jcraft.jzlib.JZlib;
4
+ import com.jcraft.jzlib.ZInputStream;
5
+ import com.jcraft.jzlib.ZOutputStream;
6
6
  import net.spy.memcached.CachedData;
7
- import net.spy.memcached.transcoders.Transcoder;
8
7
  import org.jruby.Ruby;
9
8
  import org.jruby.exceptions.RaiseException;
10
9
  import org.jruby.runtime.builtin.IRubyObject;
11
10
  import org.jruby.runtime.marshal.MarshalStream;
12
11
  import org.jruby.runtime.marshal.UnmarshalStream;
13
- import org.jruby.util.ByteList;
14
12
 
15
13
  import java.io.ByteArrayInputStream;
16
14
  import java.io.ByteArrayOutputStream;
17
- import java.io.ObjectInputStream;
18
- import java.io.ObjectOutputStream;
19
15
  import java.io.IOException;
20
16
 
21
17
  /**
@@ -36,6 +32,7 @@ public class MarshalZlibTranscoder extends MarshalTranscoder {
36
32
 
37
33
  public CachedData encode(Object o) {
38
34
  if (o instanceof IRubyObject) {
35
+ ZOutputStream zout = null;
39
36
  try {
40
37
  ByteArrayOutputStream out1 = new ByteArrayOutputStream();
41
38
  MarshalStream marshal = new MarshalStream(ruby, out1, Integer.MAX_VALUE);
@@ -44,9 +41,10 @@ public class MarshalZlibTranscoder extends MarshalTranscoder {
44
41
  byte[] bytes;
45
42
  if (getFlags() == COMPRESS_FLAG) {
46
43
  ByteArrayOutputStream out2 = new ByteArrayOutputStream();
47
- ZOutputStream zout = new ZOutputStream(out2, JZlib.Z_DEFAULT_COMPRESSION);
44
+ zout = new ZOutputStream(out2, JZlib.Z_DEFAULT_COMPRESSION);
48
45
  zout.write(out1.toByteArray());
49
- zout.close();
46
+ zout.flush();
47
+ zout.end();
50
48
  bytes = out2.toByteArray();
51
49
  } else {
52
50
  bytes = out1.toByteArray();
@@ -55,6 +53,13 @@ public class MarshalZlibTranscoder extends MarshalTranscoder {
55
53
  return new CachedData(super.getFlags(), bytes, bytes.length);
56
54
  } catch (IOException e) {
57
55
  throw ruby.newIOErrorFromException(e);
56
+ } finally {
57
+ if (zout != null) {
58
+ try {
59
+ zout.close();
60
+ } catch (IOException e) {}
61
+ zout = null;
62
+ }
58
63
  }
59
64
  } else {
60
65
  return super.encodeNumber(o);
@@ -62,11 +67,12 @@ public class MarshalZlibTranscoder extends MarshalTranscoder {
62
67
  }
63
68
 
64
69
  public Object decode(CachedData d) {
70
+ ZInputStream zin = null;
65
71
  try {
66
72
  byte[] bytes;
67
73
  if (d.getFlags() == COMPRESS_FLAG) {
68
74
  ByteArrayInputStream in = new ByteArrayInputStream(d.getData());
69
- ZInputStream zin = new ZInputStream(in);
75
+ zin = new ZInputStream(in);
70
76
 
71
77
  ByteArrayOutputStream buffer = new ByteArrayOutputStream();
72
78
  int nRead;
@@ -76,7 +82,6 @@ public class MarshalZlibTranscoder extends MarshalTranscoder {
76
82
  }
77
83
  buffer.flush();
78
84
  bytes = buffer.toByteArray();
79
- zin.close();
80
85
  } else {
81
86
  bytes = d.getData();
82
87
  }
@@ -86,6 +91,13 @@ public class MarshalZlibTranscoder extends MarshalTranscoder {
86
91
  return super.decodeNumber(d, e);
87
92
  } catch (IOException e) {
88
93
  return super.decodeNumber(d, e);
94
+ } finally {
95
+ if (zin != null) {
96
+ try {
97
+ zin.close();
98
+ } catch (IOException e) {}
99
+ zin = null;
100
+ }
89
101
  }
90
102
  }
91
103
  }
metadata CHANGED
@@ -1,106 +1,122 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: jruby-memcached
3
- version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.5.0
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.5.1
6
6
  platform: ruby
7
- authors:
8
- - Richard Huang
9
- autorequire:
7
+ authors:
8
+ - Richard Huang
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2012-08-22 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: rspec
17
- prerelease: false
18
- requirement: &id001 !ruby/object:Gem::Requirement
19
- none: false
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: "0"
24
- type: :development
25
- version_requirements: *id001
26
- - !ruby/object:Gem::Dependency
27
- name: mocha
28
- prerelease: false
29
- requirement: &id002 !ruby/object:Gem::Requirement
30
- none: false
31
- requirements:
32
- - - ">="
33
- - !ruby/object:Gem::Version
34
- version: "0"
35
- type: :development
36
- version_requirements: *id002
12
+ date: 2012-11-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ! '>='
19
+ - !ruby/object:Gem::Version
20
+ version: !binary |-
21
+ MA==
22
+ none: false
23
+ requirement: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ! '>='
26
+ - !ruby/object:Gem::Version
27
+ version: !binary |-
28
+ MA==
29
+ none: false
30
+ prerelease: false
31
+ type: :development
32
+ - !ruby/object:Gem::Dependency
33
+ name: mocha
34
+ version_requirements: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: !binary |-
39
+ MA==
40
+ none: false
41
+ requirement: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: !binary |-
46
+ MA==
47
+ none: false
48
+ prerelease: false
49
+ type: :development
37
50
  description: jruby memcacached client which is compatible with memcached gem
38
- email:
39
- - flyerhzm@gmail.com
51
+ email:
52
+ - flyerhzm@gmail.com
40
53
  executables: []
41
-
42
54
  extensions: []
43
-
44
55
  extra_rdoc_files: []
45
-
46
- files:
47
- - .gitignore
48
- - .travis.yml
49
- - CHANGELOG.md
50
- - Gemfile
51
- - Gemfile.lock
52
- - MIT-LICENSE
53
- - README.md
54
- - Rakefile
55
- - benchmark.rb
56
- - jruby_memcached.gemspec
57
- - lib/memcached.rb
58
- - lib/memcached/version.rb
59
- - pom.xml
60
- - spec/memcached_spec.rb
61
- - spec/rails_spec.rb
62
- - spec/spec_helper.rb
63
- - src/main/java/com/openfeint/memcached/Memcached.java
64
- - src/main/java/com/openfeint/memcached/MemcachedService.java
65
- - src/main/java/com/openfeint/memcached/Rails.java
66
- - src/main/java/com/openfeint/memcached/error/ATimeoutOccurred.java
67
- - src/main/java/com/openfeint/memcached/error/Error.java
68
- - src/main/java/com/openfeint/memcached/error/NotFound.java
69
- - src/main/java/com/openfeint/memcached/error/NotStored.java
70
- - src/main/java/com/openfeint/memcached/error/NotSupport.java
71
- - src/main/java/com/openfeint/memcached/transcoder/MarshalTranscoder.java
72
- - src/main/java/com/openfeint/memcached/transcoder/MarshalZlibTranscoder.java
73
- - src/main/java/net/spy/memcached/KetamaNodeLocator.java
74
- - src/main/java/net/spy/memcached/util/DefaultKetamaNodeLocatorConfiguration.java
75
- - target/spymemcached-ext-0.0.1.jar
56
+ files:
57
+ - .gitignore
58
+ - .travis.yml
59
+ - CHANGELOG.md
60
+ - Gemfile
61
+ - MIT-LICENSE
62
+ - README.md
63
+ - Rakefile
64
+ - benchmark.rb
65
+ - jruby_memcached.gemspec
66
+ - lib/memcached.rb
67
+ - lib/memcached/version.rb
68
+ - pom.xml
69
+ - spec/memcached_spec.rb
70
+ - spec/rails_spec.rb
71
+ - spec/spec_helper.rb
72
+ - spec/timeout_spec.rb
73
+ - src/main/java/com/openfeint/memcached/Memcached.java
74
+ - src/main/java/com/openfeint/memcached/MemcachedService.java
75
+ - src/main/java/com/openfeint/memcached/Rails.java
76
+ - src/main/java/com/openfeint/memcached/error/ATimeoutOccurred.java
77
+ - src/main/java/com/openfeint/memcached/error/Error.java
78
+ - src/main/java/com/openfeint/memcached/error/NotFound.java
79
+ - src/main/java/com/openfeint/memcached/error/NotStored.java
80
+ - src/main/java/com/openfeint/memcached/error/NotSupport.java
81
+ - src/main/java/com/openfeint/memcached/transcoder/MarshalTranscoder.java
82
+ - src/main/java/com/openfeint/memcached/transcoder/MarshalZlibTranscoder.java
83
+ - src/main/java/net/spy/memcached/KetamaNodeLocator.java
84
+ - src/main/java/net/spy/memcached/util/DefaultKetamaNodeLocatorConfiguration.java
85
+ - target/spymemcached-ext-0.0.1.jar
76
86
  homepage: https://github.com/aurorafeint/jruby-memcached
77
87
  licenses: []
78
-
79
- post_install_message:
88
+ post_install_message:
80
89
  rdoc_options: []
81
-
82
- require_paths:
83
- - lib
84
- required_ruby_version: !ruby/object:Gem::Requirement
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ segments:
97
+ - 0
98
+ hash: 2
99
+ version: !binary |-
100
+ MA==
85
101
  none: false
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: "0"
90
- required_rubygems_version: !ruby/object:Gem::Requirement
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ segments:
107
+ - 0
108
+ hash: 2
109
+ version: !binary |-
110
+ MA==
91
111
  none: false
92
- requirements:
93
- - - ">="
94
- - !ruby/object:Gem::Version
95
- version: "0"
96
112
  requirements: []
97
-
98
- rubyforge_project:
113
+ rubyforge_project:
99
114
  rubygems_version: 1.8.24
100
- signing_key:
115
+ signing_key:
101
116
  specification_version: 3
102
117
  summary: jruby compatible memcached client
103
- test_files:
104
- - spec/memcached_spec.rb
105
- - spec/rails_spec.rb
106
- - spec/spec_helper.rb
118
+ test_files:
119
+ - spec/memcached_spec.rb
120
+ - spec/rails_spec.rb
121
+ - spec/spec_helper.rb
122
+ - spec/timeout_spec.rb
@@ -1,30 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- jruby-memcached (0.5.0)
5
-
6
- GEM
7
- remote: http://rubygems.org/
8
- specs:
9
- diff-lcs (1.1.3)
10
- metaclass (0.0.1)
11
- mocha (0.12.1)
12
- metaclass (~> 0.0.1)
13
- rake (0.9.2.2)
14
- rspec (2.11.0)
15
- rspec-core (~> 2.11.0)
16
- rspec-expectations (~> 2.11.0)
17
- rspec-mocks (~> 2.11.0)
18
- rspec-core (2.11.1)
19
- rspec-expectations (2.11.1)
20
- diff-lcs (~> 1.1.3)
21
- rspec-mocks (2.11.1)
22
-
23
- PLATFORMS
24
- java
25
-
26
- DEPENDENCIES
27
- jruby-memcached!
28
- mocha
29
- rake
30
- rspec