librelist archives

« back to archive

Wrong Clojure release when compiling if 'with-profile' and 'uberjar' is used?

Wrong Clojure release when compiling if 'with-profile' and 'uberjar' is used?

From:
Dirk Hesse
Date:
2014-09-25 @ 13:02
Hello, I use the following project file:

(defproject cl7 "0.1.0-SNAPSHOT"
   :description "FIXME: write description"
   :url "http://example.com/FIXME"
   :license {:name "Eclipse Public License"
             :url "http://www.eclipse.org/legal/epl-v10.html"}
   :dependencies [[org.clojure/clojure "1.6.0"]]
   :profiles {
              :1.7 {:dependencies [[org.clojure/clojure "1.7.0-alpha2"]]}
              :uberjar {:aot [cl7.core ]}
              }

   :main cl7.core
   )

and the associated source code cl7/core.clj:

(ns cl7.core
   (:gen-class))

(defrecord AA [a b])

(defn hello []
   (let [v [ (AA. 1 2) (AA. 4 5) (AA. 1 2) ]]
     (println (clojure-version) (set v))))

(defn -main [& args]
   (hello))

Running the uberjar created with 'lein uberjar' is as expected ok.

But when I create the uberjar with
$ lein with-profile 1.7 uberjar
and then start the uberjar, I get the runtime exception 
java.lang.NoSuchMethodError when calling (set v).
(The reason is that the ctor for the clojure.lang.SeqIterator has 
changed in Clojure 1.7)

Why the exception is caused?:
The uberjar file contains the correct clojure 1.7 class files,
but contrary to my expectations the cl7/core.clj file was compiled to 
the class files incorrectly before with the *default* Clojure 1.6.0 release!

I have always assumed that the specified clojure version in a profile is 
also used during compilation when I use the uberjar task.

'lein with-profile 1.7 repl / run' works correctly.

Did I miss something or what I'm doing wrong?

Regards,
Dirk Hesse

Re: [leiningen] Wrong Clojure release when compiling if 'with-profile' and 'uberjar' is used?

From:
Hugo Duncan
Date:
2014-09-25 @ 14:09
heskudi@online.de writes:

>               :1.7 {:dependencies [[org.clojure/clojure "1.7.0-alpha2"]]}

Assuming you are on leiningen 2.5.0, try:

    :1.7 ^:leaky {:dependencies [[org.clojure/clojure "1.7.0-alpha2"]]}

> I have always assumed that the specified clojure version in a profile is
> also used during compilation when I use the uberjar task.
>
> 'lein with-profile 1.7 repl / run' works correctly.
>
> Did I miss something or what I'm doing wrong?

This is an unexpected consequence of the profiles with metadata change
in 2.5.0.  I shall let Phil speak to whether it is desired or not.

I think this is the second reported case of profiles being used to
affect jars, which used to work and now requires ^:leaky.

Hugo

Re: [leiningen] Wrong Clojure release when compiling if 'with-profile' and 'uberjar' is used?

From:
Dirk Hesse
Date:
2014-09-26 @ 13:21
On 25.09.2014 16:09, Hugo Duncan wrote: heskudi@online.de writes:
>>    
>> Assuming you are on leiningen 2.5.0, try:
>>
>>      :1.7 ^:leaky {:dependencies [[org.clojure/clojure "1.7.0-alpha2"]]}

Thank you, Hugo.

That's good to know! I had actually used the version 2.5.0.
It now works as expected with the ^:leaky mark.

Honestly, even if I had previously read the updated PROFILES.md doc for 
2.5.0,
I would not have thought that I have to use the :leaky mark in the case 
of a Clojure dependency.

In my opinion the Clojure depencency is a special case. Clojure is not 
only a library, but also contains the compiler.

I think the default behaviour is a bit dangerous because the wrong 
Clojure release is noticed only in the case of a possible exception.


Regards,
Dirk

Re: [leiningen] Wrong Clojure release when compiling if 'with-profile' and 'uberjar' is used?

From:
Hugo Duncan
Date:
2014-09-26 @ 15:16
heskudi@online.de writes:

> Honestly, even if I had previously read the updated PROFILES.md doc for
> 2.5.0,
> I would not have thought that I have to use the :leaky mark in the case
> of a Clojure dependency.

It is actually a bug #1701 [1]

> In my opinion the Clojure depencency is a special case. Clojure is not
> only a library, but also contains the compiler.
>
> I think the default behaviour is a bit dangerous because the wrong
> Clojure release is noticed only in the case of a possible exception.

I don't think there is a need to special case this once the bug is fixed.

Hugo

[1] https://github.com/technomancy/leiningen/issues/1701