2

I'm having an issue where I can see the fields of a Java class/object, but I can't actually access them. I can see the fields in two ways. Using this following code.

=>(require '[clojure.reflect :as r])    
=>(use '[clojure.pprint :only [print-table]])    
=>(print-table (sort-by :name (:members (r/reflect  myClass))))

And also, by creating an instance of the object. Let's say the fields are an int denoted a, a string denoted word , and a String ArrayList denoted mylist.

=>myObj
#<myClass 1 hello [world]>

In both cases, I can see that these fields exist. However, when I run the following code, I get the following error.

=>(. myObj mylist)
IllegalArgumentException No matching field found: mylist for class myClass clojure.lang.Reflector.getInstanceField (Reflector.java:271)

Does anyone have any idea what is going on?


In response to Nicolas Modrzyk's answer, I run (.-myFieild myObject) and get IllegalArgumentException No matching field found: myField for class myClass clojure.lang.Reflector.invokeNoArgInstanceMember (Reflector.java:308)

Additionally, these fields are not private. I have the Java source code in front of me.

3
  • They're probably private fields. You can't access them from clojure, just like you can't access them from java. Commented Jun 29, 2015 at 22:56
  • It would be very helpful if the question included at least part of the output from the call to print-table so we can tell what the actual field names are Commented Jun 29, 2015 at 22:56
  • Are the fields public? If not, the default access in Java is package. Your clojure code is probably running in a different one, then has no access. Please show us the Java code. Commented Jul 1, 2015 at 10:19

2 Answers 2

3

The correct notation for accessing java fields is slightly different:

   (.-fieldName instance)

Here is a full example with the java class File and its private field path:

    (require '[clojure.reflect :as r])   
    (use '[clojure.pprint :only [print-table]])    

    (import '[java.io File])
    (def f (File. "test.txt"))

    ; access a public static field
    (. File separator)
    ; "/"

    (print-table 
      (sort-by :name (:members (r/reflect  File))))

    (.-path f)
    ; java.lang.IllegalArgumentException: 
    ; No matching field found: path for class java.io.File

    (def field (.getDeclaredField File "path"))
    ; you need the below if the field is private
    (.setAccessible field true)

    ; get the value
    (.get field f)
    ; "test.txt"
Sign up to request clarification or add additional context in comments.

1 Comment

The - is not required, but is recommended.
0

Thumbnail's comment was correct. I wasn't aware of Java's default access being package. I have since accessed the fields through reflection. Thank you everyone for your help.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.