rjb 1.2.0 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog CHANGED
@@ -1,3 +1,39 @@
1
+ Sun May 30 arton
2
+ *lib/rjbextension.rb
3
+ Rjb extension from Andreas Ronge's neo4j
4
+ - directly import jar by require method
5
+ - Rjb::import without quotations (Java class as Ruby object)
6
+ *test/exttest.rb
7
+ test for rjbextension.rb
8
+ *test/rjbtest.jar
9
+ test file for rjbextension.rb
10
+ Sat May 29 arton on behalf of atoulme
11
+ *ext/rjb.c
12
+ *ext/load.c
13
+ *ext/rjbexception.c
14
+ to accomodate with rubinius
15
+ thanks atoulme !
16
+ Wed May 12 arton
17
+ *test/test.rb
18
+ add Class name for TestMixin module because ruby 1.9 doesn't handle the constant.
19
+ Tue May 11 arton
20
+ *ext/rjb.c
21
+ fix duplicate method registering while no alias.
22
+ add class methods for inspecting method signatures.
23
+ add class_eval method for extending Java class
24
+ *test/test.rb
25
+ add class methods test for inspecting method signatures.
26
+ add mixin tests
27
+ Tue May 4 arton
28
+ *ext/load.c
29
+ corrected wrong function signature (BUG#28088), pointed and fixed by Romulo A. Ceccon (thanks)
30
+ *ext/rjb.c
31
+ using inheritance check while inspecting a object is RJB's instance (for extending it).
32
+ Tue Mar 16 arton
33
+ *ext/riconv.c
34
+ change locale setting "" to "C", fixed by Fabien Sartor (rjb-Bugs-27968)
35
+ *ext/rjb.c
36
+ RJB_VERSION -> 1.2.1
1
37
  Sun Nov 1 arton
2
38
  *ext/load.c
3
39
  load jvm pointed by JVM_LIB environment variable first (suggested by Ittay Dror).
data/ext/load.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Rjb - Ruby <-> Java Bridge
3
- * Copyright(c) 2004,2005,2006,2009 arton
3
+ * Copyright(c) 2004,2005,2006,2009,2010 arton
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -12,7 +12,7 @@
12
12
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
13
  * Lesser General Public License for more details.
14
14
  *
15
- * $Id: load.c 102 2009-11-01 14:01:41Z arton $
15
+ * $Id: load.c 112 2010-05-29 03:09:11Z arton $
16
16
  */
17
17
 
18
18
  #include <stdlib.h>
@@ -90,8 +90,8 @@
90
90
  #define GETDEFAULTJVMINITARGS "JNI_GetDefaultJavaVMInitArgs"
91
91
  #endif
92
92
 
93
- typedef int (*GETDEFAULTJAVAVMINITARGS)(void*);
94
- typedef int (*CREATEJAVAVM)(JavaVM**, JNIEnv**, void*);
93
+ typedef int (JNICALL *GETDEFAULTJAVAVMINITARGS)(void*);
94
+ typedef int (JNICALL *CREATEJAVAVM)(JavaVM**, JNIEnv**, void*);
95
95
 
96
96
 
97
97
  static VALUE jvmdll = Qnil;
@@ -295,7 +295,8 @@ int rjb_create_jvm(JNIEnv** pjenv, JavaVMInitArgs* vm_args, char* userpath, VALU
295
295
  }
296
296
  #endif
297
297
  }
298
- #if RJB_RUBY_VERSION_CODE < 190
298
+
299
+ #if RJB_RUBY_VERSION_CODE < 190 && !defined(RUBINIUS)
299
300
  ruby_errinfo = Qnil;
300
301
  #else
301
302
  rb_set_errinfo(Qnil);
@@ -366,4 +367,3 @@ int rjb_create_jvm(JNIEnv** pjenv, JavaVMInitArgs* vm_args, char* userpath, VALU
366
367
  }
367
368
  return result;
368
369
  }
369
-
@@ -12,7 +12,7 @@
12
12
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
13
  * Lesser General Public License for more details.
14
14
  *
15
- * $Id: riconv.c 65 2008-03-26 13:19:29Z arton $
15
+ * $Id: riconv.c 104 2010-03-16 12:19:18Z arton $
16
16
  */
17
17
 
18
18
  #include "ruby.h"
@@ -98,14 +98,14 @@ static const char* get_charcode_name()
98
98
  #if defined _WIN32 || defined __CYGWIN__
99
99
  if (932 == GetACP()) result = CS_CP932;
100
100
  #elif defined HAVE_NL_LANGINFO
101
- setlocale(LC_ALL, ""); //initialize
101
+ setlocale(LC_ALL, "C"); //initialize
102
102
  lang = nl_langinfo(CODESET);
103
103
  if (find_table(lang, NL_EUC_TABLE))
104
104
  result = CS_EUCJP;
105
105
  else if (find_table(lang, NL_SJIS_TABLE))
106
106
  result = CS_SJIS;
107
107
  #elif defined HAVE_SETLOCALE
108
- setlocale(LC_ALL, ""); //initialize
108
+ setlocale(LC_ALL, "C"); //initialize
109
109
  result = get_charcode_name_by_locale(setlocale(LC_ALL, NULL));
110
110
  #elif defined HAVE_GETENV
111
111
  if (result = get_charcode_name_by_locale(getenv("LC_ALL")))
