user=> (def p (new java.util.Hashtable))
#<Var: user/p>
user=> (. p (put "a" "1"))
nil
user=> (. p (put "b" "2"))
nil
user=> p
{b=2, a=1}
user=> (. (first (seq (. p (entrySet)))) (getClass))
class java.util.Hashtable$Entry
user=> (. (first (seq (. p (entrySet)))) (getKey))
java.lang.IllegalAccessException: Class clojure.lang.Reflector can not
access a member of class java.util.Hashtable$Entry with modifiers
"public"
at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:37)
at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:25)
at clojure.lang.Compiler$InstanceMethodExpr.eval(Compiler.java:770)
at clojure.lang.Compiler.eval(Compiler.java:2555)
at clojure.lang.Compiler.main(Compiler.java:2728)
Thanks,
Bill
I've added special handling for this situation in Reflector.java -
it's in SVN now, and will be in the next release. With the change your
code works fine.
Thanks,
Rich
(. (first (seq (. (. System (getProperties)) (entrySet)))) (toString))
It fails because toString() is a public method of a public super class
(java.lang.Object) of java.util.Hashtable$Entry. I think adding this
to the beginning of Reflector.getMethods() will help:
while (c != null && ! Modifier.isPublic(c.getModifiers())) {
c = c.getSuperclass();
}
if (c == null) {
return new ArrayList();
}
-Bill
static public List getMethods(Class c, int arity, String name,
boolean getStatics){
ArrayList methods = new ArrayList();
Class origC = c;
while (c != null && ! Modifier.isPublic(c.getModifiers())) {
c = c.getSuperclass();
}
if (c != null) {
Method[] allmethods = c.getMethods();
for(int i = 0; i < allmethods.length; i++)
{
if (name.equals(allmethods[i].getName()) &&
Modifier.isStatic(allmethods[i].getModifiers()) == getStatics &&
allmethods[i].getParameterTypes().length == arity) {
methods.add(allmethods[i]);
}
}
}
if (!getStatics) {
for (Class xface : origC.getInterfaces()) {
for (Method m : xface.getMethods()) {
if (name.equals(m.getName())) {
if (m.getParameterTypes().length == arity) {
methods.add(m);
}
}
}
}
}
return methods;
}
user=> (. (first (seq (. (. System (getProperties)) (entrySet))))
(toString))
"java.runtime.name=Java(TM) 2 Runtime Environment, Standard Edition"
In case you weren't aware, that can be written as:
(str (first (.. System (getProperties) (entrySet))))
utilizing:
'..' - the chaining dot operator
first seqs its arg
str === toString
Fix is in SVN.
Thanks for the feedback,
Rich