It's possible to do a mixed AOT (your code) non-aot (third-party code)
setup, but it's a huge pain.

The particular issue you're seeing is probably the result of multiple
versions of a class existing across jars and classloaders.  Unfortunately
there is no consistent way to get this right, but the solution would
involve a lot of manual inspection and stripping classes with filters like
the maven jar plugin's 'exclude' functionality.  There are some libraries
that are more troublesome than others.  In particular, any AOT'd 1st-party
code that references protocols from 3rd party code will break if those
classes are compiled dynamically, forcing you to include them, so I think
your multi-module AOT setup is likely to break hard in this case unless the
modules don't share dependencies.

One of the other big sources of problems occurs when there is mixed source
and AOT classes, as with the clojure artifact jar itself.  Uberjarring
would be sensitive to timestamps, the clj source should be older than the
compiled class files.  This is specifically a problem with the
maven-shade-plugin and I experienced it on a mixed-java/clojure project.

In short, it's probably more trouble than it's worth to split the build
into module jars only to combine them again.  If I were to do the
shared-AOT-library consumed by clojure code scenario over again, I'd
include the shared source into the build system of the consuming project,
instead of including the jar artifact.

On Wed, Oct 12, 2016 at 4:26 PM Stuart Halloway <stuart.hallo...@gmail.com>
wrote:

> Hi Piotr,
>
> Yes, the limitation is how the Java classpath works.  If you AOT your app,
> you need to AOT compile other Clojure code your app uses.
>
> See e.g.
> http://dev.clojure.org/jira/browse/CLJ-1544?focusedCommentId=43558&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-43558
>
> Cheers,
> Stu
>
> On Wed, Oct 12, 2016 at 2:22 PM, Piotr Bzdyl <pi...@bzdyl.net> wrote:
>
> Hello,
>
> I am trying to solve an issue in my project where I have the following
> setup. My application modules are AOT-compiled into several jars and then
> packaged with their 3rd party dependencies into an uberjar. As a result my
> uberjar contains my project's namespaces compiled to class files and
> dependencies (in this case clojure.java.jdbc) source clj files.
>
> When I try to start the application it fails with the following
> stacktrace. Is there any limitation that prevents me running AOT-compiled
> namespaces using other namespaces available as clj on classpath?
>
> java.lang.reflect.InvocationTargetException: null
>    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
> ~[na:1.8.0_102]
>    at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
> ~[na:1.8.0_102]
>    at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>  ~[na:1.8.0_102]
>    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_102]
>    at com.example.Launcher$ThreadLauncher.run(Launcher.java:42) ~[na:na]
>    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_102]
> Caused by: java.lang.NoClassDefFoundError: clojure/java/jdbc/Connectable
>    at com.example.db.common.database__init.load(Unknown Source) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at com.example.db.common.database__init.<clinit>(Unknown Source) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at java.lang.Class.forName0(Native Method) ~[na:1.8.0_102]
>    at java.lang.Class.forName(Class.java:348) ~[na:1.8.0_102]
>    at clojure.lang.RT.classForName(RT.java:2154) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.classForName(RT.java:2163) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.loadClassForName(RT.java:2182) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.load(RT.java:436) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.load(RT.java:412) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load$fn__5448.invoke(core.clj:5866) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load.doInvoke(core.clj:5865) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.invoke(RestFn.java:408) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_one.invoke(core.clj:5671) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_lib$fn__5397.invoke(core.clj:5711) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_lib.doInvoke(core.clj:5710) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.applyTo(RestFn.java:142) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$apply.invoke(core.clj:632) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_libs.doInvoke(core.clj:5749) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.applyTo(RestFn.java:137) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$apply.invoke(core.clj:632) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$require.doInvoke(core.clj:5832) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.invoke(RestFn.java:421) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at 
> com.example.db.auth.password$loading__5340__auto____1250.invoke(password.clj:1)
>  ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at com.example.db.auth.password__init.load(Unknown Source) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at com.example.db.auth.password__init.<clinit>(Unknown Source) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at java.lang.Class.forName0(Native Method) ~[na:1.8.0_102]
>    at java.lang.Class.forName(Class.java:348) ~[na:1.8.0_102]
>    at clojure.lang.RT.classForName(RT.java:2154) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.classForName(RT.java:2163) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.loadClassForName(RT.java:2182) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.load(RT.java:436) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.load(RT.java:412) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load$fn__5448.invoke(core.clj:5866) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load.doInvoke(core.clj:5865) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.invoke(RestFn.java:408) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_one.invoke(core.clj:5671) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_lib$fn__5397.invoke(core.clj:5711) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_lib.doInvoke(core.clj:5710) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.applyTo(RestFn.java:142) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$apply.invoke(core.clj:632) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_libs.doInvoke(core.clj:5749) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.applyTo(RestFn.java:137) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$apply.invoke(core.clj:634) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$use.doInvoke(core.clj:5843) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.invoke(RestFn.java:436) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at com.example.db.auth.user$loading__5340__auto____1248.invoke(user.clj:1) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at com.example.db.auth.user__init.load(Unknown Source) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at com.example.db.auth.user__init.<clinit>(Unknown Source) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at java.lang.Class.forName0(Native Method) ~[na:1.8.0_102]
>    at java.lang.Class.forName(Class.java:348) ~[na:1.8.0_102]
>    at clojure.lang.RT.classForName(RT.java:2154) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.classForName(RT.java:2163) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.loadClassForName(RT.java:2182) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.load(RT.java:436) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.load(RT.java:412) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load$fn__5448.invoke(core.clj:5866) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load.doInvoke(core.clj:5865) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.invoke(RestFn.java:408) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_one.invoke(core.clj:5671) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_lib$fn__5397.invoke(core.clj:5711) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_lib.doInvoke(core.clj:5710) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.applyTo(RestFn.java:142) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$apply.invoke(core.clj:632) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_libs.doInvoke(core.clj:5753) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.applyTo(RestFn.java:137) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$apply.invoke(core.clj:632) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$require.doInvoke(core.clj:5832) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.invoke(RestFn.java:436) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at com.example.db.auth.init$loading__5340__auto____1246.invoke(init.clj:1) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at com.example.db.auth.init__init.load(Unknown Source) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at com.example.db.auth.init__init.<clinit>(Unknown Source) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at java.lang.Class.forName0(Native Method) ~[na:1.8.0_102]
>    at java.lang.Class.forName(Class.java:348) ~[na:1.8.0_102]
>    at clojure.lang.RT.classForName(RT.java:2154) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.classForName(RT.java:2163) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.loadClassForName(RT.java:2182) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.load(RT.java:436) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RT.load(RT.java:412) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load$fn__5448.invoke(core.clj:5866) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load.doInvoke(core.clj:5865) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.invoke(RestFn.java:408) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_one.invoke(core.clj:5671) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_lib$fn__5397.invoke(core.clj:5711) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_lib.doInvoke(core.clj:5710) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.applyTo(RestFn.java:142) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$apply.invoke(core.clj:632) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$load_libs.doInvoke(core.clj:5749) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.applyTo(RestFn.java:137) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$apply.invoke(core.clj:632) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.core$require.doInvoke(core.clj:5832) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.invoke(RestFn.java:408) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at 
> com.example.services.activator$register_services.invoke(activator.clj:61) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at com.example.services.activator$startup.invoke(activator.clj:131) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at com.example.services.activator$_main.doInvoke(activator.clj:139) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.invoke(RestFn.java:397) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.AFn.applyToHelper(AFn.java:152) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at clojure.lang.RestFn.applyTo(RestFn.java:132) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    at com.example.services.activator.main(Unknown Source) 
> ~[example-2.5.0-SNAPSHOT-standalone.jar:na]
>    ... 6 common frames omitted
> Caused by: java.lang.ClassNotFoundException: clojure.java.jdbc.Connectable
>    at java.net.URLClassLoader.findClass(URLClassLoader.java:381) 
> ~[na:1.8.0_102]
>    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_102]
>    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_102]
>    ... 104 common frames omitted
>
>
> Best regards,
> Piotr
>
> --
> 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.
>
>
> --
> 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.
>

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