首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对SBT中的模块依赖项使用自定义类加载程序

对SBT中的模块依赖项使用自定义类加载程序
EN

Stack Overflow用户
提问于 2015-04-11 14:07:59
回答 1查看 1.9K关注 0票数 9

我有一个由apicorethird-party组成的多模块SBT构建.其结构大致如下:

代码语言:javascript
复制
api
|- core
|- third-party

third-party的代码实现了api,是从其他地方逐字复制的,所以我真的不想碰它。

由于third-party的实现方式(大量使用单例),我不能只让core依赖于third-party。具体来说,我只需要通过api使用它,但是我需要在运行时拥有多个独立的third-party副本。(这允许我同时拥有多个“单身汉”。)

如果我在SBT构建之外运行,我只需要这样做:

代码语言:javascript
复制
def createInstance(): foo.bar.API = {
  val loader = new java.net.URLClassLoader("path/to/third-party.jar", parent)
  loader.loadClass("foo.bar.Impl").asSubclass(classOf[foo.bar.API]).newInstance()
}

但问题是,如果我是通过URLClassLoader运行的,那么我不知道如何在运行时为sbt core/run提供一个参数。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-11 16:12:27

这应该是可行的,虽然我并没有用你的设置来测试它。

基本思想是让sbt将类路径写入一个您可以在运行时使用的文件中。sbt-buildinfo已经为此提供了一个很好的基础,所以我将在这里使用它,但是您可能只提取相关的部分,而不使用这个插件。

将此添加到项目定义中:

代码语言:javascript
复制
lazy val core = project enablePlugins BuildInfoPlugin settings (
  buildInfoKeys := Seq(BuildInfoKey.map(exportedProducts in (`third-party`, Runtime)) {
    case (_, classFiles) ⇒ ("thirdParty", classFiles.map(_.data.toURI.toURL)) 
  })
  ...

在运行时,请使用以下命令:

代码语言:javascript
复制
def createInstance(): foo.bar.API = {
  val loader = new java.net.URLClassLoader(buildinfo.BuildInfo.thirdParty.toArray, parent)
  loader.loadClass("foo.bar.Impl").asSubclass(classOf[foo.bar.API]).newInstance()
}

exportedProducts只包含项目的编译类(例如.../target/scala-2.10/classes/)。根据您的设置,您可能希望使用fullClasspath (它还包含libraryDependencies和依赖项目)或任何其他与类路径相关的键。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29578808

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档