2015-05-22 4 views
15

Ich habe ein Projekt, das JOCL-Bibliothek (http://www.jocl.org/) verwendet und mehrere Module hat. Als ich „./activator test“ von der Kommandozeile, oder führen Sie ‚test‘ Befehl in SBT-Konsole ausführen Ich erhalte Fehler wie folgt aus:"UnzufriedenerLinkError: Native Bibliothek bereits in einem anderen Klassenlader geladen" in Multimodul-Projekt

[info] Exception encountered when attempting to run a suite with class name: pl.tarsa.sortalgobox.opencl.CpuMergeSortSpec *** ABORTED *** 
[info] java.lang.UnsatisfiedLinkError: Error while loading native library "JOCL_0_1_9-linux-x86_64" with base name "JOCL_0_1_9" 
[info] Operating system name: Linux 
[info] Architecture   : amd64 
[info] Architecture bit size: 64 
[info] ---(start of nested stack traces)--- 
[info] Stack trace from the attempt to load the library as a file: 
[info] java.lang.UnsatisfiedLinkError: no JOCL_0_1_9-linux-x86_64 in java.library.path 
[info] at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1865) 
[info] at java.lang.Runtime.loadLibrary0(Runtime.java:870) 
[info] at java.lang.System.loadLibrary(System.java:1122) 
[info] at org.jocl.LibUtils.loadLibrary(LibUtils.java:80) 
[info] at org.jocl.CL.<clinit>(CL.java:47) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextDescription$.enumerate(CLContextDescription.scala:44) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsManager$.contextsDescriptions$lzycompute(CLContextsManager.scala:6) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsManager$.contextsDescriptions(CLContextsManager.scala:6) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsManager$.createCpuContext(CLContextsManager.scala:9) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsCache$.cpuContext$lzycompute(CLContextsCache.scala:24) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsCache$.cpuContext(CLContextsCache.scala:24) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsCache$.withCpuContext(CLContextsCache.scala:28) 
[info] at pl.tarsa.sortalgobox.opencl.common.CpuSort.sort(CpuSort.scala:34) 
[info] at pl.tarsa.sortalgobox.opencl.common.CpuSort.sort(CpuSort.scala:32) 
[info] at pl.tarsa.sortalgobox.sorts.SortChecker.forEmptyArray(SortChecker.scala:31) 
[info] at pl.tarsa.sortalgobox.opencl.CpuMergeSortSpec$$anonfun$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(CpuMergeSortSpec.scala:32) 
[info] at pl.tarsa.sortalgobox.tests.CommonUnitSpecBase.guardedOpenCLTest(CommonUnitSpecBase.scala:40) 
[info] at pl.tarsa.sortalgobox.opencl.CpuMergeSortSpec$$anonfun$1.apply$mcV$sp(CpuMergeSortSpec.scala:31) 
[info] at pl.tarsa.sortalgobox.opencl.CpuMergeSortSpec$$anonfun$1.apply(CpuMergeSortSpec.scala:31) 
[info] at pl.tarsa.sortalgobox.opencl.CpuMergeSortSpec$$anonfun$1.apply(CpuMergeSortSpec.scala:31) 
[info] at org.scalatest.Transformer$$anonfun$apply$1.apply$mcV$sp(Transformer.scala:22) 
[info] at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85) 
[info] at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104) 
[info] at org.scalatest.Transformer.apply(Transformer.scala:22) 
[info] at org.scalatest.Transformer.apply(Transformer.scala:20) 
[info] at org.scalatest.FlatSpecLike$$anon$1.apply(FlatSpecLike.scala:1647) 
[info] at org.scalamock.scalatest.AbstractMockFactory$$anonfun$withFixture$1.apply(AbstractMockFactory.scala:35) 
[info] at org.scalamock.scalatest.AbstractMockFactory$$anonfun$withFixture$1.apply(AbstractMockFactory.scala:34) 
[info] at org.scalamock.MockFactoryBase$class.withExpectations(MockFactoryBase.scala:41) 
[info] at pl.tarsa.sortalgobox.tests.CommonUnitSpecBase.withExpectations(CommonUnitSpecBase.scala:28) 
[info] at org.scalamock.scalatest.AbstractMockFactory$class.withFixture(AbstractMockFactory.scala:34) 
[info] at pl.tarsa.sortalgobox.tests.CommonUnitSpecBase.withFixture(CommonUnitSpecBase.scala:28) 
[info] at org.scalatest.FlatSpecLike$class.invokeWithFixture$1(FlatSpecLike.scala:1644) 
[info] at org.scalatest.FlatSpecLike$$anonfun$runTest$1.apply(FlatSpecLike.scala:1656) 
[info] at org.scalatest.FlatSpecLike$$anonfun$runTest$1.apply(FlatSpecLike.scala:1656) 
[info] at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306) 
[info] at org.scalatest.FlatSpecLike$class.runTest(FlatSpecLike.scala:1656) 
[info] at org.scalatest.FlatSpec.runTest(FlatSpec.scala:1683) 
[info] at org.scalatest.FlatSpecLike$$anonfun$runTests$1.apply(FlatSpecLike.scala:1714) 
[info] at org.scalatest.FlatSpecLike$$anonfun$runTests$1.apply(FlatSpecLike.scala:1714) 
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:413) 
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:401) 
[info] at scala.collection.immutable.List.foreach(List.scala:381) 
[info] at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401) 
[info] at org.scalatest.SuperEngine.org$scalatest$SuperEngine$$runTestsInBranch(Engine.scala:390) 
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:427) 
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:401) 
[info] at scala.collection.immutable.List.foreach(List.scala:381) 
[info] at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401) 
[info] at org.scalatest.SuperEngine.org$scalatest$SuperEngine$$runTestsInBranch(Engine.scala:396) 
[info] at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:483) 
[info] at org.scalatest.FlatSpecLike$class.runTests(FlatSpecLike.scala:1714) 
[info] at org.scalatest.FlatSpec.runTests(FlatSpec.scala:1683) 
[info] at org.scalatest.Suite$class.run(Suite.scala:1424) 
[info] at org.scalatest.FlatSpec.org$scalatest$FlatSpecLike$$super$run(FlatSpec.scala:1683) 
[info] at org.scalatest.FlatSpecLike$$anonfun$run$1.apply(FlatSpecLike.scala:1760) 
[info] at org.scalatest.FlatSpecLike$$anonfun$run$1.apply(FlatSpecLike.scala:1760) 
[info] at org.scalatest.SuperEngine.runImpl(Engine.scala:545) 
[info] at org.scalatest.FlatSpecLike$class.run(FlatSpecLike.scala:1760) 
[info] at org.scalatest.FlatSpec.run(FlatSpec.scala:1683) 
[info] at org.scalatest.tools.Framework.org$scalatest$tools$Framework$$runSuite(Framework.scala:462) 
[info] at org.scalatest.tools.Framework$ScalaTestTask.execute(Framework.scala:671) 
[info] at sbt.TestRunner.runTest$1(TestFramework.scala:76) 
[info] at sbt.TestRunner.run(TestFramework.scala:85) 
[info] at sbt.TestFramework$$anon$2$$anonfun$$init$$1$$anonfun$apply$8.apply(TestFramework.scala:202) 
[info] at sbt.TestFramework$$anon$2$$anonfun$$init$$1$$anonfun$apply$8.apply(TestFramework.scala:202) 
[info] at sbt.TestFramework$.sbt$TestFramework$$withContextLoader(TestFramework.scala:185) 
[info] at sbt.TestFramework$$anon$2$$anonfun$$init$$1.apply(TestFramework.scala:202) 
[info] at sbt.TestFramework$$anon$2$$anonfun$$init$$1.apply(TestFramework.scala:202) 
[info] at sbt.TestFunction.apply(TestFramework.scala:207) 
[info] at sbt.Tests$$anonfun$9.apply(Tests.scala:216) 
[info] at sbt.Tests$$anonfun$9.apply(Tests.scala:216) 
[info] at sbt.std.Transform$$anon$3$$anonfun$apply$2.apply(System.scala:44) 
[info] at sbt.std.Transform$$anon$3$$anonfun$apply$2.apply(System.scala:44) 
[info] at sbt.std.Transform$$anon$4.work(System.scala:63) 
[info] at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226) 
[info] at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226) 
[info] at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17) 
[info] at sbt.Execute.work(Execute.scala:235) 
[info] at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226) 
[info] at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226) 
[info] at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159) 
[info] at sbt.CompletionService$$anon$2.call(CompletionService.scala:28) 
[info] at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
[info] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
[info] at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
[info] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
[info] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
[info] at java.lang.Thread.run(Thread.java:745) 
[info] Stack trace from the attempt to load the library as a resource: 
[info] java.lang.UnsatisfiedLinkError: Native Library /tmp/libJOCL_0_1_9-linux-x86_64.so already loaded in another classloader 
[info] at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1903) 
[info] at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1822) 
[info] at java.lang.Runtime.load0(Runtime.java:809) 
[info] at java.lang.System.load(System.java:1086) 
[info] at org.jocl.LibUtils.loadLibraryResource(LibUtils.java:188) 
[info] at org.jocl.LibUtils.loadLibrary(LibUtils.java:91) 
[info] at org.jocl.CL.<clinit>(CL.java:47) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextDescription$.enumerate(CLContextDescription.scala:44) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsManager$.contextsDescriptions$lzycompute(CLContextsManager.scala:6) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsManager$.contextsDescriptions(CLContextsManager.scala:6) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsManager$.createCpuContext(CLContextsManager.scala:9) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsCache$.cpuContext$lzycompute(CLContextsCache.scala:24) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsCache$.cpuContext(CLContextsCache.scala:24) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsCache$.withCpuContext(CLContextsCache.scala:28) 
[info] at pl.tarsa.sortalgobox.opencl.common.CpuSort.sort(CpuSort.scala:34) 
[info] at pl.tarsa.sortalgobox.opencl.common.CpuSort.sort(CpuSort.scala:32) 
[info] at pl.tarsa.sortalgobox.sorts.SortChecker.forEmptyArray(SortChecker.scala:31) 
[info] at pl.tarsa.sortalgobox.opencl.CpuMergeSortSpec$$anonfun$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(CpuMergeSortSpec.scala:32) 
[info] at pl.tarsa.sortalgobox.tests.CommonUnitSpecBase.guardedOpenCLTest(CommonUnitSpecBase.scala:40) 
[info] at pl.tarsa.sortalgobox.opencl.CpuMergeSortSpec$$anonfun$1.apply$mcV$sp(CpuMergeSortSpec.scala:31) 
[info] at pl.tarsa.sortalgobox.opencl.CpuMergeSortSpec$$anonfun$1.apply(CpuMergeSortSpec.scala:31) 
[info] at pl.tarsa.sortalgobox.opencl.CpuMergeSortSpec$$anonfun$1.apply(CpuMergeSortSpec.scala:31) 
[info] at org.scalatest.Transformer$$anonfun$apply$1.apply$mcV$sp(Transformer.scala:22) 
[info] at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85) 
[info] at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104) 
[info] at org.scalatest.Transformer.apply(Transformer.scala:22) 
[info] at org.scalatest.Transformer.apply(Transformer.scala:20) 
[info] at org.scalatest.FlatSpecLike$$anon$1.apply(FlatSpecLike.scala:1647) 
[info] at org.scalamock.scalatest.AbstractMockFactory$$anonfun$withFixture$1.apply(AbstractMockFactory.scala:35) 
[info] at org.scalamock.scalatest.AbstractMockFactory$$anonfun$withFixture$1.apply(AbstractMockFactory.scala:34) 
[info] at org.scalamock.MockFactoryBase$class.withExpectations(MockFactoryBase.scala:41) 
[info] at pl.tarsa.sortalgobox.tests.CommonUnitSpecBase.withExpectations(CommonUnitSpecBase.scala:28) 
[info] at org.scalamock.scalatest.AbstractMockFactory$class.withFixture(AbstractMockFactory.scala:34) 
[info] at pl.tarsa.sortalgobox.tests.CommonUnitSpecBase.withFixture(CommonUnitSpecBase.scala:28) 
[info] at org.scalatest.FlatSpecLike$class.invokeWithFixture$1(FlatSpecLike.scala:1644) 
[info] at org.scalatest.FlatSpecLike$$anonfun$runTest$1.apply(FlatSpecLike.scala:1656) 
[info] at org.scalatest.FlatSpecLike$$anonfun$runTest$1.apply(FlatSpecLike.scala:1656) 
[info] at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306) 
[info] at org.scalatest.FlatSpecLike$class.runTest(FlatSpecLike.scala:1656) 
[info] at org.scalatest.FlatSpec.runTest(FlatSpec.scala:1683) 
[info] at org.scalatest.FlatSpecLike$$anonfun$runTests$1.apply(FlatSpecLike.scala:1714) 
[info] at org.scalatest.FlatSpecLike$$anonfun$runTests$1.apply(FlatSpecLike.scala:1714) 
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:413) 
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:401) 
[info] at scala.collection.immutable.List.foreach(List.scala:381) 
[info] at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401) 
[info] at org.scalatest.SuperEngine.org$scalatest$SuperEngine$$runTestsInBranch(Engine.scala:390) 
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:427) 
[info] at org.scalatest.SuperEngine$$anonfun$traverseSubNodes$1$1.apply(Engine.scala:401) 
[info] at scala.collection.immutable.List.foreach(List.scala:381) 
[info] at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401) 
[info] at org.scalatest.SuperEngine.org$scalatest$SuperEngine$$runTestsInBranch(Engine.scala:396) 
[info] at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:483) 
[info] at org.scalatest.FlatSpecLike$class.runTests(FlatSpecLike.scala:1714) 
[info] at org.scalatest.FlatSpec.runTests(FlatSpec.scala:1683) 
[info] at org.scalatest.Suite$class.run(Suite.scala:1424) 
[info] at org.scalatest.FlatSpec.org$scalatest$FlatSpecLike$$super$run(FlatSpec.scala:1683) 
[info] at org.scalatest.FlatSpecLike$$anonfun$run$1.apply(FlatSpecLike.scala:1760) 
[info] at org.scalatest.FlatSpecLike$$anonfun$run$1.apply(FlatSpecLike.scala:1760) 
[info] at org.scalatest.SuperEngine.runImpl(Engine.scala:545) 
[info] at org.scalatest.FlatSpecLike$class.run(FlatSpecLike.scala:1760) 
[info] at org.scalatest.FlatSpec.run(FlatSpec.scala:1683) 
[info] at org.scalatest.tools.Framework.org$scalatest$tools$Framework$$runSuite(Framework.scala:462) 
[info] at org.scalatest.tools.Framework$ScalaTestTask.execute(Framework.scala:671) 
[info] at sbt.TestRunner.runTest$1(TestFramework.scala:76) 
[info] at sbt.TestRunner.run(TestFramework.scala:85) 
[info] at sbt.TestFramework$$anon$2$$anonfun$$init$$1$$anonfun$apply$8.apply(TestFramework.scala:202) 
[info] at sbt.TestFramework$$anon$2$$anonfun$$init$$1$$anonfun$apply$8.apply(TestFramework.scala:202) 
[info] at sbt.TestFramework$.sbt$TestFramework$$withContextLoader(TestFramework.scala:185) 
[info] at sbt.TestFramework$$anon$2$$anonfun$$init$$1.apply(TestFramework.scala:202) 
[info] at sbt.TestFramework$$anon$2$$anonfun$$init$$1.apply(TestFramework.scala:202) 
[info] at sbt.TestFunction.apply(TestFramework.scala:207) 
[info] at sbt.Tests$$anonfun$9.apply(Tests.scala:216) 
[info] at sbt.Tests$$anonfun$9.apply(Tests.scala:216) 
[info] at sbt.std.Transform$$anon$3$$anonfun$apply$2.apply(System.scala:44) 
[info] at sbt.std.Transform$$anon$3$$anonfun$apply$2.apply(System.scala:44) 
[info] at sbt.std.Transform$$anon$4.work(System.scala:63) 
[info] at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226) 
[info] at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226) 
[info] at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17) 
[info] at sbt.Execute.work(Execute.scala:235) 
[info] at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226) 
[info] at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226) 
[info] at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159) 
[info] at sbt.CompletionService$$anon$2.call(CompletionService.scala:28) 
[info] at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
[info] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
[info] at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
[info] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
[info] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
[info] at java.lang.Thread.run(Thread.java:745) 
[info] ---(end of nested stack traces)--- 
[info] at org.jocl.LibUtils.loadLibrary(LibUtils.java:122) 
[info] at org.jocl.CL.<clinit>(CL.java:47) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextDescription$.enumerate(CLContextDescription.scala:44) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsManager$.contextsDescriptions$lzycompute(CLContextsManager.scala:6) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsManager$.contextsDescriptions(CLContextsManager.scala:6) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsManager$.createCpuContext(CLContextsManager.scala:9) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsCache$.cpuContext$lzycompute(CLContextsCache.scala:24) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsCache$.cpuContext(CLContextsCache.scala:24) 
[info] at pl.tarsa.sortalgobox.opencl.common.CLContextsCache$.withCpuContext(CLContextsCache.scala:28) 
[info] at pl.tarsa.sortalgobox.opencl.common.CpuSort.sort(CpuSort.scala:34) 

