lar*_*srh 9 scala classloader sbt
我有一个多模块构建SBT组成的api,core和third-party.结构大致如下:
api
|- core
|- third-party
Run Code Online (Sandbox Code Playgroud)
third-party实现的代码api和从其他地方逐字复制,所以我真的不想触摸它.
由于实施的方式third-party(大量使用单身人士),我不能只core依赖third-party.具体来说,我只需要通过它来使用它api,但我需要third-party在运行时拥有多个独立的副本.(这允许我同时拥有多个"单身人士".)
如果我在我的SBT构建之外运行,我只是这样做:
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()
}
Run Code Online (Sandbox Code Playgroud)
但问题是,我不知道如何在运行时弄清楚URLClassLoader如果我正在运行,我应该给出什么作为参数sbt core/run.
这应该可行,但我没有用你的设置测试它.
基本思想是让sbt将类路径写入可在运行时使用的文件中.sbt-buildinfo 已经为此提供了一个很好的基础,所以我将在这里使用它,但你可能只提取相关部分而不使用这个插件.
将其添加到项目定义中:
lazy val core = project enablePlugins BuildInfoPlugin settings (
buildInfoKeys := Seq(BuildInfoKey.map(exportedProducts in (`third-party`, Runtime)) {
case (_, classFiles) ? ("thirdParty", classFiles.map(_.data.toURI.toURL))
})
...
Run Code Online (Sandbox Code Playgroud)
在运行时,使用此:
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()
}
Run Code Online (Sandbox Code Playgroud)
exportedProducts仅包含项目的已编译类(例如.../target/scala-2.10/classes/).根据您的设置,您可能希望使用fullClasspath(也包含libraryDependencies和依赖项目)或任何其他类路径相关键.
| 归档时间: |
|
| 查看次数: |
1183 次 |
| 最近记录: |