[BUG?] No matching method found: getString

231 views
Skip to first unread message

Michael Wood

unread,
Nov 19, 2008, 4:00:30 AM11/19/08
to clo...@googlegroups.com
In September I was trying out the Java interop support of Clojure by
converting this:

http://www.dcm4che.org/confluence/display/d2/Accessing+dcm4che2+Toolkit+with+Jruby

to Clojure.

I was using the 20080612 release and got an exception like this:

Exception in thread "main" java.lang.IllegalArgumentException: No
matching method found: getString for class
org.dcm4che2.data.BasicDicomObject (dinfo.clj:0)

rhickey pointed out that there was a 20080916 version available, so I
tried that and the problem went away.

Yesterday I tried running the code again using r1109 of Clojure and
got the same exception again! Here's what it looks like with r1110:

Exception in thread "main" java.lang.IllegalArgumentException: No
matching method found: getString for class
org.dcm4che2.data.BasicDicomObject (dinfo.clj:0)
at clojure.lang.Compiler.eval(Compiler.java:4111)
at clojure.lang.Compiler.load(Compiler.java:4427)
at clojure.lang.Compiler.loadFile(Compiler.java:4394)
at clojure.lang.Script.main(Script.java:65)
Caused by: java.lang.IllegalArgumentException: No matching method
found: getString for class org.dcm4che2.data.BasicDicomObject
at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:48)
at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28)
at clojure.core$print_tag__8.invoke(dinfo.clj:18)
at clojure.core$eval__11.invoke(dinfo.clj:21)
at clojure.lang.Compiler.eval(Compiler.java:4100)
... 3 more

The code is here:
http://paste.lisp.org/display/70670

The Javadoc for BasicDicomObject is here:
http://www.dcm4che.org/docs/dcm4che2-apidocs/org/dcm4che2/data/BasicDicomObject.html

I bisected this down to r1047 and r1048. i.e.:
1029 works
1039 works
1044 works
1046 works
1047 doesn't work
1049 doesn't work
1069 doesn't work
1109 doesn't work

If I revert those two revisions then the problem goes away again.
i.e. the following fixes it:
svn up -r1110; svn diff -r1046:1048 | patch -p0 -R

Chouser said, "Wodin: looks like you're going to have to take it up
with rhickey_. The method you want isBridge (whatever that means), but
the class is not StringBuilder, thus Clojure's not letting you get to
that method. "

--
Michael Wood <esio...@gmail.com>

Chouser

unread,
Nov 19, 2008, 5:10:38 PM11/19/08
to clo...@googlegroups.com
On Wed, Nov 19, 2008 at 4:00 AM, Michael Wood <esio...@gmail.com> wrote:
>
> Exception in thread "main" java.lang.IllegalArgumentException: No
> matching method found: getString for class
> org.dcm4che2.data.BasicDicomObject (dinfo.clj:0)

This was discussed on IRC:

http://clojure-log.n01se.net/date/2008-11-19.html#15:46a-16:07

So it looks like there may be no good, general, solution. Unless or
until there is, there's a work-around using reflection manually.

Start by getting a reference to the Method you're trying to call:

(def bdo-get-string (.getMethod (identity BasicDicomObject)
"getString" (into-array [Integer/TYPE])))