data/ext/rjb.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Rjb - Ruby <-> Java Bridge
3
- * Copyright(c) 2004,2005,2006,2007,2008,2009 arton
3
+ * Copyright(c) 2004,2005,2006,2007,2008,2009,2010 arton
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -12,10 +12,10 @@
12
12
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
13
  * Lesser General Public License for more details.
14
14
  *
15
- * $Id: rjb.c 102 2009-11-01 14:01:41Z arton $
15
+ * $Id: rjb.c 112 2010-05-29 03:09:11Z arton $
16
16
  */
17
17
 
18
- #define RJB_VERSION "1.2.0"
18
+ #define RJB_VERSION "1.2.2"
19
19
 
20
20
  #include "ruby.h"
21
21
  #include "extconf.h"
@@ -55,10 +55,12 @@
55
55
  #define RJB_LOAD_STATIC_METHOD(var, obj, name, sig) \
56
56
  var = (*jenv)->GetStaticMethodID(jenv, obj, name, sig); \
57
57
  rjb_check_exception(jenv, 1)
58
+ #define IS_RJB_OBJECT(v) (rb_class_inherited(rjbi, rb_obj_class(v)) || rb_obj_class(v) == rjb)
59
+ #define USER_INITIALIZE "@user_initialize"
58
60
 
59
61
  static void register_class(VALUE, VALUE);
60
62
  static VALUE import_class(JNIEnv* jenv, jclass, VALUE);
61
- static VALUE register_instance(JNIEnv* jenv, struct jvi_data*, jobject);
63
+ static VALUE register_instance(JNIEnv* jenv, VALUE klass, struct jv_data*, jobject);
62
64
  static VALUE rjb_s_free(struct jv_data*);
63
65
  static VALUE rjb_class_forname(int argc, VALUE* argv, VALUE self);
64
66
  static void setup_metadata(JNIEnv* jenv, VALUE self, struct jv_data*, VALUE classname);
@@ -73,6 +75,8 @@ static VALUE rjbc;
73
75
  static VALUE rjbi;
74
76
  static VALUE rjbb;
75
77
 
78
+ static ID user_initialize;
79
+
76
80
  VALUE rjb_loaded_classes;
77
81
  static VALUE proxies;
78
82
  JavaVM* rjb_jvm;
@@ -286,7 +290,7 @@ static VALUE jv2rv_r(JNIEnv* jenv, jvalue val)
286
290
  v = import_class(jenv, klass, clsname);
287
291
  }
288
292
  Data_Get_Struct(v, struct jv_data, ptr);
289
- v = register_instance(jenv, (struct jvi_data*)ptr, val.l);
293
+ v = register_instance(jenv, v, (struct jv_data*)ptr, val.l);
290
294
  (*jenv)->DeleteLocalRef(jenv, klass);
291
295
  (*jenv)->DeleteLocalRef(jenv, val.l);
292
296
  return v;
