(The leiningen-core dep caught my eye as being unnecessary here; all you need 
to use pomegranate is [com.cemerick/pomegranate "0.0.13"].  Although, that 
doesn't change the outcome in this case.)

You're quite right, loading datomic dynamically with piggieback already in 
place (either from the start or itself dynamically) goes sideways.  This is 
because of conflicting Google Guava dependencies.  Here's the dep tree for 
datomic:

[com.datomic/datomic-free "0.8.3488" :exclusions [[org.slf4j/slf4j-nop]]]
   [com.amazonaws/aws-java-sdk "1.3.0" :exclusions [[javax.mail/mail] 
[org.codehaus.jackson/jackson-core-asl] [org.apache.httpcomponents/httpclient] 
[commons-logging]]]
   [com.google.guava/guava "12.0.1"]
     [com.google.code.findbugs/jsr305 "1.3.9"]
   [com.h2database/h2 "1.3.165"]
   [net.java.dev.jets3t/jets3t "0.8.1" :exclusions [[commons-logging]]]
     [com.jamesmurty.utils/java-xmlbuilder "0.4"]
     [commons-codec "1.3"]
     [commons-httpclient "3.1" :exclusions [[commons-codec] [commons-logging]]]
   [org.apache.httpcomponents/httpclient "4.2-alpha1" :exclusions 
[[commons-logging]]]
     [org.apache.httpcomponents/httpcore "4.2-alpha2"]
   [org.apache.lucene/lucene-core "3.3.0"]
   [org.apache.tomcat/tomcat-jdbc "7.0.27" :exclusions [[commons-logging]]]
     [org.apache.tomcat/tomcat-juli "7.0.27"]
   [org.clojure/data.json "0.1.2"]
   [org.codehaus.jackson/jackson-core-asl "1.8.0"]
   [org.codehaus.janino/commons-compiler-jdk "2.6.1"]
     [org.codehaus.janino/commons-compiler "2.6.1"]
   [org.hornetq/hornetq-core "2.2.2.Final"]
   [org.jboss.netty/netty "3.2.4.Final"]
   [org.slf4j/jcl-over-slf4j "1.6.4"]
   [org.slf4j/jul-to-slf4j "1.6.4"]
   [org.slf4j/log4j-over-slf4j "1.6.4" :scope "runtime"]
   [postgresql "9.1-901.jdbc4"]
   [spy/spymemcached "2.8.1"]

Notice [com.google.guava/guava "12.0.1"] in there.  Here's the tree for 
ClojureScript, which piggieback depends upon:

 [org.clojure/clojurescript "0.0-1450"]
   [com.google.javascript/closure-compiler "r1918"]
     [args4j "2.0.12"]
     [com.google.code.findbugs/jsr305 "1.3.9"]
     [com.google.guava/guava "10.0.1"]
     [com.google.protobuf/protobuf-java "2.4.1"]
     [com.googlecode.jarjar/jarjar "1.1"]
     [junit "4.8.2"]
     [org.apache.ant/ant "1.8.2"]
       [org.apache.ant/ant-launcher "1.8.2"]
     [org.json/json "20090211"]
   [org.clojure/google-closure-library "0.0-1376"]
   [org.mozilla/rhino "1.7R3"]

Notice [com.google.guava/guava "10.0.1"] in there, a mismatch, and clearly a 
fatal one (datomic happens to depend on some API in the newer 12.0.1 release).

This is a fundamental shortcoming of classloaders (and therefore pomegranate): 
everything is just a jar (or zip, or directory containing classes+resources), 
with absolutely no metadata associated with it identifying which library each 
represents.  So when pomegranate adds things to a classloader's classpath, it 
(currently) has no way of knowing, e.g. that Guava 10.0.1 is already there.  
Even knowing that, there's no mechanism to ensure that e.g. ClojureScript would 
continue to use 10.0.1, but Datomic would have access to 12.0.1.

These are the sorts of problems that module systems (like OSGi, the NetBeans 
module system, the Jigsaw theory, etc) aim to solve…although they introduce a 
whole separate set of difficulties as well.  There are some avenues I've yet to 
fully explore that might make your scenario work without adding the pain of 
modules, but they are comfortably backlogged at the moment.

Thus, the role of pomegranate's add-dependencies is far more of an escape hatch 
than anything else.  I've added some language to the project's README to this 
effect, FWIW.

Cheers,

- Chas

On Oct 1, 2012, at 12:31 AM, Brent Millare wrote:

> Using the project file
> (defproject test "1.0"
>   :dependencies [#_ [com.datomic/datomic-free "0.8.3538"]
>                  [leiningen-core "2.0.0-preview10"]
>                  [com.cemerick/piggieback "0.0.2"]])
>   
> Then doing a lein2 repl
> and running the following commands in order
> user=> (require '[cemerick.pomegranate])
> nil
> user=> (cemerick.pomegranate/add-dependencies :coordinates 
> '[[com.datomic/datomic-free "0.8.3538"]])
> ...lots of output...
> user=> (require '[datomic.api])
> NoSuchMethodError 
> com.google.common.cache.CacheBuilder.maximumSize(J)Lcom/google
> /common/cache/CacheBuilder;  datomic.cache/create-computing (cache.clj:129)
> 
> If I use lein2 normally with datomic in the project.clj file, everything 
> works as normal. Is there something going on differently that prevents this 
> from working when adding dependencies dynamically?
> 
> (Note I need to have piggieback in there to create the error).
> 
> -- 
> 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 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

Reply via email to