Ich denke, es ist damit verbunden: Do security providers cause ClassLoader leaks in Java?. Grundsätzlich verwendet Security
Anbieter von alten Klassenladern. Dies kann in jeder Umgebung mit mehreren Klassen (wie OSGi) passieren, nicht nur in SBT.
Fix für Ihre build.sbt
(ohne Forking):
testOptions in Test += Tests.Cleanup(() =>
java.security.Security.removeProvider("BC"))
Experiment:
sbt-classloader-issue$ sbt
> test
[success] Total time: 1 s, completed Jul 6, 2017 11:43:53 PM
> test
[success] Total time: 0 s, completed Jul 6, 2017 11:43:55 PM
Erläuterung:
Wie ich aus dem Code sehen kann (veröffentlicht here):
Sie verwenden den gleichen BouncyCastleProvider
Provider jedes Mal, wenn Sie einen Test ausführen, da Ihr Security.addProvider
only first time funktioniert. Da sbt einen neuen Klassenlader für jeden "Testlauf" erstellt, aber denselben JVM verwendet - Security
ist ein JVM-Scoped-Singleton, wie er von JVM-Bootstrap geladen wurde, sodass classOf[java.security.Security].getClassLoader() == null
und sbt diese Klasse nicht erneut initialisieren/reinitialisieren können .
und Sie können leicht überprüfen, ob
classOf[org.bouncycastle.jce.spec.ECParameterSpec].getClassLoader()
res30: ClassLoader = URLClassLoader with NativeCopyLoader with RawResources
org.bouncycastle
Klassen mit benutzerdefinierten Klassenlader (von SBT) geladen werden, die jede Zeit Sie test
laufen ändert.
Also dieser Code:
val generator = KeyPairGenerator.getInstance("ECDSA", "BC")
bekommt Instanz der Klasse von alten Klassenlader (der für die erste „Test“ run verwendet wird) geladen und Sie versuchen, es aus den neuen Klassenlader mit spec zu initialisieren:
generator.initialize(ecSpec)
Das ist, warum Sie "Parameter Objekt nicht eine ECParameterSpec" Ausnahme erhalten. Die Argumentation um "net.i2p.crypto.eddsa.EdDSAPublicKey kann nicht in net.i2p.crypto.eddsa.EdDSAPublicKey umgewandelt werden" ist im Wesentlichen gleich.
Können Sie Code einfügen, der dieses Problem in Ihrer Frage reproduziert? Warum denkst du, Klassenfahrer sind das Problem? –
Ich beendete das Verfassen eines Problemberichts für sbt, um zu versuchen, dies zu debuggen, überprüfen Sie bitte https://github.com/sbt/sbt/issues/3306 Ich schrieb ein kleines Projekt, das dieses Problem reproduziert – simao