SBT:插件依赖项和项目类路径

时间:2011-10-26 22:10:46

标签: scala sbt

如何将外部依赖项添加到SBT插件并使其在项目和插件类路径中可用?:

具体来说,我有一个简单的插件,应该运行我们的TestNG测试套件并进行一些后期处理。这是一个简化版本:

import sbt._
import java.util.ArrayList
import Keys._
import org.testng._

object RunTestSuitesPlugin extends Plugin {
  lazy val runTestSuites = TaskKey[Unit]("run-test-suites", "runs TestNG test suites")
  lazy val testSuites = SettingKey[Seq[String]]("test-suites", "list of test suites to run")

  class JavaListWrapper[T](val seq: Seq[T]) {
    def toJavaList = seq.foldLeft(new java.util.ArrayList[T](seq.size)) { (al, e) => al.add(e); al }
  }
  implicit def listToJavaList[T](l: Seq[T]) = new JavaListWrapper(l)

  def runTestSuitesTask = runTestSuites <<= (target, streams, testSuites) map {
    (targetDirectory, taskStream, suites) =>
      import taskStream.log
      log.info("running test suites: " + suites)
      runSuites(suites)
  }

  private def runSuites(testSuites: Seq[String]) = {
    var tester = new TestNG
    tester.setTestSuites(testSuites.toJavaList)
    tester.run()
  }

  def testSuiteSettings = {
    inConfig(Compile)(Seq(
      runTestSuitesTask,
      testSuites := Seq("testsuites/mysuite.xml"),
      libraryDependencies += "org.testng" % "testng" % "5.14"))
  }
}

问题在于,当我将此插件添加到项目并使用 run-test-suites 运行时,它会因 java.lang.NoClassDefFoundError:org / testng / TestNG <而失败/ strong>即使 show full-classpath 显示 testng.jar 在类路径中。

因此,在执行插件时使用的类路径与我项目中的类路径不同,那么如何在两个地方都出现插件依赖?

2 个答案:

答案 0 :(得分:1)

我会尝试回答,但我对sbt的内部细节不是很熟悉。

通常,构建系统的路径(与您的程序相对)在项目下,如here所述。那通常是project/plugins.sbt。听起来很正确,因为你没有理由认为你开发的应用程序应该关注构建系统使用的库,而不是相反。

当您的插件运行应用程序代码时,可能不是那么简单,并且可能存在类路径/类加载器问题。我不确定它会起作用。通常,您的插件应该实现测试框架而不是定义自己的任务。 Documentation of testing对于sbt是有限的。

测试框架应在test-interface中实施org.scalatools.testing.Framework。添加

后,您的构建将考虑到它
testFrameworks += new TestFramework("full.class.name")

当你运行正常的测试命令时,它让每个框架都能识别它所处理的测试类(两个可用的标准:扩展一些基类或有一些注释)并运行它们。框架在构建中运行,它被赋予一个类加载器来访问应用程序代码。

您可以查看the framework implementation for junit(随附sbt)。还有一个TestNG implementation。我不知道,根据它的文件,它有点非正统,希望它对你有用。

答案 1 :(得分:1)

通过在使用插件的项目中将TestNG直接添加到编译中的 unmanagedJars 来修复错误。

我没有找到任何资源来解释插件执行期间SBT类路径的结构,因此我们将非常感谢任何解释为什么需要这一步骤的尝试。