gpt4 book ai didi

scala - SBT/Play2 多项目设置不包括运行/测试中类路径中的依赖项目

转载 作者:行者123 更新时间:2023-12-04 19:13:38 24 4
gpt4 key购买 nike

我有以下 SBT/Play2 多项目设置:

import sbt._
import Keys._
import PlayProject._

object ApplicationBuild extends Build {
val appName = "traveltime-api"
val appVersion = "1.0"

val appDependencies = Seq(
// Google geocoding library
"com.google.code.geocoder-java" % "geocoder-java" % "0.9",
// Emailer
"org.apache.commons" % "commons-email" % "1.2",
// CSV generator
"net.sf.opencsv" % "opencsv" % "2.0",

"org.scalatest" %% "scalatest" % "1.7.2" % "test",
"org.scalacheck" %% "scalacheck" % "1.10.0" % "test",
"org.mockito" % "mockito-core" % "1.9.0" % "test"
)

val lib = RootProject(file("../lib"))
val chiShape = RootProject(file("../chi-shape"))

lazy val main = PlayProject(
appName, appVersion, appDependencies, mainLang = SCALA
).settings(
// Add your own project settings here
resolvers ++= Seq(
"Sonatype Snapshots" at
"http://oss.sonatype.org/content/repositories/snapshots",
"Sonatype Releases" at
"http://oss.sonatype.org/content/repositories/releases"
),
// Scalatest compatibility
testOptions in Test := Nil
).aggregate(lib, chiShape).dependsOn(lib, chiShape)
}

如您所见,该项目依赖于两个独立的子项目:lib 和 chiShape。

现在编译工作正常 - 所有源代码都被正确编译。但是,如果我尝试运行或测试,运行时中的两个任务都没有加载类路径上子项目的类,并且由于 NoClassFound 异常,事情会变得困惑。

例如 - 我的应用程序必须从文件加载序列化数据,它是这样的:测试启动 FakeApplication,它尝试加载数据和繁荣:
[info] CsvGeneratorsTest:
[info] #markerFilterCsv
[info] - should fail on bad json *** FAILED ***
[info] java.lang.ClassNotFoundException: com.library.Node
[info] at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
[info] at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
[info] at java.security.AccessController.doPrivileged(Native Method)
[info] at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
[info] at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
[info] at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
[info] at java.lang.Class.forName0(Native Method)
[info] at java.lang.Class.forName(Class.java:264)
[info] at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:622)
[info] at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1593)
[info] ...

奇怪的是 stage 在 staged/中创建了一个包含 chi-shapes_2.9.1-1.0.jar 和 lib_2.9.1-1.0.jar 的目录结构。

如何让我的运行时/测试配置将子项目放入类路径?

更新:

我已将以下代码添加到 Global#onStart:
  override def onStart(app: Application) {
println(app)
ClassLoader.getSystemClassLoader.asInstanceOf[URLClassLoader].getURLs.
foreach(println)
throw new RuntimeException("foo!")
}

当我启动测试时,类路径的填充非常糟糕,至少可以说:)
FakeApplication(.,sbt.classpath.ClasspathUtilities$$anon$1@182253a,List(),List(),Map(application.load-data -> test, mailer.smtp.test-mode -> true))
file:/home/arturas/Software/sdks/play-2.0.3/framework/sbt/sbt-launch.jar
[info] CsvGeneratorsTest:

启动暂存应用程序时,有很多东西,它应该如何:)
$ target/start
Play server process ID is 29045
play.api.Application@1c2862b
file:/home/arturas/work/traveltime-api/api/target/staged/jul-to-slf4j.jar

这很奇怪,因为我认为类路径中至少应该有测试 jars?

最佳答案

看来我已经解决了。

罪魁祸首是对象输入流 默认情况下忽略线程本地类加载器,只使用系统类加载器。

所以我从:

  def unserialize[T](file: File): T = {
val in = new ObjectInputStream(new FileInputStream(file))
try {
in.readObject().asInstanceOf[T]
}
finally {
in.close
}
}

到:
  /**
* Object input stream which respects thread local class loader.
*
* TL class loader is used by SBT to avoid polluting system class loader when
* running different tasks.
*/
class TLObjectInputStream(in: InputStream) extends ObjectInputStream(in) {
override protected def resolveClass(desc: ObjectStreamClass): Class[_] = {
Option(Thread.currentThread().getContextClassLoader).map { cl =>
try { return cl.loadClass(desc.getName)}
catch { case (e: java.lang.ClassNotFoundException) => () }
}
super.resolveClass(desc)
}
}

def unserialize[T](file: File): T = {
val in = new TLObjectInputStream(new FileInputStream(file))
try {
in.readObject().asInstanceOf[T]
}
finally {
in.close
}
}

而我的类没有发现问题就消失了!

感谢 How to put custom ClassLoader to use?http://tech-tauk.blogspot.com/2010/05/thread-context-classlaoder-in.html关于反序列化和线程本地类加载器的有用见解。

关于scala - SBT/Play2 多项目设置不包括运行/测试中类路径中的依赖项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12496939/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com