Michael Klishin <michael.s.klis...@gmail.com> 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... You probably could rewrite your using-fn as a macro where a call like (using-fn foo) expands into something like (deftype MyJob_foo [] Job (execute [ctx] (foo ctx)) for any function foo, plus the registration of MyJob_foo with that JobBuilder thingy. Of course, a second call (using-fn foo) should skip the definition of that already existing type. Bye, Tassilo -- 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