On Mon, Jan 23, 2012 at 3:54 AM, Tassilo Horn <[email protected]> wrote:
> Michael Klishin <[email protected]> writes:
>
> Hi Michael,
>
>> I am trying to make it possible to use functions as Quartz jobs for my
>> Clojure DSL on top of Quartz [1]. For that, I need to implement a
>> simple 1-method interface. Both gen-class and defrecord with
>> additional methods work great but seem too heavyweight in many cases
>> so I am trying to add function support using core/proxy.
>>
>> The interface I need to implement looks like this:
>>
>> https://gist.github.com/63989c1a081737813f99
>>
>> and my code is basically this:
>>
>> https://gist.github.com/a83687aed4ea62c915f5
>>
>> However, when Quartz tries to execute a new job instance,
>> UnsupportedOperationException is raised as if execute was not
>> implemented.
>
> I don't know Quartz, but checking your gist, it seems that you don't
> actually do anything with the proxy object except getting its class and
> "registering" it with some JobBuilder.
>
> Although the class generated by proxy can be instantiated using a
> zero-args constructor, those new instances don't behave like the object
> returned by proxy itself.
>
> Here's an example without additional deps illustrating the issue.
>
> --8<---------------cut here---------------start------------->8---
> (defn using-fn [f]
> (let [prx (proxy [java.util.concurrent.Delayed] []
> (getDelay [tu]
> (f 0)))
> clazz (class prx)]
> [prx clazz])) ;; return the proxy object and its class
>
> ;; Calling getDelay on the proxy object works
> (.getDelay (first (using-fn inc)) java.util.concurrent.TimeUnit/SECONDS)
> ;=> 1
>
> ;; Creating a new instance of the class generated by proxy also works
> (.newInstance (second (using-fn inc)))
> ;=> #<Object$Delayed$333735ab
> user.proxy$java.lang.Object$Delayed$333735ab@7746e075>
>
> ;; However, that new instance doesn't work as expected
> (.getDelay (.newInstance (second (using-fn inc)))
> java.util.concurrent.TimeUnit/SECONDS)
> ; getDelay
> ; [Thrown class java.lang.UnsupportedOperationException]
> ; Evaluation aborted.
> --8<---------------cut here---------------end--------------->8---
>
> Generally, proxy is for creating proxy objects, and the generation of a
> class is more or less a side effect.
>
> Do I see it correctly that you need a way (1) to have objects
> implementing Job which (2) can be instantiated with a zero-args
> constructor and (3) whose execute behavior is customizable by providing
> an arbitrary function f on the JobExecutionContext?
>
> If so, I don't see a too good way. deftype would be usable if the
> function f would be specified as a field of the type, but then it has no
> zero-args constructor...
(let [f (atom (fn [_] (throw (IllegalStateException.))))]
(defn set-job-fn! [x]
(reset! f x))
(deftype Job []
Job
(execute [ctx]
(@f ctx))))
Elaborate as you see fit with e.g. a with-job-fn macro or whatever
inside the let.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en