У меня есть проект, который использует библиотеку JOCL (http://www.jocl.org/) и имеет несколько модулей. Когда я бегу «тест ./activator» из командной строки или выполнить команду „тест“ в SBT консоли я получаю сообщение об ошибке, как следующее:«UnsatisfiedLinkError: родная библиотека, уже загруженная в другой загрузчик классов» в проекте с несколькими модулями
[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)
Эти ошибки не появляются для испытаний в первом модуле/подпроект в зависимости от JOCL. Т.е. когда я делаю «./activator test», тогда тесты OpenCL из некоторого (первого протестированного) модуля работают, а все остальные - нет. Когда я делаю «./activator», чтобы запустить консоль SBT, а затем запускать «тест» несколько раз, а затем он ведет себя как обычный «./activator test», но для следующего теста все тесты OpenCL не работают с UnsatisfiedLinkError.
Вот мой файл сборка: https://github.com/tarsa/SortAlgoBox/blob/4a041d93beb572a6dcce100780bc675d46d814f3/project/MainBuild.scala
Согласно этому ответу: https://stackoverflow.com/a/23157190/492749 SBT использует магические загрузчик классов и переименовывает собственные библиотеки для каждых такого загрузчика классов. Проблема в том, что JOCL распаковывает собственные библиотеки во время загрузки какого-либо Java-класса, и результирующее имя файла и местоположение всегда одно и то же. Другими словами: магию SBT не хорошо сочетается с магией JOCL.
Какое у вас решение?
PS: тесты хорошо работают при исполнении IntelliJ IDEA - возможно, IDEA не использует магию загрузчика классов.
Это * может * быть связано, но я не уверен: https://github.com/sbt/sbt-assembly/issues/141 – Marco13
Примечание: для JOCL, в частности, будет обходной путь в версия 0.2.0: при запуске с 'java -DuniqueLibraryNames = true TheApplication' каждый раз будет генерировать новое имя библиотеки. Это может иметь нежелательные побочные эффекты и действительно должно рассматриваться только как * обходное решение *, пока не будет найдено правильное решение для общей проблемы с SBT/native library. – Marco13