Thanks for the feedback.  I will try to track this issue via the 
maven-shade-plugin then.  Hopefully there can be some momentum to change it 
there.
On Saturday, December 31, 2016 at 12:09:32 PM UTC-5, Alex Miller wrote:
>
> This seems like a pretty straightforward bug with maven-shade-plugin not 
> preserving information that it should, so it seems like it should be fixed 
> there.
>
> On Wednesday, December 28, 2016 at 7:06:11 AM UTC-6, Mike Rodriguez wrote:
>>
>> Background:
>>
>> This problem is specific to building jars that contain AOT (Ahead Of 
>> Time) compiled Clojure code using Maven and the maven-shade-plugin.
>>
>> Clojure AOT compilation depends on timestamps of .class files vs .clj 
>> files being accurate.  When both .class files and their associated .clj 
>> files exist, the AOT .class files are only used by the compiler if their 
>> last modified timestamp is strictly greater than the last modified 
>> timestamp of the associated .clj file.
>>
>> Also note that the Clojure core jar itself is deployed AOTed.
>>
>> I know that much of the Clojure ecosystem uses Leiningen as a build tool 
>> (and boot now too I guess).  This problem doesn't apply to Leiningen (and I 
>> haven't looked at boot).
>>
>> Problem:
>>
>> The maven-shade-plugin is popular for building shaded/uber/standalone 
>> jars in Maven.  Typically this means the jar will include some/all of its 
>> dependency jars' files.  The maven-shade-plugin has an unfortunate property 
>> though.  It does not preserve the timestamps on files that are added to 
>> this final shaded jar.  The resulting jar actually ends up with all files 
>> inside of it having the same timestamp (when the jar was created).  In 
>> particular, if you originally had AOT Clojure .class files and .clj files 
>> with different last modified timestamps, now they will have the same 
>> timestamps in the shaded jar.
>>
>> I've brought this up before @ 
>> http://stackoverflow.com/questions/19594360/preserving-timestamps-on-clojure-clj-files-when-building-shaded-jar-via-maven-s
>>
>> I have rarely seen people bring up issues around this with 
>> maven-shade-plugin beyond this particular case.  I believe I have seen a 
>> complaint or two around the timestamp loss during shading (I can't find 
>> them now), but nothing that has gained any traction (I may try to bring it 
>> up to the plugin people soon though).
>>
>> When the AOTed .class file is ignored in favor of the .clj file, the 
>> namespace is JIT (Just-In-Time) compiled.  There are several issues with 
>> this.
>>
>> 1) Performance:  It makes the AOT files mostly worthless since they are 
>> not saving you on startup time costs anymore.  Everything is JITed anyways.
>> 2) Errors:  The reloading of the .clj files is a forced reload of the 
>> .clj namespaces involved.  This can cause classpath clashes among 
>> ClassLoaders.
>> - There are quite a few CLJ Jiras out there that faced trouble dealing 
>> with the mix of reloading namespaces and AOT compilation.
>>
>> You may be thinking, "Just don't build your Clojure jars with Maven.  Use 
>> Leiningen instead perhaps?"
>> This is fine when it is something you control.  However, what if I want 
>> to use Clojure to develop a library that may be consumed by Java consumers 
>> who very likely will be using Maven.  If my library is going to be shaded 
>> into a standalone jar with maven-shade-plugin by this Java consumer (again, 
>> likely) then this scenario can happen.
>>
>> Another thought that may occur is to just avoid AOT compilation of my 
>> library application to avoid the problem (this is recommended in the 
>> community I believe).  However, Clojure core is AOT compiled and it will 
>> get included in the shaded jar.  That alone is enough to cause the issue.
>>
>> Example:
>>
>> I have a GitHub repo to show a minimum example of where this can be a 
>> problem.  In particular it shows a way for the problem (2) to occur.
>> @ https://github.com/mrrodriguez/mvn-shade-test
>>
>> This repo has a Java API through shade.ShadeJava that will cause the 
>> Clojure compiler to require the shade.main namespace using JIT compilation. 
>>  However, shade.main uses clojure.pprint, which is AOT compiled via Clojure 
>> core.
>>
>> clojure.pprint was chosen here just because it one of the cases I've seen 
>> come up that actually fail with problem (2) from above.  Even if there were 
>> no failures though, the Clojure core namespaces would be getting recompiled 
>> with problem (1).
>>
>>

-- 
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