在SBT构建期间无法在同一个jar中找到类

时间:2017-03-22 09:33:00

标签: sbt classpath

我正在尝试构建像swagger2markup这样的sbt插件,但在sbt中执行此操作时遇到问题:

org.apache.commons.configuration2.ex.ConfigurationRuntimeException: java.lang.ClassNotFoundException: org.apache.commons.configuration2.PropertiesConfiguration
    at org.apache.commons.configuration2.beanutils.BeanHelper.fetchBeanClass(BeanHelper.java:549)
..snip..
Caused by: java.lang.ClassNotFoundException: org.apache.commons.configuration2.PropertiesConfiguration
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at org.apache.commons.lang3.ClassUtils.getClass(ClassUtils.java:909)

因此,尝试从同一个jar中的类查找PropertiesConfiguration失败。似乎sbt在不包含依赖项的类加载器中运行任务。当我从sbt控制台运行任务时会发生这种情况。

2 个答案:

答案 0 :(得分:0)

commons-configuration2正在使用commons-lang3加载ConfigurationBuilder的类文件。并且commons-lang正在尝试使用当前线程中的ClassLoader来执行加载,请参阅ClassUtils,但似乎sbt并未对Thread.currentThread().getContextClassLoader提供任何保证,有关详细信息,请参阅discussion

解决方法是手动当前线程classLoader,如:

Thread.currentThread().setContextClassLoader(
  PluignObject.getClass.getClassLoader
)

但说实话,我不确定这个解决方案有多安全。

答案 1 :(得分:0)

我最终管理的解决方法是在分叉的jvm进程中调用任务:

val runner: ScalaRun = initScoped(myTask.scopedKey, Defaults.runnerInit).value
val log: Logger = streams.value.log
val arguments = Seq()
runner.run(mainClass, classpath.map(_.data), arguments, log)

当我使用的工具中有一个主类时,这对我有用。