5

How do you link to Java classes in sbt using apiMappings? This is my code below which works for various dependencies, but I'm unclear how to link to Java standard library classes?

apiMappings ++= {
  def findManagedDependency(organization: String, name: String): Option[File] = {
    (for {
      entry <- (fullClasspath in Runtime).value ++ (fullClasspath in Test).value
      module <- entry.get(moduleID.key) if module.organization == organization && module.name.startsWith(name)
    } yield entry.data).headOption
  }
  val links = Seq(
    findManagedDependency("org.scala-lang", "scala-library").map(d => d -> url(s"http://www.scala-lang.org/api/$scalaVsn/")),
    findManagedDependency("com.typesafe.akka", "akka-actor").map(d => d -> url(s"http://doc.akka.io/api/akka/$akkaVersion/")),
    findManagedDependency("com.typesafe", "config").map(d => d -> url("http://typesafehub.github.io/config/latest/api/")),
    findManagedDependency("com.fasterxml.jackson.core", "jackson-core").map(d => d -> url("http://fasterxml.github.io/jackson-core/javadoc/2.3.1/")),
    findManagedDependency("io.spray", "spray-http").map(d => d -> url("http://spray.io/documentation/1.1-SNAPSHOT/api/")),
    findManagedDependency("io.spray", "spray-routing").map(d => d -> url("http://spray.io/documentation/1.1-SNAPSHOT/api/")),
    findManagedDependency("org.slf4j", "slf4j-api").map(d => d -> url("http://www.slf4j.org/api/")),
    findManagedDependency("com.typesafe.akka", "akka-testkit").map(d => d -> url(s"http://doc.akka.io/api/akka/$akkaVersion/")),
    findManagedDependency("org.specs2", "specs2").map(d => d -> url(s"http://etorreborre.github.io/specs2/api/SPECS2-$specs2Version/"))
  )
  links.collect { case Some(d) => d }.toMap
}
Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
Taylor Leese
  • 51,004
  • 28
  • 112
  • 141
  • Are you looking to link Java libraries or Scala standard library? If it's Java, this question is a duplicate of http://stackoverflow.com/questions/16934488, and basically not supported by Scaladoc. – Eugene Yokota May 01 '14 at 06:31
  • @EugeneYokota I'm trying to link to the standard Java library. Prior to 2.11 I used "-external-urls" and it worked great, but that option isn't available anymore. There's no legitimate way to do this anymore? That seems...not optimal. – Taylor Leese May 01 '14 at 07:36
  • What is missing in my answer to http://stackoverflow.com/q/16934488/1305344 that you need for your use case? Can you do `last doc` after executing `doc` to see what options are missing and compare with the different versions of Scala? I really need more input to work on the use case. – Jacek Laskowski Aug 01 '14 at 13:16
  • Noting you're using what can roughly be called the “findManagedDependency pattern,” you might be interested [in an answer I've given to a related question that makes these mappings more generic](http://stackoverflow.com/a/35673212/700420) (and reusable). – Michael Ahlers Feb 27 '16 at 17:51

2 Answers2

0

Use the solution from How to link classes from JDK into scaladoc-generated doc?, i.e. add the following to apiMappings:

apiMappings += (
    file("/Library/Java/JavaVirtualMachines/jdk1.8.0_11.jdk/Contents/Home/jre/lib/rt.jar") -> 
    url("http://docs.oracle.com/javase/8/docs/api")
)

and fixJavaLinksTask task will do the rest with the following in build.sbt:

import scala.util.matching.Regex.Match

autoAPIMappings := true

// builds -doc-external-doc
apiMappings += (
    file("/Library/Java/JavaVirtualMachines/jdk1.8.0_11.jdk/Contents/Home/jre/lib/rt.jar") -> 
    url("http://docs.oracle.com/javase/8/docs/api")
)

lazy val fixJavaLinksTask = taskKey[Unit](
    "Fix Java links - replace #java.io.File with ?java/io/File.html"
)

fixJavaLinksTask := {
  println("Fixing Java links")
  val t = (target in (Compile, doc)).value
  (t ** "*.html").get.filter(hasJavadocApiLink).foreach { f => 
    println("fixing " + f)
    val newContent = javadocApiLink.replaceAllIn(IO.read(f), fixJavaLinks)
    IO.write(f, newContent)
  }
}

val fixJavaLinks: Match => String = m =>
    m.group(1) + "?" + m.group(2).replace(".", "/") + ".html"

val javadocApiLink = """\"(http://docs\.oracle\.com/javase/8/docs/api/index\.html)#([^"]*)\"""".r

def hasJavadocApiLink(f: File): Boolean = (javadocApiLink findFirstIn IO.read(f)).nonEmpty

fixJavaLinksTask <<= fixJavaLinksTask triggeredBy (doc in Compile)
Community
  • 1
  • 1
Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
0

You may find my answer to this question what you are looking for.

This main difference between that answer and the other answer posted here is that the location of rt.jar is determined from the runtime, and not hard coded.

Community
  • 1
  • 1
Andrew Bate
  • 406
  • 3
  • 17