This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-12-04
Channels
- # admin-announcements (1)
- # adventofcode (98)
- # announcements (5)
- # asami (3)
- # babashka (24)
- # beginners (51)
- # bitcoin (3)
- # calva (24)
- # clj-kondo (73)
- # cljdoc (5)
- # cljs-dev (2)
- # clojure (15)
- # clojure-czech (3)
- # clojure-dev (27)
- # clojure-europe (7)
- # clojure-gamedev (1)
- # clojure-italy (2)
- # clojure-uk (1)
- # conjure (4)
- # cursive (18)
- # datahike (4)
- # datomic (3)
- # deps-new (7)
- # emacs (1)
- # events (10)
- # fulcro (5)
- # honeysql (4)
- # jackdaw (2)
- # java (13)
- # lsp (85)
- # meander (9)
- # membrane (1)
- # minecraft (1)
- # off-topic (45)
- # re-frame (16)
- # sql (17)
- # tools-deps (10)
- # vscode (9)
- # xtdb (8)
I'm trying to call a method on a static inner class. I have imported the inner class and its parent class (not sure of the terminology here) . I get an instance of the inner class, and reflection shows that it has the methods I want to invoke, yet I keep getting "No matching method" errors when trying to invoke them. Any tips?
;;;
;;;
(import '(org.web3j.crypto
StructuredDataEncoder
StructuredData
StructuredData$EIP712Message))
(let [sde (StructuredDataEncoder. valid-json-str)
^StructuredData$EIP712Message msg
;;returns a StructuredData$EIP712Message
(.jsonMessageObject sde)]
;; the msg has getMessage and getPrimaryType methods with zero arguments:
(run! println
(-> msg class .getMethods (->> (map str) (filter #(re-find #"\.get.+" %)))))
;; prints:
;; public java.lang.Object org.web3j.crypto.StructuredData$EIP712Message.getMessage()
;; public java.lang.String org.web3j.crypto.StructuredData$EIP712Message.getPrimaryType()
;; ...
;; however, both of these fail
(.getPrimaryType msg) ;; (.getMessage msg) also fails
;; IllegalArgumentException No matching method getPrimaryType found taking 0 args for class org.web3j.crypto.StructuredData$EIP712Message
)
Edit: maven dep is
org.web3j/core {:mvn/version "4.8.9"}
@jjttjj I don't see anything obvious wrong with it. I can't test it in a REPL without knowing what valid-json-str
is tho'... I tried but clearly that's a very specific structure?
@seancorfield Yes, sorry this is the valid-json-str
(def valid-json-str
"{
\"types\" : {
\"EIP712Domain\" : [
{\"name\" : \"name\", \"type\" : \"string\"},
{\"name\" : \"version\", \"type\" : \"string\"},
{\"name\" : \"chainId\", \"type\" : \"uint256\"},
{\"name\" : \"verifyingContract\", \"type\" : \"address\"}
],
\"Person\" : [
{\"name\" : \"name\", \"type\" : \"string\"},
{\"name\" : \"wallet\", \"type\" : \"address\"}
],
\"Mail\" : [
{\"name\" : \"from\", \"type\" : \"Person\"},
{\"name\" : \"to\", \"type\" : \"Person\"},
{\"name\" : \"contents\", \"type\" : \"string\"}
]
},
\"primaryType\" : \"Mail\",
\"domain\" : {
\"name\" : \"Ether Mail\",
\"version\" : \"1\",
\"chainId\" : 1,
\"verifyingContract\" : \"0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC\"
},
\"message\" : {
\"from\": {
\"name\": \"Cow\",
\"wallet\": \"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826\"
},
\"to\": {
\"name\": \"Bob\",
\"wallet\": \"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB\"
},
\"contents\": \"Hello, Bob!\"
}
}")
I wonder if this is because that inner class is static
?
You can call .toString()
which is an override from Object
I guess.
I wonder if this might be a limitation of Clojure's interop?
Could be. I might try to dig deeper at some point and possibly post an ask.clojure question. Thanks for verify my sanity for now though!
The static inner class isn't public
Dang! Totally missed that. Thanks @alexmiller
That's it! Thanks.
(let [m (->>
StructuredData$EIP712Message
.getMethods
vec
(some (fn [x]
(when (= (.getName x) "getMessage") x)))
)]
(.setAccessible m true)
(.invoke m
(.jsonMessageObject (StructuredDataEncoder. valid-json-str))
(into-array [])))
;; =>
#object[java.util.LinkedHashMap
"0x36ee2fe"
"{from={name=Cow, wallet=0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826}, to={name=Bob, wallet=0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB}, contents=Hello, Bob!}"]
Note that setAccesible will not work on all jdk versions or all permission sets, so generally better to find out how the author wants you to use the api if possible