@@ -673,8 +677,7 @@ static void rv2jstring(JNIEnv* jenv, VALUE val, jvalue* jv, const char* psig, in
673
677
  {
674
678
  if (!release)
675
679
  {
676
- if (TYPE(val) == T_DATA
677
- && (RBASIC(val)->klass == rjbi || RBASIC(val)->klass == rjb))
680
+ if (TYPE(val) == T_DATA && IS_RJB_OBJECT(val))
678
681
  {
679
682
  struct jvi_data* ptr;
680
683
  Data_Get_Struct(val, struct jvi_data, ptr);
@@ -710,7 +713,7 @@ static void rv2jstring(JNIEnv* jenv, VALUE val, jvalue* jv, const char* psig, in
710
713
  {
711
714
  if (TYPE(val) == T_DATA)
712
715
  {
713
- if (RBASIC(val)->klass == rjbi || RBASIC(val)->klass == rjb)
716
+ if (IS_RJB_OBJECT(val))
714
717
  {
715
718
  struct jvi_data* ptr;
716
719
  Data_Get_Struct(val, struct jvi_data, ptr);
@@ -764,20 +767,20 @@ static void rv2jobject(JNIEnv* jenv, VALUE val, jvalue* jv, const char* psig, in
764
767
  switch (TYPE(val))
765
768
  {
766
769
  case T_DATA:
767
- if (RBASIC(val)->klass == rjbi || RBASIC(val)->klass == rjb)
770
+ if (IS_RJB_OBJECT(val))
768
771
  {
769
- /* TODO: check instanceof (class (in psig) ) */
772
+ /* TODO: check instanceof (class (in psig) ) */
770
773
  struct jvi_data* ptr;
771
774
  Data_Get_Struct(val, struct jvi_data, ptr);
772
775
  jv->l = ptr->obj;
773
776
  }
774
- else if (RBASIC(val)->klass == rjbb)
777
+ else if (rb_obj_class(val) == rjbb)
775
778
  {
776
779
  struct rj_bridge* ptr;
777
780
  Data_Get_Struct(val, struct rj_bridge, ptr);
778
781
  jv->l = ptr->proxy;
779
782
  }
780
- else if (rb_class_inherited(rjbc, RBASIC(val)->klass))
783
+ else if (rb_class_inherited(rjbc, rb_obj_class(val)))
781
784
  {
782
785
  struct jv_data* ptr;
783
786
  Data_Get_Struct(val, struct jv_data, ptr);
@@ -1327,14 +1330,16 @@ static struct cls_method* clone_methodinfo(struct cls_method* pm)
1327
1330
  return result;
1328
1331
  }
1329
1332
 
1330
- static void make_alias(const char* jname, char* rname)
1333
+ static int make_alias(const char* jname, char* rname)
1331
1334
  {
1335
+ int ret = 0;
1332
1336
  while (*jname)
1333
1337
  {
1334
1338
  if (isupper(*jname))
1335
1339
  {
1336
1340
  *rname++ = '_';
1337
1341
  *rname++ = tolower(*jname++);
1342
+ ret = 1;
1338
1343
  }
1339
1344
  else
1340
1345
  {
@@ -1342,6 +1347,7 @@ static void make_alias(const char* jname, char* rname)
1342
1347
  }
1343
1348
  }
1344
1349
  *rname = '\0';
1350
+ return ret;
1345
1351
  }
1346
1352
 
1347
1353
  static void create_methodinfo(JNIEnv* jenv, st_table* tbl, jobject m, int static_method)
@@ -1349,6 +1355,7 @@ static void create_methodinfo(JNIEnv* jenv, st_table* tbl, jobject m, int static
1349
1355
  struct cls_method* result;
1350
1356
  struct cls_method* pm;
1351
1357
  const char* jname;
1358
+ int alias;
1352
1359
  jstring nm;
1353
1360
  jobjectArray parama;
1354
1361
  jobject cls;
@@ -1365,7 +1372,7 @@ static void create_methodinfo(JNIEnv* jenv, st_table* tbl, jobject m, int static
1365
1372
  rjb_check_exception(jenv, 0);
1366
1373
  jname = (*jenv)->GetStringUTFChars(jenv, nm, NULL);
1367
1374
  rname = ALLOCA_N(char, strlen(jname) * 2 + 8);
1368
- make_alias(jname, rname);
1375
+ alias = make_alias(jname, rname);
1369
1376
  result->name = rb_intern(jname);
1370
1377
  rjb_release_string(jenv, nm, jname);
1371
1378
  result->basic.id = (*jenv)->FromReflectedMethod(jenv, m);
@@ -1404,7 +1411,7 @@ static void create_methodinfo(JNIEnv* jenv, st_table* tbl, jobject m, int static
1404
1411
  if (*rname == '_') rname++;
1405
1412
  strcat(rname, "?");
1406
1413
  }
1407
- else
1414
+ else if (alias)
1408
1415
  {
1409
1416
  pm = clone_methodinfo(result);
1410
1417
  }
@@ -1589,14 +1596,14 @@ static void load_constants(JNIEnv* jenv, jclass klass, VALUE self, jobjectArray
1589
1596
  strcpy(pname, cname);
1590
1597
  *pname = toupper(*pname);
1591
1598
  if (!isupper(*pname)
1592
- || rb_const_defined(RBASIC(self)->klass, rb_intern(pname)))
1599
+ || rb_const_defined(rb_obj_class(self), rb_intern(pname)))
1593
1600
  {
1594
1601
  pname = NULL;
1595
1602
  }
1596
1603
  }
1597
1604
  if (pname)
1598
1605
  {
1599
- rb_define_const(RBASIC(self)->klass, pname, j2r(jenv, jv));
1606
+ rb_define_const(rb_obj_class(self), pname, j2r(jenv, jv));
1600
1607
  }
1601
1608
  rjb_release_string(jenv, nm, cname);
1602
1609
  }
@@ -1728,7 +1735,8 @@ static VALUE rjb_s_load(int argc, VALUE* argv, VALUE self)
1728
1735
  }
1729
1736
 
1730
1737
  jklass = import_class(jenv, j_class, rb_str_new2("java.lang.Class"));
1731
- rb_define_method(RBASIC(jklass)->klass, "forName", rjb_class_forname, -1);
1738
+ rb_define_method(rb_singleton_class(jklass), "forName", rjb_class_forname, -1);
1739
+ rb_define_method(rb_singleton_class(jklass), "for_name", rjb_class_forname, -1);
1732
1740
  rb_gc_register_address(&jklass);
1733
1741
 
1734
1742
  return Qnil;
@@ -1745,6 +1753,18 @@ VALUE rjb_load_vm_default()
1745
1753
  return rjb_s_load(0, NULL, 0);
1746
1754
  }
1747
1755
 
1756
+ /*
1757
+ * common prelude
1758
+ */
1759
+ JNIEnv* rjb_prelude()
1760
+ {
1761
+ JNIEnv* jenv = NULL;
1762
+ rjb_load_vm_default();
1763
+ jenv = rjb_attach_current_thread();
1764
+ (*jenv)->ExceptionClear(jenv);
1765
+ return jenv;
1766
+ }
1767
+
1748
1768
  /*
1749
1769
  * unload Java Virtual Machine
1750
1770
  *
@@ -1760,7 +1780,16 @@ static int clear_classes(VALUE key, VALUE val, VALUE dummy)
1760
1780
  static VALUE rjb_s_unload(int argc, VALUE* argv, VALUE self)
1761
1781
  {
1762
1782
  int result = 0;
1783
+ #ifdef HAVE_RB_HASH_FOREACH
1784
+ rb_hash_foreach(rjb_loaded_classes, clear_classes, 0);
1785
+ #else
1786
+ #ifdef RHASH_TBL
1763
1787
  st_foreach(RHASH_TBL(rjb_loaded_classes), clear_classes, 0);
1788
+ #else
1789
+ st_foreach(RHASH(rjb_loaded_classes)->tbl, clear_classes, 0);
1790
+ #endif
1791
+ #endif
1792
+
1764
1793
  if (rjb_jvm)
1765
1794
  {
1766
1795
  JNIEnv* jenv = rjb_attach_current_thread();
@@ -1883,14 +1912,19 @@ static VALUE rjb_s_free(struct jv_data* ptr)
1883
1912
  * create new instance of this class
1884
1913
  */
1885
1914
  static VALUE createinstance(JNIEnv* jenv, int argc, VALUE* argv,
1886
- struct jvi_data* org, struct cls_constructor* pc)
1915
+ VALUE self, struct cls_constructor* pc)
1887
1916
  {
1888
1917
  int i;
1889
1918
  char* psig = pc->method_signature;
1890
1919
  jobject obj = NULL;
1891
1920
  VALUE result;
1892
-
1921
+ struct jv_data* jklass;
1922
+ struct jvi_data* org;
1893
1923
  jvalue* args = (argc) ? ALLOCA_N(jvalue, argc) : NULL;
1924
+
1925
+ Data_Get_Struct(self, struct jv_data, jklass);
1926
+ org = &jklass->idata;
1927
+
1894
1928
  for (i = 0; i < argc; i++)
1895
1929
  {
1896
1930
  R2J pr2j = *(pc->arg_convert + i);
@@ -1911,7 +1945,7 @@ static VALUE createinstance(JNIEnv* jenv, int argc, VALUE* argv,
1911
1945
  psig = next_sig(psig);
1912
1946
  }
1913
1947
 
1914
- result = register_instance(jenv, org, obj);
1948
+ result = register_instance(jenv, self, jklass, obj);
1915
1949
  (*jenv)->DeleteLocalRef(jenv, obj);
1916
1950
  return result;
1917
1951
  }
@@ -1941,16 +1975,29 @@ static VALUE import_class(JNIEnv* jenv, jclass jcls, VALUE clsname)
1941
1975
  return v;
1942
1976
  }
1943
1977
 
1944
- static VALUE register_instance(JNIEnv* jenv, struct jvi_data* org, jobject obj)
1978
+ static VALUE rjb_i_prepare_proxy(VALUE self)
1979
+ {
1980
+ return rb_funcall(self, rb_intern("instance_eval"), 1,
1981
+ rb_str_new2("instance_eval &" USER_INITIALIZE));
1982
+ }
1983
+
1984
+ static VALUE register_instance(JNIEnv* jenv, VALUE klass, struct jv_data* org, jobject obj)
1945
1985
  {
1946
1986
  VALUE v;
1987
+ VALUE iproc;
1947
1988
  struct jvi_data* ptr = ALLOC(struct jvi_data);
1948
1989
  memset(ptr, 0, sizeof(struct jvi_data));
1949
1990
  v = Data_Wrap_Struct(rjbi, NULL, rjb_delete_ref, ptr);
1950
- ptr->klass = org->obj;
1991
+ ptr->klass = org->idata.obj;
1951
1992
  ptr->obj = (*jenv)->NewGlobalRef(jenv, obj);
1952
- ptr->methods = org->methods;
1953
- ptr->fields = org->fields;
1993
+ ptr->methods = org->idata.methods;
1994
+ ptr->fields = org->idata.fields;
1995
+ iproc = rb_ivar_get(klass, user_initialize);
1996
+ if (iproc != Qnil)
1997
+ {
1998
+ rb_ivar_set(v, user_initialize, iproc);
1999
+ rb_funcall(v, rb_intern("_prepare_proxy"), 0, 0);
2000
+ }
1954
2001
  return v;
1955
2002
  }
1956
2003
 
@@ -1990,7 +2037,7 @@ static int check_rtype(JNIEnv* jenv, VALUE v, char* p)
1990
2037
  case T_ARRAY:
1991
2038
  return *p == '[';
1992
2039
  case T_DATA:
1993
- if (RBASIC(v)->klass == rjbi && pcls)
2040
+ if (IS_RJB_OBJECT(v) && pcls)
1994
2041
  {
1995
2042
  /* imported object */
1996
2043
  jclass cls;
@@ -2028,11 +2075,7 @@ static VALUE rjb_newinstance_s(int argc, VALUE* argv, VALUE self)
2028
2075
  VALUE ret = Qnil;
2029
2076
  struct jv_data* ptr;
2030
2077
  int found = 0;
2031
- JNIEnv* jenv = NULL;
2032
-
2033
- rjb_load_vm_default();
2034
- jenv = rjb_attach_current_thread();
2035
- (*jenv)->ExceptionClear(jenv);
2078
+ JNIEnv* jenv = rjb_prelude();
2036
2079
 
2037
2080
  rb_scan_args(argc, argv, "1*", &vsig, &rest);
2038
2081
  sig = StringValueCStr(vsig);
@@ -2046,7 +2089,7 @@ static VALUE rjb_newinstance_s(int argc, VALUE* argv, VALUE self)
2046
2089
  && !strcmp(sig, (*pc)->method_signature))
2047
2090
  {
2048
2091
  found = 1;
2049
- ret = createinstance(jenv, argc - 1, argv + 1, &ptr->idata, *pc);
2092
+ ret = createinstance(jenv, argc - 1, argv + 1, self, *pc);
2050
2093
  break;
2051
2094
  }
2052
2095
  }
@@ -2063,12 +2106,8 @@ static VALUE rjb_newinstance(int argc, VALUE* argv, VALUE self)
2063
2106
  struct jv_data* ptr;
2064
2107
  struct cls_constructor** pc;
2065
2108
  int found = 0;
2066
- JNIEnv* jenv = NULL;
2109
+ JNIEnv* jenv = rjb_prelude();
2067
2110
 
2068
- rjb_load_vm_default();
2069
- jenv = rjb_attach_current_thread();
2070
- (*jenv)->ExceptionClear(jenv);
2071
-
2072
2111
  Data_Get_Struct(self, struct jv_data, ptr);
2073
2112
 
2074
2113
  if (ptr->constructors)
@@ -2092,7 +2131,7 @@ static VALUE rjb_newinstance(int argc, VALUE* argv, VALUE self)
2092
2131
  }
2093
2132
  if (found)
2094
2133
  {
2095
- ret = createinstance(jenv, argc, argv, &ptr->idata, *pc);
2134
+ ret = createinstance(jenv, argc, argv, self, *pc);
2096
2135
  break;
2097
2136
  }
2098
2137
  }
@@ -2118,18 +2157,71 @@ jclass rjb_find_class(JNIEnv* jenv, VALUE name)
2118
2157
  return (*jenv)->FindClass(jenv, java2jniname(jnicls));
2119
2158
  }
2120
2159
 
2160
+ /*
2161
+ * get specified method signature
2162
+ */
2163
+ static VALUE get_signatures(VALUE mname, st_table* st)
2164
+ {
2165
+ VALUE ret;
2166
+ struct cls_method* pm;
2167
+ ID rmid = rb_to_id(mname);
2168
+
2169
+ if (!st_lookup(st, rmid, (st_data_t*)&pm))
2170
+ {
2171
+ const char* tname = rb_id2name(rmid);
2172
+ rb_raise(rb_eRuntimeError, "Fail: unknown method name `%s'", tname);
2173
+ }
2174
+ ret = rb_ary_new();
2175
+ for (; pm; pm = pm->next)
2176
+ {
2177
+ rb_ary_push(ret, rb_str_new2(pm->basic.method_signature));
2178
+ }
2179
+ return ret;
2180
+ }
2181
+
2182
+ static VALUE rjb_get_signatures(VALUE self, VALUE mname)
2183
+ {
2184
+ struct jv_data* ptr;
2185
+
2186
+ Data_Get_Struct(self, struct jv_data, ptr);
2187
+ return get_signatures(mname, ptr->idata.methods);
2188
+ }
2189
+
2190
+ static VALUE rjb_get_static_signatures(VALUE self, VALUE mname)
2191
+ {
2192
+ struct jv_data* ptr;
2193
+
2194
+ Data_Get_Struct(self, struct jv_data, ptr);
2195
+ return get_signatures(mname, ptr->static_methods);
2196
+ }
2197
+
2198
+ static VALUE rjb_get_ctor_signatures(VALUE self)
2199
+ {
2200
+ VALUE ret;
2201
+ struct jv_data* ptr;
2202
+ struct cls_constructor** pc;
2203
+
2204
+ Data_Get_Struct(self, struct jv_data, ptr);
2205
+ ret = rb_ary_new();
2206
+ if (ptr->constructors)
2207
+ {
2208
+ for (pc = ptr->constructors; *pc; pc++)
2209
+ {
2210
+ rb_ary_push(ret, rb_str_new2((*pc)->method_signature));
2211
+ }
2212
+ }
2213
+ return ret;
2214
+ }
2215
+
2121
2216
  /*
2122
2217
  * jclass Rjb::bind(rbobj, interface_name)
2123
2218
  */
2124
2219
  static VALUE rjb_s_bind(VALUE self, VALUE rbobj, VALUE itfname)
2125
2220
  {
2126
2221
  VALUE result = Qnil;
2127
- JNIEnv* jenv = NULL;
2128
2222
  jclass itf;
2223
+ JNIEnv* jenv = rjb_prelude();
2129
2224
 
2130
- rjb_load_vm_default();
2131
- jenv = rjb_attach_current_thread();
2132
- (*jenv)->ExceptionClear(jenv);
2133
2225
  itf = rjb_find_class(jenv, itfname);
2134
2226
  rjb_check_exception(jenv, 1);
2135
2227
  if (itf)
@@ -2154,15 +2246,24 @@ static VALUE rjb_s_bind(VALUE self, VALUE rbobj, VALUE itfname)
2154
2246
  return result;
2155
2247
  }
2156
2248
 
2249
+ /*
2250
+ * Rjb's class is not Class but Object, so add class_eval for the Java class.
2251
+ */
2252
+ static VALUE rjb_class_eval(int argc, VALUE* argv, VALUE self)
2253
+ {
2254
+ if (rb_block_given_p())
2255
+ {
2256
+ rb_ivar_set(self, user_initialize, rb_block_proc());
2257
+ }
2258
+ return self;
2259
+ }
2260
+
2157
2261
  /*
2158
2262
  * jclass Rjb::bind(rbobj, interface_name)
2159
2263
  */
2160
2264
  static VALUE rjb_s_unbind(VALUE self, VALUE rbobj)
2161
2265
  {
2162
- JNIEnv* jenv;
2163
- rjb_load_vm_default();
2164
- jenv = rjb_attach_current_thread();
2165
- (*jenv)->ExceptionClear(jenv);
2266
+ JNIEnv* jenv = rjb_prelude();
2166
2267
  return rb_ary_delete(proxies, rbobj);
2167
2268
  }
2168
2269
 
@@ -2179,9 +2280,7 @@ static VALUE rjb_s_import(VALUE self, VALUE clsname)
2179
2280
  return v;
2180
2281
  }
2181
2282
 
2182
- rjb_load_vm_default();
2183
- jenv = rjb_attach_current_thread();
2184
- (*jenv)->ExceptionClear(jenv);
2283
+ jenv = rjb_prelude();
2185
2284
  jcls = rjb_find_class(jenv, clsname);
2186
2285
  if (!jcls)
2187
2286
  {
@@ -2196,10 +2295,23 @@ static void register_class(VALUE self, VALUE clsname)
2196
2295
  {
2197
2296
  rb_define_singleton_method(self, "new", rjb_newinstance, -1);
2198
2297
  rb_define_singleton_method(self, "new_with_sig", rjb_newinstance_s, -1);
2298
+ rb_define_singleton_method(self, "class_eval", rjb_class_eval, -1);
2299
+ rb_define_singleton_method(self, "sigs", rjb_get_signatures, 1);
2300
+ rb_define_singleton_method(self, "static_sigs", rjb_get_static_signatures, 1);
2301
+ rb_define_singleton_method(self, "ctor_sigs", rjb_get_ctor_signatures, 0);
2199
2302
  /*
2200
2303
  * the hash was frozen, so it need to call st_ func directly.
2201
2304
  */
2305
+
2306
+ #ifdef HAVE_RB_HASH_ASET
2307
+ rb_hash_aset(rjb_loaded_classes, clsname, self);
2308
+ #else
2309
+ #ifdef RHASH_TBL
2202
2310
  st_insert(RHASH_TBL(rjb_loaded_classes), clsname, self);
2311
+ #else
2312
+ st_insert(RHASH(rjb_loaded_classes)->tbl, clsname, self);
2313
+ #endif
2314
+ #endif
2203
2315
  }
2204
2316
 
2205
2317
  /*
@@ -2702,7 +2814,7 @@ static VALUE rjb_missing(int argc, VALUE* argv, VALUE self)
2702
2814
  {
2703
2815
  VALUE r, args[2];
2704
2816
  int state = 0;
2705
- args[0] = RBASIC(self)->klass;
2817
+ args[0] = rb_obj_class(self);
2706
2818
  args[1] = rmid;
2707
2819
  r = rb_protect(find_const, (VALUE)args, &state);
2708
2820
  if (!state)
@@ -2741,10 +2853,13 @@ void Init_rjbcore()
2741
2853
  rb_protect((VALUE(*)(VALUE))rb_require, (VALUE)"iconv", NULL);
2742
2854
 
2743
2855
  rjb_loaded_classes = rb_hash_new();
2856
+ #ifndef RUBINIUS
2744
2857
  OBJ_FREEZE(rjb_loaded_classes);
2858
+ #endif
2745
2859
  rb_global_variable(&rjb_loaded_classes);
2746
2860
  proxies = rb_ary_new();
2747
2861
  rb_global_variable(&proxies);
2862
+ user_initialize = rb_intern(USER_INITIALIZE);
2748
2863
 
2749
2864
  rjb = rb_define_module("Rjb");
2750
2865
  rb_define_module_function(rjb, "load", rjb_s_load, -1);
@@ -2763,7 +2878,7 @@ void Init_rjbcore()
2763
2878
  rb_gc_register_address(&rjbc);
2764
2879
  rb_define_method(rjbc, "method_missing", rjb_missing, -1);
2765
2880
  rb_define_method(rjbc, "_invoke", rjb_invoke, -1);
2766
- rb_define_method(rjbc, "_classname", rjb_i_class, 0);
2881
+ rb_define_method(rjbc, "_classname", rjb_i_class, 0);
2767
2882
 
2768
2883
  /* Java instance object */
2769
2884
  rjbi = rb_class_new(rb_cObject);
@@ -2771,6 +2886,8 @@ void Init_rjbcore()
2771
2886
  rb_define_method(rjbi, "method_missing", rjb_i_missing, -1);
2772
2887
  rb_define_method(rjbi, "_invoke", rjb_i_invoke, -1);
2773
2888
  rb_define_method(rjbi, "_classname", rjb_i_class, 0);
2889
+ rb_define_method(rjbi, "_prepare_proxy", rjb_i_prepare_proxy, 0);
2890
+ rb_define_alias(rjbi, "include", "extend");
2774
2891
 
2775
2892
  /* Ruby-Java Bridge object */
2776
2893
  rjbb = rb_class_new(rb_cObject);
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Rjb - Ruby <-> Java Bridge
3
- * Copyright(c) 2004,2005,2006 arton
3
+ * Copyright(c) 2004,2005,2006,2010 arton
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -12,7 +12,7 @@
12
12
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
13
  * Lesser General Public License for more details.
14
14
  *
15
- * $Id: rjbexception.c 94 2009-09-10 13:54:42Z arton $
15
+ * $Id: rjbexception.c 112 2010-05-29 03:09:11Z arton $
16
16
  */
17
17
 
18
18
  #include "ruby.h"
@@ -54,7 +54,16 @@ VALUE rjb_get_exception_class(JNIEnv* jenv, jstring str)
54
54
  if (rexp == Qnil)
55
55
  {
56
56
  rexp = rb_define_class(pcls, rb_eStandardError);
57
- st_insert(RHASH_TBL(rjb_loaded_classes), cname, rexp);
57
+ #ifdef HAVE_RB_HASH_ASET
58
+ rb_hash_aset(rjb_loaded_classes, cname, rexp);
59
+ #else
60
+ #ifdef RHASH_TBL
61
+ st_insert(RHASH_TBL(rjb_loaded_classes), cname, rexp);
62
+ #else
63
+ st_insert(RHASH(rjb_loaded_classes)->tbl, cname, rexp);
64
+ #endif
65
+ #endif
66
+
58
67
  }
59
68
  return rexp;
60
69
  }
@@ -137,4 +146,3 @@ void rjb_check_exception(JNIEnv* jenv, int t)
137
146
  }
138
147
  }
