使用SBT处理库中的非托管类路径jar,以便依赖项目可以访问它们

时间:2013-08-19 08:34:07

标签: jar dependencies sbt packaging

我正在编写一个依赖于代码的库(我们称之为foo.jar),它只能作为二进制jar使用。作为标准,我将它放在lib/目录中,因此SBT将其视为非托管依赖项。到目前为止这很好。

但是,由于这是一个库,我希望能够发布它,以便依赖它的其他项目也可以访问foo.jar中的非托管代码,而无需手动定位它。我原本以为我可以使用像SBT Assembly这样的胖jar插件来创建一个带有依赖项的jar,但这不会影响使用sbt publish-local实际发布的内容 - 它只会在你创建一个胖jar时运行sbt assembly。是否有一些标准的简单方法来处理这个问题?对于每个使用非托管依赖项的库来说,当下游其他项目使用时,这似乎是一个坏主意,所以我想知道我是否遗漏了一些明显的东西。

2 个答案:

答案 0 :(得分:3)

我不知道这是否适用于sbt-assembly,因为其他库可能依赖于foo.jar等不同版本。

解决此问题的一种方法是自己在Maven存储库中发布foo.jar。 Scala和/或sbt社区中的一些人一直在讨论bintray。它还处于测试阶段,但如果你想要发布一些罐子,看起来很有希望。

答案 1 :(得分:1)

您可以通过操纵mappings in (Compile, packageBin)来包含您希望打包的jar具有的文件(publish使用packageBin的输出)来获得所需的结果。这种技术允许你在jar中包含你想要的任何文件。官方的sbt doc在这里:http://www.scala-sbt.org/0.12.3/docs/Howto/package.html#contents

作为示例,请考虑在jar中包含.properties文件的常见情况。假设您需要包含" messages.properties"在路径" com / bigco / messages.properties"在你的包装罐子里。并且假设此文件位于src / main / scala / ...下您可以将以下内容添加到build.sbt:

mappings in (Compile, packageBin) <+= baseDirectory map { base =>
  (base / "src" / "main" / "scala" / "com" / "bigco" / "messages.properties") -> "com/bigco/messages.properties"
}

要尝试回答原始问题,您可以解压缩foo.jar并根据正确的包路径将每个class文件添加到打包的jar中。所以类似于

mappings in (Compile, packageBin) <+= baseDirectory map { base => 
  (base / path / to / unzipped / file.class) -> "path.to.unzipped.file.class"
  ...
}

或者您可以通过简单地将foo.jar包含在打包的jar的根目录中来解决这个问题:

mappings in (Compile, packageBin) <+= baseDirectory map { base => 
  (base / "lib" / "foo.jar") -> "foo.jar"
}