首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用sbt-aspect创建aspectJ库

使用sbt-aspect创建aspectJ库
EN

Stack Overflow用户
提问于 2019-12-29 23:34:03
回答 1查看 116关注 0票数 0

我正在编写一个执行监控/OpenTracing的库,并且我正在尝试使用sbt-aspectj,这样库的用户就不需要手动插装他们的代码。然而,我目前在创建代表这样一个库的sbt-project时遇到了一个问题。

我的想法是,我想要一个外部库,就像这个示例中指出的那样,https://github.com/sbt/sbt-aspectj/tree/master/src/sbt-test/weave/external,但是这个外部库依赖于一个外部依赖项(即akka-actors)。基本上,我尝试将https://github.com/sbt/sbt-aspectj/tree/master/src/sbt-test/weave/externalhttps://github.com/sbt/sbt-aspectj/tree/master/src/sbt-test/weave/jar结合起来。我在这里创建了一个样例项目https://github.com/mdedetrich/sbt-aspectj-issue来指出我遇到的问题,但下面是相关的样例

代码语言:javascript
复制
lazy val root = (project in file("."))
  .enablePlugins(SbtAspectj)
  .settings(
    name := RootName,
    version := Version,
    // add akka-actor as an aspectj input (find it in the update report)
//    aspectjInputs in Aspectj ++= update.value.matching(
//      moduleFilter(organization = "com.typesafe.akka", name = "akka-actor*")),
    // replace the original akka-actor jar with the instrumented classes in runtime
//    fullClasspath in Runtime := aspectjUseInstrumentedClasses(Runtime).value,
    // only compile the aspects (no weaving)
    aspectjCompileOnly in Aspectj := true,
    // ignore warnings (we don't have the target classes at this point)
    aspectjLintProperties in Aspectj += "invalidAbsoluteTypeName = ignore",
    // replace regular products with compiled aspects
    products in Compile ++= (products in Aspectj).value,
    libraryDependencies ++= Seq(
      "com.typesafe.akka" %% "akka-actor" % akkaVersion
    )
  )

lazy val test = (project in file("test"))
  .enablePlugins(SbtAspectj)
  .settings(
    aspectjBinaries in Aspectj ++= update.value.matching(
      moduleFilter(organization = Organization, name = s"$RootName*")),
    aspectjInputs in Aspectj ++= update.value.matching(
      moduleFilter(organization = "com.typesafe.akka", name = "akka-actor*")),
    fullClasspath in Runtime := aspectjUseInstrumentedClasses(Runtime).value,
    // weave this project's classes
    aspectjInputs in Aspectj += (aspectjCompiledClasses in Aspectj).value,
    products in Compile := (products in Aspectj).value,
    products in Runtime := (products in Compile).value,
    libraryDependencies ++= Seq(
      Organization %% RootName % Version
    )
  )

我们的想法是,我们使用root/publishLocal发布root项目,而测试项目只是被设计为包含root作为libraryDependency,这样我们就可以看到aspect-j是否正常工作。

问题很简单,我不能让它工作。https://github.com/mdedetrich/sbt-aspectj-issue的当前代码是用root/publishLocal发布的(虽然不确定它是否正确),但是当我执行test/run时,我得到了如下结果

代码语言:javascript
复制
[info] Weaving 2 inputs with 1 AspectJ binary to /home/mdedetrich/github/sbt-aspectj-issue/test/target/scala-2.13/aspectj/classes...
[error] stack trace is suppressed; run last test / Compile / packageBin for the full output
[error] (test / Compile / packageBin) java.util.zip.ZipException: duplicate entry: META-INF/MANIFEST.MF
[error] Total time: 1 s, completed Dec 29, 2019 4:31:27 PM
sbt:sbt-aspectj-issue> 

这似乎是具有重复的akka-actor条目的问题。我尝试在build.sbt中切换各种条目,但没有成功。

编辑:这也是github在https://github.com/sbt/sbt-aspectj/issues/44上发布的问题

EN

回答 1

Stack Overflow用户

发布于 2019-12-31 10:43:09

通常,您可以从编织的外部库中排除META-INF目录。

代码语言:javascript
复制
mappings in (Compile, packageBin) := {
    (mappings in (Compile, packageBin)).value
        .filterNot(_._2.startsWith("META-INF/"))
}

但对于akka库来说,还有另一个问题。在每个akka库中,都有一个reference.conf,其中包含所提供功能的回退配置。这也会导致像META-INF那样的冲突。但它不能像META-INF一样被排除在外,因为它们对于akka的正常工作至关重要。

如果你排除了它们,你必须在你的application.conf中提供所有需要的akka配置,或者在你的项目中提供一个合并的(而不是简单的连接) reference.conf。这不是微不足道的,而且会受到akka版本变化的影响。

另一种解决方案是分别编织和重新打包akka库,这样reference.conf就可以保存在重新打包的库中。项目布局和构建脚本会有点复杂,但如果你计划在未来升级到更新版本的akka,也会更容易维护。

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

https://stackoverflow.com/questions/59520762

复制
相关文章

相似问题

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