139
148
  }
140
-
data/lib/rjb.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  =begin
2
- Copyright(c) 2006 arton
2
+ Copyright(c) 2006-2010 arton
3
3
  =end
4
4
 
5
5
  require 'rbconfig'
@@ -20,3 +20,4 @@ end
20
20
 
21
21
  require 'rjbcore'
22
22
 
23
+
@@ -0,0 +1,135 @@
1
+ =begin
2
+ Copyright(c) 2010 arton
3
+
4
+ This library is free software; you can redistribute it and/or
5
+ modify it under the terms of the GNU Lesser General Public
6
+ License as published by the Free Software Foundation; either
7
+ version 2.1 of the License, or (at your option) any later version.
8
+
9
+ This library is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ Lesser General Public License for more details.
13
+
14
+ $Id:$
15
+
16
+ This file is from Andreas Ronge project neo4j
17
+ http://github.com/andreasronge/neo4j/blob/rjb/lib/rjb_ext.rb
18
+
19
+ Copyright (c) 2008 Andreas Ronge
20
+
21
+ Permission is hereby granted, free of charge, to any person obtaining a copy
22
+ of this software and associated documentation files (the "Software"), to deal
23
+ in the Software without restriction, including without limitation the rights
24
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25
+ copies of the Software, and to permit persons to whom the Software is
26
+ furnished to do so, subject to the following conditions:
27
+
28
+ The above copyright notice and this permission notice shall be included in
29
+ all copies or substantial portions of the Software.
30
+
31
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
37
+ THE SOFTWARE.
38
+ =end
39
+
40
+ # Loads the JVM with the given <tt>classpath</tt> and arguments to the jre.
41
+ # All needed .jars should be included in <tt>classpath</tt>.
42
+
43
+ module Kernel
44
+ alias rjb_original_require require
45
+
46
+ def require(path)
47
+ rjb_original_require(path)
48
+ rescue LoadError
49
+ # check that it's not a jar file
50
+ raise unless path =~ /\.jar/
51
+
52
+ # This will maybe use the wrong jar file from a previous version of the GEM
53
+ # puts "LOAD PATH #{$LOAD_PATH}"
54
+ found_path = $LOAD_PATH.reverse.find{|p| File.exist?(File.join(p,path))}
55
+ raise unless found_path
56
+
57
+ abs_path = File.join(found_path, path)
58
+ # check that the file exists
59
+ raise unless File.exist?(abs_path)
60
+
61
+ # try to load it using RJB
62
+ @@rjb_jars ||= []
63
+ @@rjb_jars << abs_path unless @@rjb_jars.include?(abs_path)
64
+ # TODO
65
+ end
66
+
67
+ @@jvm_loaded = false
68
+
69
+ def load_jvm(jargs = [])
70
+ # avoid starting the JVM twice
71
+ return if @@jvm_loaded
72
+
73
+ @@jvm_loaded = true
74
+ classpath = ENV['CLASSPATH'] ||= ''
75
+ @@rjb_jars.each do |jar|
76
+ classpath += File::PATH_SEPARATOR unless classpath.empty?
77
+ classpath += jar
78
+ end
79
+ Rjb::load(classpath, jargs)
80
+ end
81
+ end
82
+
83
+ class JavaPackage
84
+
85
+ def initialize(pack_name, parent_pack = nil)
86
+ @pack_name = pack_name
87
+ @parent_pack = parent_pack
88
+ @cache = {}
89
+ end
90
+
91
+ def method_missing(m, *args)
92
+ # return if possible old module/class
93
+ @cache[m] ||= create_package_or_class(m)
94
+ end
95
+ def create_package_or_class(m)
96
+ method = m.to_s
97
+ if class?(method)
98
+ Rjb::import("#{self}.#{method}")
99
+ else
100
+ JavaPackage.new(method, self)
101
+ end
102
+ end
103
+
104
+ def to_s
105
+ if @parent_pack
106
+ "#{@parent_pack.to_s}.#@pack_name"
107
+ else
108
+ "#@pack_name"
109
+ end
110
+ end
111
+
112
+ def class?(a)
113
+ first_letter = a[0,1]
114
+ first_letter >= 'A' && first_letter <= 'Z'
115
+ end
116
+
117
+ @@cache = {}
118
+ def self.new(pack_name, parent_pack = nil)
119
+ @@cache[pack_name] ||= super
120
+ end
121
+ end
122
+
123
+ module RjbConf
124
+ # make them as singleton
125
+ ORG = JavaPackage.new('org')
126
+ JAVA = JavaPackage.new('java')
127
+ end
128
+
129
+ def org
130
+ RjbConf::ORG
131
+ end
132
+
133
+ def java
134
+ RjbConf::JAVA
135
+ end
@@ -0,0 +1,34 @@
1
+ #!/usr/local/env ruby -Ku
2
+ # encoding: utf-8
3
+ # $Id:$
4
+
5
+ begin
6
+ require 'rjb'
7
+ rescue LoadError
8
+ require 'rubygems'
9
+ require 'rjb'
10
+ end
11
+
12
+ if Rjb::VERSION < '1.2.2'
13
+ puts "Rjb #{Rjb::VERSION} does not support rjbextension. exit"
14
+ exit 0
15
+ end
16
+
17
+ require 'rjbextension'
18
+ require 'test/unit'
19
+
20
+ puts "start RJB(#{Rjb::VERSION}) test"
21
+ class ExtTestRjb < Test::Unit::TestCase
22
+
23
+ def jp
24
+ JavaPackage.new('jp')
25
+ end
26
+
27
+ def test_require_extension
28
+ require 'rjbtest.jar'
29
+ load_jvm
30
+
31
+ base = jp.co.infoseek.hp.arton.rjb.Base.new
32
+ assert_equal('hello', base.instance_var)
33
+ end
34
+ end
Binary file
@@ -1,6 +1,6 @@
1
1
  #!/usr/local/env ruby -Ku
