Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling clojure code from a scala sbt task

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.

like image 971
shakdwipeea Avatar asked Mar 06 '18 06:03

shakdwipeea


1 Answers

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?

like image 184
Piotrek Bzdyl Avatar answered Oct 11 '22 22:10

Piotrek Bzdyl