Btw, if you own the defrecord, extend a protocol to it directly in its 
definition, rather than in a separate extend or extend-protocol form. 
 Doing it inline makes the record implement the protocol's backing 
interface, which will be much more efficient. (If it's not your record you 
don't really have a choice.)

(defrecord FooRecord [msg]
  FooProtocol
  (foo [_] ...))


On Tuesday, January 6, 2015 5:20:17 PM UTC-5, Michael Blume wrote:
>
> On further investigation, it looks like you're suffering from 
> http://dev.clojure.org/jira/browse/CLJ-979 -- if I apply the patch for 
> this bug to clojure and recompile your project everything works fine. It 
> looks like this patch *is* slated to make it into Clojure 1.7.0, so that 
> should also make your problem go away.
>
> On Tue Jan 06 2015 at 1:29:39 PM Michael Blume <blume...@gmail.com 
> <javascript:>> wrote:
>
>> TL;DR: If you wait for that lein-ring pull to get merged, you can upgrade 
>> lein-ring and your problem will go away. If you wait for Clojure 1.7.0 it's 
>> possible your problem will go away, though I'm less confident here (the 
>> current alpha doesn't have a fix). If you want your problem to go away 
>> *right now* then you want your ring handler listed in your project.clj to 
>> be in a namespace that *doesn't import any of the rest of your project*. 
>> That's what 
>> https://github.com/MichaelBlume/extend-test/blob/6a676e6e326a91a1003e76b219b94a2664175587/src/extend_test/core/shim.clj
>>  
>> does. It has an initialize! function which, at run-time, rather than at 
>> compile-time, manually imports your real handler and sticks it in an atom. 
>> Then the handler exposed to ring just reads the real handler out of the 
>> atom and applies it to the incoming request.
>>
>>
>> On Tue Jan 06 2015 at 1:24:40 PM Michael Blume <blume...@gmail.com 
>> <javascript:>> wrote:
>>
>>> lein-ring uses AOT compilation to build war files. AOT compilation in 
>>> clojure is, well, problematic sometimes. Fortunately it can almost always 
>>> be avoided using clever indirection.
>>>
>>> For example: https://github.com/pdenhaan/extend-test/pull/1 builds a 
>>> war that works =)
>>>
>>> I've got a pull open against lein-ring that will use this trick by 
>>> default and avoid AOT in war builds, I'm hoping it'll get merged/released 
>>> soon.
>>>
>>> There's a couple open bugs in Clojure right now to do with AOT that have 
>>> patches that should land in 1.7.0. It's possible one of them will solve 
>>> your problem, I'm poking at them now to check.
>>>
>>>
>>> On Tue Jan 06 2015 at 8:08:41 AM <peter....@qficonsulting.com 
>>> <javascript:>> wrote:
>>>
>>>> I'm a relative newcomer to Clojure, and I'm puzzled by problems I have 
>>>> using extend in a webapp. Any help would be hugely appreciated.
>>>>
>>>> My use case is basically this:
>>>>
>>>> (defrecord FooRecord [msg])
>>>>
>>>>
>>>> (defprotocol FooProtocol
>>>>   (bar [foo] "to use with extend-type"))
>>>>
>>>>
>>>> (extend FooRecord
>>>>   FooProtocol
>>>>   {:bar (fn [foo] (str "Test " (:msg foo)))})
>>>>
>>>> I'm calling bar on a newly created FooRecord:
>>>>
>>>> (bar (->FooRecord "Successful"))
>>>>
>>>> This works in a REPL, and also works great in a web application on ring 
>>>> server-headless:
>>>>
>>>> Test Successful
>>>>
>>>>
>>>> But the moment I package the code in a war and deploy to Jetty 8 or 
>>>> Tomcat 7, it fails:
>>>>
>>>>     java.lang.IllegalArgumentException: No implementation of method: 
>>>>> :bar of protocol: #'extend-test.core.handler/FooProtocol found for 
>>>>> class: extend_test.core.handler.FooRecord
>>>>>         clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:544)
>>>>>         extend_test.core.handler$eval44$fn__45$G__35__50.invoke(hand
>>>>> ler.clj:8)
>>>>>         extend_test.core.handler$fn__65.invoke(handler.clj:16)
>>>>>         compojure.core$make_route$fn__1431.invoke(core.clj:104)
>>>>>         ...
>>>>
>>>>
>>>> I searched this group and the web for clues. It smells of a 
>>>> classloading/aliasing problem, but I could not find any information to 
>>>> indicate that this behaviour is expected when deploying to a servlet 
>>>> container, or what I can do about it apart from avoid using extend.
>>>>
>>>> If you'd like to check out the full code or run it yourself, I've 
>>>> created a Github project with a minimal test case 
>>>> <https://github.com/pdenhaan/extend-test>.
>>>>
>>>> The problem has me altogether stumped for the moment. Thanks for 
>>>> reading.
>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To post to this group, send email to clo...@googlegroups.com 
>>>> <javascript:>
>>>> Note that posts from new members are moderated - please be patient with 
>>>> your first post.
>>>> To unsubscribe from this group, send email to
>>>> clojure+u...@googlegroups.com <javascript:>
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/clojure?hl=en
>>>> --- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "Clojure" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to clojure+u...@googlegroups.com <javascript:>.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to