2
2
  # encoding: utf-8
3
- # $Id: test.rb 87 2009-02-15 12:25:36Z arton $
3
+ # $Id: test.rb 111 2010-05-12 12:34:28Z arton $
4
4
 
5
5
  begin
6
6
  require 'rjb'
@@ -18,14 +18,14 @@ class TestRjb < Test::Unit::TestCase
18
18
  Rjb::primitive_conversion = false
19
19
 
20
20
  @jString = import('java.lang.String')
21
- @jInteger = Rjb::import('java.lang.Integer')
22
- @jShort = Rjb::import('java.lang.Short')
23
- @jDouble = Rjb::import('java.lang.Double')
24
- @jFloat = Rjb::import('java.lang.Float')
25
- @jBoolean = Rjb::import('java.lang.Boolean')
26
- @jByte = Rjb::import('java.lang.Byte')
27
- @jLong = Rjb::import('java.lang.Long')
28
- @jChar = Rjb::import('java.lang.Character')
21
+ @jInteger = import('java.lang.Integer')
22
+ @jShort = import('java.lang.Short')
23
+ @jDouble = import('java.lang.Double')
24
+ @jFloat = import('java.lang.Float')
25
+ @jBoolean = import('java.lang.Boolean')
26
+ @jByte = import('java.lang.Byte')
27
+ @jLong = import('java.lang.Long')
28
+ @jChar = import('java.lang.Character')
29
29
  end
