sksamuel
sksamuel

Reputation: 16387

SBT Plugin use classpath of compiled sources

I have an SBT Plugin and in this plugin I want to instantiate classes that were compiled as part of the compile step.

Essentially, think of my plugin as doing this:

classOf[com.skamuel.Dummy].newInstance where Dummy is a class compiled by the build.

But when I try this, I get class not found exception. I can execute the above code in the console after executing the compile task, just not as part of a plugin.

So, what classpath magic do I need to do to get the above to work?

Upvotes: 1

Views: 291

Answers (1)

lpiepiora
lpiepiora

Reputation: 13749

Your plugin can use runtime class path of the compiled project to which it is added, but it cannot use it at the compile time. This is logical I guess, your plugin exists without knowing of your project.

Given that you could use the mentioned class like this:

import sbt._
import Keys._
import classpath._

object MyPlugin extends Plugin {

  val createClass = taskKey[Unit]("Creates new instance of a class")

  lazy val myPluginSettings = inConfig(Compile)(Seq(
    createClass := {
      // we need to make sure the class we want to use is compiled
      val analysis = (compile in Compile).value
      // create custom class loader from the output of compile plus other deps
      val classpath = (fullClasspath in Compile).value.map(_.data)
      val loader = ClasspathUtilities.makeLoader(classpath, scalaInstance.value)
      val myClass = Class.forName("com.stackoverflow.lpiepiora.MyClass", true, loader).newInstance
      println(myClass.asInstanceOf[{def helloWorld(): String}].helloWorld())
    }
  ))

}

The problem is that you cannot do much with the class, as plugin cannot cast it directly to the type - it doesn't know it.

I'm using structural type for the example, as I have my class defined as

package com.stackoverflow.lpiepiora
class MyClass {
  def helloWorld(): String = "Hello World"
}

You can also check the complete, working example in my GitHub repository

Upvotes: 2

Related Questions