librelist archives

« back to archive

Re: [leiningen] :main namespace and protocols/deftypes

Re: [leiningen] :main namespace and protocols/deftypes

Phil Hagelberg
2013-02-12 @ 17:52
Tassilo Horn writes:

> A bit debugging revealed that having a :main namespace implies doing
> AOT-compilation.  In turn, the AOT-compilation compiled classes for the
> deftypes, and when the project is being run, I end up with having 2
> versions of any deftype classes in memory: From the AOT-compilation,
> there're classes loaded by the AppClassLoader, and once I require the
> lib-namespaces new classes for the very same deftypestypes are created
> and loaded by a clojure DynamicClassLoader.

This is part of the reason I try to avoid protocols as much as possible;
these kinds of situations are very difficult to debug. Perhaps someone
who's more familiar with protocols can advise you how to work around
this problem. From what I understand things shouldn't be recompiled if
they've already been AOT'd, but I know that the fallback path for
protocols doesn't work as well as it does for other Clojure constructs.

> I've just found out that I can use
>   :main ^:skip-aot my.main.ns
> to disable AOT-compilation in the presence of a :main namespace, and
> indeed, after doing that my project works again.

Yes, the fact that :main implies AOT is a mistake in retrospect; it made
sense before the run task existed since :main was used for uberjars
only, but it is no longer the right choice. I removed this in 2.0.0, but
it was added back in at the last minute and slipped my notice.
Unfortunately support for :skip-aot was *not* added back in, so in 2.0.0
there's no way to do this properly. I've added :skip-aot back in on
master, so 2.1.0 will have it. Removal of auto-AOT of :main will have to
wait for 3.0.0 unfortunately.