9

I am trying to call some clojure code as a sbt task.

My build.sbt looks like,

lazy val aTask = taskKey[Unit]("a task")

libraryDependencies ++= Seq(
"org.clojure" % "clojure" % "1.9.0"
)

import clojure.java.api.Clojure
import clojure.lang.IFn

aTask := {
val plus: IFn = Clojure.`var`("clojure.core", "+")
println(plus.invoke(1, 4))
}

Contents of project/build.sbt

resolvers += Resolver.mavenLocal

libraryDependencies ++= Seq(
   "org.clojure" % "clojure" % "1.9.0"
 )

Also I have added clojure dep in project/build.sbt of my project.

I am getting the following error when calling the task

[error] java.lang.ExceptionInInitializerError
[error] at clojure.lang.Namespace.<init>(Namespace.java:34)
[error] at clojure.lang.Namespace.findOrCreate(Namespace.java:176)
[error] at clojure.lang.Var.intern(Var.java:148)
[error] at clojure.java.api.Clojure.var(Clojure.java:82)
[error] at clojure.java.api.Clojure.<clinit>(Clojure.java:96)
[error] at $2d5a9b65ddee7e6a09cc$.$anonfun$$sbtdef$1(build.sbt:20)
[error] at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
[error] at sbt.std.Transform$$anon$3.$anonfun$apply$2(System.scala:46)
[error] at sbt.std.Transform$$anon$4.work(System.scala:66)
[error] at sbt.Execute.$anonfun$submit$2(Execute.scala:262)
[error] at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:16)
[error] at sbt.Execute.work(Execute.scala:271)
[error] at sbt.Execute.$anonfun$submit$1(Execute.scala:262)
[error] at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:174)
[error] at sbt.CompletionService$$anon$2.call(CompletionService.scala:36)
[error] at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[error] at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[error] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[error] at java.lang.Thread.run(Thread.java:748)
[error] Caused by: java.io.FileNotFoundException: Could not locate clojure/core__init.class or clojure/core.clj on classpath.
[error] at clojure.lang.RT.load(RT.java:463)
[error] at clojure.lang.RT.load(RT.java:426)
[error] at clojure.lang.RT.doInit(RT.java:468)
[error] at clojure.lang.RT.<clinit>(RT.java:336)

Any pointers on what I could try would be helpful.

shakdwipeea
  • 775
  • 2
  • 7
  • 14
  • `libraryDependencies` updates the classpath for the slave JVMs started by sbt, not for the master JVM that is parsing and executing your build.sbt file. – DaoWen Mar 07 '18 at 07:07
  • @DaoWen How can i go about adding deps to the master jvm? i've tried adding the clojure dependency in the project/build.sbt as well as in the global.sbt. I get the same error in both the cases. – shakdwipeea Mar 07 '18 at 09:50
  • Sorry, I don't know enough about SBT to answer that. My guess is that there is currently no support for doing that from your build.sbt spec. – DaoWen Mar 07 '18 at 16:20
  • can you show the content of the `project/build.sbt` file? – lev Mar 09 '18 at 13:56
  • @lev I've updated the question with the contents – shakdwipeea Mar 09 '18 at 18:37
  • why not compile your clojure code and call it from within a very skinny SBT task? I've rewritten the existing sbt-clojure plugin for 1.0 here: https://github.com/terminally-chill/sbt-clojure the readme describes how to interop. – emran Jun 19 '18 at 20:29

1 Answers1

1

I think there is an issue with class loaders setup by sbt. Clojure's RT class loads Clojure namespaces/classes using class loaders API. If sbt configures the classloaders hierarchy and class loading strategy (e.g. parent first) in a way that RT's classloader doesn't find Clojure's classes via classloader it's using then it will fail with the error you are getting.

Unfortunately, I don't know sbt internals to determine how the classloaders get configured. Maybe another question would help in the investigation: How to display classpath used for run task?

Piotrek Bzdyl
  • 12,965
  • 1
  • 31
  • 49