Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
155 views
in Technique[技术] by (71.8m points)

scala - pattern matching fails on second try

I am using the following code to pattern match an instance of PrivateKey:

import java.security.interfaces.{RSAPrivateKey, RSAPublicKey}
import java.security.{PrivateKey, PublicKey} 

object ClientPrivateKey {
  def apply(privateKey: PrivateKey) = privateKey match {
    case k: RSAPrivateKey ? RSAClientPrivateKey(k)
    case k: EdDSAPrivateKey ? EDCClientPrivateKey(k)
  }
}

val pk: PrivateKey = ....
ClientPrivateKey(pk)

I am getting a weird behavior when running tests with sbt ~test. On the first run the test passes, on subsequent tries, without restarting sbt, the test fails with:

[info]   scala.MatchError: net.i2p.crypto.eddsa.EdDSAPrivateKey@e5d5feef (of class net.i2p.crypto.eddsa.EdDSAPrivateKey)
[info]   at com.advancedtelematic.libtuf.data.ClientDataType$ClientPrivateKey$.apply(ClientDataType.scala:39)
[info]   at com.advancedtelematic.tuf.keyserver.daemon.KeyGenerationOp$$anonfun$saveToVault$1.apply(KeyGeneratorLeader.scala:122)
[info]   at com.advancedtelematic.tuf.keyserver.daemon.KeyGenerationOp$$anonfun$saveToVault$1.apply(KeyGeneratorLeader.scala:121)
[info]   at scala.concurrent.Future$$anonfun$traverse$1.apply(Future.scala:576)
[info]   at scala.concurrent.Future$$anonfun$traverse$1.apply(Future.scala:575)
[info]   at scala.collection.TraversableOnce$$anonfun$foldLeft$1.apply(TraversableOnce.scala:157)
[info]   at scala.collection.TraversableOnce$$anonfun$foldLeft$1.apply(TraversableOnce.scala:157)

Which is strange, as net.i2p.crypto.eddsa.EdDSAPrivateKey matches the type of the object being matched.

What can be interfering with this pattern matching?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

One thing that comes to my mind is that your privateKey might be coming from a different classloader that the one used by default by your pattern matching code.

You can test this e.g. like that:

def apply(privateKey: PrivateKey) = privateKey match {
  case k: RSAPrivateKey ? RSAClientPrivateKey(k)
  case k: EdDSAPrivateKey ? EDCClientPrivateKey(k)
  case k if k.getClass.getName == classOf[EdDSAPrivateKey].getName =>
    val sameClasses = k.getClass == classOf[EdDSAPrivateKey]
    val sameClasses = k.getClass.getClassLoader == classOf[EdDSAPrivateKey].getClassLoader
    throw new Exception(s"Different class loaders? $sameClasses $sameClassLoaders")
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...