使用sbt-aspect创建一个AspectJ库

我正在编写一个进行监视/ 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处创建了一个示例项目,以表明我遇到的问题,但以下是相关示例

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",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发布root/publishLocal项目,而测试项目只是设计为包含root作为libraryDependency,因此我们可以查看方面-j工作正常。

问题很简单,我无法使其正常运行。 https://github.com/mdedetrich/sbt-aspectj-issue处的当前代码与root/publishLocal一起发布(虽然不确定其是否正确),但是当我然后执行test/run时,我得到了

[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

x4701481 回答:使用sbt-aspect创建一个AspectJ库

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

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​​,则项目布局和构建脚本会稍微复杂一些,但也更易于维护。

本文链接:https://www.f2er.com/2844431.html

大家都在问