30
30
 
31
31
  def teardown
@@ -650,5 +650,48 @@ class TestRjb < Test::Unit::TestCase
650
650
  assert_equal "can't create Java VM", $!.message
651
651
  end
652
652
  end
653
+
654
+ module TestMixin
655
+ def test_hello(s)
656
+ 'hello ' + s
657
+ end
658
+ end
659
+ def test_extend
660
+ @jString.class_eval do
661
+ include TestRjb::TestMixin
662
+ end
663
+ s = @jString.new
664
+ assert_equal('hello world', s.test_hello('world'))
665
+ end
666
+ def test_extend_with_factory
667
+ point = import('java.awt.Point')
668
+ point.class_eval do
669
+ include TestRjb::TestMixin
670
+ end
671
+ p = point.new(11, 12)
672
+ assert_equal(11, p.x)
673
+ assert_equal(12, p.y)
674
+ assert_equal('hello world', p.test_hello('world'))
675
+ p = p.location
676
+ assert_equal(11, p.x)
677
+ assert_equal(12, p.y)
678
+ assert_equal('hello world', p.test_hello('world'))
679
+ end
680
+ def test_fetch_method_signature
681
+ expected = ['I', 'II', 'Ljava.lang.String;', 'Ljava.lang.String;I']
682
+ sig = @jString.sigs('indexOf').sort
683
+ assert_equal(expected, sig)
684
+ end
685
+ def test_fetch_static_method_signature
686
+ expected = ['Ljava.lang.String;[Ljava.lang.Object;',
687
+ 'Ljava.util.Locale;Ljava.lang.String;[Ljava.lang.Object;']
688
+ sig = @jString.static_sigs('format').sort
689
+ assert_equal(expected, sig)
690
+ end
691
+ def test_fetch_ctor_signature
692
+ expected = ['I', 'Ljava.lang.String;']
693
+ sig = @jInteger.ctor_sigs.sort
694
+ assert_equal(expected, sig)
695
+ end
653
696
  end
654
697
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rjb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - arton
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-01 00:00:00 +09:00
12
+ date: 2010-05-30 00:00:00 +09:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -36,14 +36,17 @@ files:
36
36
  - ext/depend
37
37
  - data/rjb/jp/co/infoseek/hp/arton/rjb/RBridge.class
38
38
  - lib/rjb.rb
39
+ - lib/rjbextension.rb
39
40
  - samples/filechooser.rb
40
41
  - test/test.rb
42
+ - test/exttest.rb
41
43
  - test/gctest.rb
42
44
  - test/jp/co/infoseek/hp/arton/rjb/Base.class
43
45
  - test/jp/co/infoseek/hp/arton/rjb/IBase.class
44
46
  - test/jp/co/infoseek/hp/arton/rjb/Test.class
45
47
  - test/jp/co/infoseek/hp/arton/rjb/Test$TestTypes.class
46
48
  - test/jp/co/infoseek/hp/arton/rjb/ExtBase.class
49
+ - test/rjbtest.jar
47
50
  - COPYING
48
51
  - ChangeLog
49
52
  - readme.sj