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>
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
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>
Works for me.
--
Michael Wood <esio...@gmail.com>