Diese Fehler für Tests im ersten Modul nicht angezeigt/Teilprojekt abhängig von JOCL. Dh wenn ich "./activator test" mache, dann testet OpenCL von einigen (ersten getesteten) Modularbeiten und allen anderen nicht. Wenn ich "./activator" verwende, um die SBT-Konsole zu erzeugen und dann "test" mehrmals auszuführen, verhält es sich zum ersten Mal wie gewöhnlicher "./activator test", aber bei den nächsten Testläufen versagen alle OpenCL-Tests mit UnzufriedenerLinkError.

Hier ist meine Build-Datei: https://github.com/tarsa/SortAlgoBox/blob/4a041d93beb572a6dcce100780bc675d46d814f3/project/MainBuild.scala

Nach dieser Antwort: https://stackoverflow.com/a/23157190/492749 SBT einige magische Klassenladeprogramme verwendet und benennt native Bibliotheken für jede solche Klassenlader. Das Problem ist, dass JOCL die nativen Bibliotheken beim Laden einiger Java-Klassen entpackt und der resultierende Dateiname und der Speicherort immer gleich sind. Mit anderen Worten: SBT Magie spielt nicht gut mit JOCL Magie.

Was wäre Ihre Lösung?

PS: Tests funktionieren gut, wenn sie in IntelliJ IDEA ausgeführt werden - IDEA verwendet wahrscheinlich nicht die Magie des Klassenladers.

+0

Das * könnte * verwandt sein, aber ich bin mir nicht sicher: https://github.com/sbt/sbt-assembly/issues/141 – Marco13

+1

Eine Randnotiz: Für JOCL insbesondere wird es eine Abhilfe in Version 0.2.0: Wenn mit 'java -DuniqueLibraryNames = true TheApplication' begonnen wird, wird jedes Mal ein neuer Bibliotheksname generiert. Dies kann unerwünschte Nebenwirkungen haben und sollte eigentlich nur als * Workaround * betrachtet werden, bis eine richtige Lösung für das Problem der allgemeinen SBT/nativen Bibliothek gefunden wurde. – Marco13

Antwort

1

According to this answer: https://stackoverflow.com/a/23157190/492749 SBT uses some magic classloaders and renames native libraries for each such classloader. The problem is that JOCL unpacks the native libraries during loading of some Java class and the resulting filename and location is always the same. In other words: SBT's magic doesn't play well with JOCL magic.

Dies geschah nicht automatisch für mich; Ich denke, es wird nur beim Laden von SBT-Plugins verwendet. Ich musste adapt the SBT classloader:

// adapted from sbt.classpath.NativeCopyLoader 
package scalan.compilation.lms 

import java.io.File 
import java.net.{URLClassLoader, URL} 
import java.nio.file.Files 

