2017-05-29 14 views
5
lihaoyi test$ tree 
. 
└── Foo.scala 

0 directories, 1 file 

lihaoyi test$ cat Foo.scala 
object Main{ 
    def main(args: Array[String]): Unit = { 
    println(getClass.getClassLoader.getResourceAsStream("java/lang/String.class")) 
    println(getClass.getClassLoader.getClass) 
    println(Thread.currentThread().getContextClassLoader.getResourceAsStream("java/lang/String.class")) 
    println(Thread.currentThread().getContextClassLoader.getClass) 
    } 
} 

lihaoyi test$ sbt run 
[info] Loading global plugins from /Users/lihaoyi/.sbt/0.13/plugins 
[info] Set current project to test (in build file:/Users/lihaoyi/Dropbox/Workspace/test/) 
[info] Updating {file:/Users/lihaoyi/Dropbox/Workspace/test/}test... 
[info] Resolving org.fusesource.jansi#jansi;1.4 ... 
[info] Done updating. 
[info] Compiling 1 Scala source to /Users/lihaoyi/Dropbox/Workspace/test/target/scala-2.10/classes... 
[info] Running Main 
[email protected]8ff2 
class sbt.classpath.ClasspathUtilities$$anon$1 
null 
class sbt.classpath.ClasspathFilter 
[success] Total time: 2 s, completed 29 May, 2017 4:14:11 PM 

lihaoyi test$ 

Ở đây, chúng ta có thể thấy rằng getClass.getClassLoaderThread.currentThread.getContextClassLoader đang trả về các giá trị khác nhau. Hơn nữa, các Thread.currentThread.getContextClassLoader dường như từ chối để tải java/lang/String.class, trong khi khác có thể.Tại sao trình nạp lớp ngữ cảnh chủ đề của SBT không tải được các tệp lớp JDK làm tài nguyên?

Đáng chú ý, khi tôi chạy file jar sử dụng một công cụ bên ngoài như scalac/scala, hoặc java, cả classloaders có thể tải các classfile như một nguồn lực

lihaoyi test$ scalac Foo.scala 

lihaoyi test$ scala Main 
[email protected]cdfa 
class scala.reflect.internal.util.ScalaClassLoader$URLClassLoader 
[email protected]724f 
class scala.reflect.internal.util.ScalaClassLoader$URLClassLoader 

Tôi mong chờ SBT để hành xử tương tự: để có Main.getClass.getClassLoaderThread.currentThread().getContextClassLoader cả hai đều có thể tải java/lang/String.class làm tài nguyên. Đưa cái gì?

Trả lời

3

Một số gợi ý được cung cấp bởi Jason Zaugg (viết tắt) của sbt launcher notes.

sbt/launcher là một ứng dụng Scala nhỏ khởi động chương trình Scala tùy ý (thường là SBT) mô tả tệp cấu hình và có nguồn gốc thông qua độ phân giải phụ thuộc của Ivy.

Điều này tạo bộ nạp lớp con chứa Scala 2.10.6. Một phần tử con này chứa chính SBT và xsbti/interface-0.13.11.jar.

SBT cần sử dụng phân cấp trình nạp lớp không chuẩn để ẩn lớp có chọn lọc khi tạo trình nạp lớp con cho mã plugin, cho trình biên dịch Scala hoặc cho mã người dùng.

Một số gợi ý ở những SBT 0.13 nguồn:

def makeLoader(classpath: Seq[File], instance: ScalaInstance, nativeTemp: File): ClassLoader = 
    filterByClasspath(classpath, makeLoader(classpath, instance.loader, instance, nativeTemp)) 


def makeLoader(classpath: Seq[File], parent: ClassLoader, instance: ScalaInstance, nativeTemp: File): ClassLoader = 
    toLoader(classpath, parent, createClasspathResources(classpath, instance), nativeTemp) 

Về cơ bản SBT là một bồn rửa chén của một ứng dụng Java có một Scala tùy ý các phiên bản và mã của bạn, và các thư viện thử nghiệm của bạn cùng với Java libr của Oracle/OpenJDK ary. Để xây dựng một classpath có ý nghĩa mà không cần tải chúng lặp đi lặp lại, nó tạo ra một hệ thống phân cấp của các trình nạp lớp từng được lọc theo một số tiêu chí. (Tôi nghĩ)

1

Đáng chú ý, có một cách để làm việc xung quanh vấn đề này là để thiết lập

(fork in run) := true, 

(connectInput in run) := true, 
(outputStrategy in run) := Some(StdoutOutput), 

Đó dường như để giải quyết vấn đề này, (Thread.currentThread().getContextClassLoader.getResourceAsStream("java/lang/String.class") hiện đang làm việc) nhưng giới thiệu các vấn đề liên quan khác (chia hai JVM mất một chút thời để khởi động, khởi động lạnh và cần thời gian để hâm nóng ...)

Các vấn đề liên quan