我正在尝试构建像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控制台运行任务时会发生这种情况。
答案 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)
当我使用的工具中有一个主类时,这对我有用。