The three args to .getMethods are:
1. The class (use identity to get the instance of Class instead of
trying to BasicDicomObject's non-existent getMethod method)
2. The name of the method as a string, "getString"
3. An array of the argument types for the method you want to call.
Use Interger/TYPE to specify the primitive 'int'

You can then call the method you found above using the .invoke method
of the Method instance:

(.invoke bdo-get-string (BasicDicomObject.) (to-array [0x00100010]))

The .invoke method always takes 3 args:
1. The Method instance we got earlier
2. The instance of the class you want call (in this example I created
a new instance on the spot)
3. And array holding all the args to pass to the Method.

Not too pretty, but of course if you find you actually need this you
can wrap either step in a function to make calling it more pleasant.

--Chouser

Michael Wood

unread,
Nov 20, 2008, 10:47:14 AM11/20/08
to clo...@googlegroups.com
Hi

On Thu, Nov 20, 2008 at 12:10 AM, Chouser <cho...@gmail.com> wrote:
>
> On Wed, Nov 19, 2008 at 4:00 AM, Michael Wood <esio...@gmail.com> wrote:
>>
>> Exception in thread "main" java.lang.IllegalArgumentException: No
>> matching method found: getString for class
>> org.dcm4che2.data.BasicDicomObject (dinfo.clj:0)
>
> This was discussed on IRC:
>
> http://clojure-log.n01se.net/date/2008-11-19.html#15:46a-16:07
>
> So it looks like there may be no good, general, solution. Unless or
> until there is, there's a work-around using reflection manually.
>
> Start by getting a reference to the Method you're trying to call:
>
> (def bdo-get-string (.getMethod (identity BasicDicomObject)
> "getString" (into-array [Integer/TYPE])))

Thanks. That works fine. I'll use that in the mean time.

> The three args to .getMethods are:
> 1. The class (use identity to get the instance of Class instead of
> trying to BasicDicomObject's non-existent getMethod method)
> 2. The name of the method as a string, "getString"
> 3. An array of the argument types for the method you want to call.
> Use Interger/TYPE to specify the primitive 'int'
>
> You can then call the method you found above using the .invoke method
> of the Method instance:
>
> (.invoke bdo-get-string (BasicDicomObject.) (to-array [0x00100010]))
>
> The .invoke method always takes 3 args:
> 1. The Method instance we got earlier
> 2. The instance of the class you want call (in this example I created
> a new instance on the spot)
> 3. And array holding all the args to pass to the Method.

Thanks for the explanation.

> Not too pretty, but of course if you find you actually need this you
> can wrap either step in a function to make calling it more pleasant.

Yes, I've changed print-tag from:

(defn print-tag [dcm tag]
(.getString dcm tag))

to:

(defn print-tag [dcm tag]


(def bdo-get-string
(.getMethod
(identity BasicDicomObject) "getString" (into-array [Integer/TYPE])))

(.invoke bdo-get-string dcm (to-array [tag])))

--
Michael Wood <esio...@gmail.com>

Rich Hickey

unread,
Nov 20, 2008, 11:59:45 AM11/20/08
to Clojure


On Nov 20, 10:47 am, "Michael Wood" <esiot...@gmail.com> wrote:
> Hi
>
>
>
> On Thu, Nov 20, 2008 at 12:10 AM, Chouser <chou...@gmail.com> wrote:
SVN rev 1119 has my latest attempt to reconcile these bridge methods,
trying to make all of these work:

http://groups.google.com/group/clojure/browse_frm/thread/a4e1b58061962479/23a1efe8d9f45eb3
http://groups.google.com/group/clojure/browse_frm/thread/ee1c729f1577d530/a21fbfedafb1998b
http://groups.google.com/group/clojure/browse_frm/thread/c584c41ebe1caaf2/03ac73e2abd8e425#03ac73e2abd8e425

without breaking anything else.

Please let me know the effects, positive or negative, on method
resolution.

Rich

Michael Wood

unread,
Nov 21, 2008, 1:43:16 AM11/21/08
to clo...@googlegroups.com
On Thu, Nov 20, 2008 at 6:59 PM, Rich Hickey <richh...@gmail.com> wrote:
> SVN rev 1119 has my latest attempt to reconcile these bridge methods,
> trying to make all of these work:
>
> http://groups.google.com/group/clojure/browse_frm/thread/a4e1b58061962479/23a1efe8d9f45eb3
> http://groups.google.com/group/clojure/browse_frm/thread/ee1c729f1577d530/a21fbfedafb1998b
> http://groups.google.com/group/clojure/browse_frm/thread/c584c41ebe1caaf2/03ac73e2abd8e425#03ac73e2abd8e425
>
> without breaking anything else.
>
> Please let me know the effects, positive or negative, on method
> resolution.

Works for me.

--
Michael Wood <esio...@gmail.com>

Reply all
Reply to author
Forward
0 new messages