/** 
* Loads native libraries from a temporary location in order to work around the jvm native library uniqueness restriction. 
* 
* The loader will provide native libraries listed in `explicitLibraries` and on `searchPaths` by copying them to `tempDirectory`. 
*/ 
class NativeCopyLoader(explicitLibraries: Seq[File], searchPaths: Seq[File], urls: Array[URL], parent: ClassLoader) extends URLClassLoader(urls, parent) { 
    private[this] val mapped = new collection.mutable.HashMap[String, String] 
    private[this] val tempDirectory = Files.createTempDirectory("native-library-copies").toFile 
    tempDirectory.deleteOnExit() 

    override protected def findLibrary(name: String): String = 
    synchronized { mapped.getOrElseUpdate(name, findLibrary0(name)) } 

    private[this] def findLibrary0(name: String): String = { 
    val mappedName = System.mapLibraryName(name) 
    val explicit = explicitLibraries.filter(_.getName == mappedName).toStream 
    val search = searchPaths.toStream flatMap relativeLibrary(mappedName) 
    (explicit ++ search).headOption.map(copy).orNull 
    } 
    private[this] def relativeLibrary(mappedName: String)(base: File): Seq[File] = { 
    val f = new File(base, mappedName) 
    if (f.isFile) f :: Nil else Nil 
    } 
    private[this] def copy(f: File): String = { 
    val target = new File(tempDirectory, f.getName) 
    Files.copy(f.toPath, target.toPath) 
    target.getAbsolutePath 
    } 
} 

Und dann stellen Sie sicher, es verwendet wird, wenn die Klassen geladen, die die nativen Bibliotheken laden. Dies muss jedoch möglicherweise geändert werden, um mit JOCL-Magie arbeiten zu können.

Verwandte Themen