简体   繁体   中英

scala matchers works from jar not from sbt

I have a code blurb thats doing some reflection on scala class files and looking for annotations,something like

// Create a new class loader with the directory
val cl = new URLClassLoader(allpaths.toArray)


getTypeNamesFromPath(sourceDir).map(s => {
  val cls = cl.loadClass(s)
  cls.getAnnotations.map(an =>
    an match {
      case q: javax.ws.rs.Path => println("found annotation")
      case _ => 
    })
})

This code prints "found annotation" when assembling this in a jar and running using java -jar, but doesn't print anything when running from sbt run.

sbt version is 13.8, scala version 2.11.7

for completeness

 private def getTypeNamesFromPath(file: File, currentPath: mutable.Stack[String] = new mutable.Stack[String]()): List[String] = {
    if (file.isDirectory) {
      var list = List[String]()
      for (f <- file.listFiles()) {
        currentPath.push(f.getName)
        list = list ++ getTypeNamesFromPath(f, currentPath)
      }
      return list
    }

    if (currentPath.isEmpty)
      throw new IllegalArgumentException(file.getAbsolutePath)

    currentPath.pop()

    if (file.getName.endsWith(".class")) {
      return List(currentPath.foldRight("")((s, b) => if (b.isEmpty) s else b + "." + s) + "." + file.getName.stripSuffix(".class"))
    }
    return List()
  }

so it turns out i need two things...

  1. use URLClassLoader from scala.tools.nsc.util.ScalaClassLoader.URLClassLoader , this will solve loading the right classes.

  2. set the fork := true in build.sbt, because once you do step #1, you will run into issues with class name clashes because sbt runs with own class paths and own version of class loader, more on it here http://www.scala-sbt.org/0.13.0/docs/Detailed-Topics/Forking.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM