VirtusLab / scala-cli

Scala CLI is a command-line tool to interact with the Scala language. It lets you compile, run, test, and package your Scala code (and more!)
https://scala-cli.virtuslab.org
Apache License 2.0
544 stars 128 forks source link

Unable to use `scala-native-crypto` #3141

Closed scarf005 closed 4 weeks ago

scarf005 commented 4 weeks ago

Version(s) Scala CLI version: 1.5.0 Scala version (default): 3.5.0

Describe the bug unable to use https://github.com/lolgab/scala-native-crypto, a drop-in scala-native java.security.MessageDigest replacement library.

To Reproduce

//> using platform native
//> using nativeVersion 0.4.17
//> using dep "com.github.lolgab::scala-native-crypto::0.0.4"
//> using nativeLinking -lcrypto

import java.security.MessageDigest

def md5(s: String) =
  println(s.getBytes())
  println(
    MessageDigest
      .getInstance("MD5"),
  )

  println(
    MessageDigest
      .getInstance("MD5")
      .digest(s.getBytes()),
  )

@main def hello =
  println(md5("yex"))

sudo dnf install openssl-devel (or equivalent) scala-cli run repro.scala

Expected behaviour

it works in scala native.

Actual behaviour

[info] Linking (1142 ms)
[warn] 
Found 1 errors on @"M14repro$package$D3md5L16java.lang.StringuEO" :
[warn]     can't call D6digestLAb_LAb_EO on @"T32java.security.DummyMessageDigest"
[warn] 
1 errors found
[info] Checking intermediate code (quick) (64 ms)
[info] Discovered 693 classes and 3836 methods
[info] Optimizing (debug mode) (750 ms)
[info] Generating intermediate code (614 ms)
[info] Produced 12 files
[info] Compiling to native code (1834 ms)
[info] Linking with [pthread, dl]
[info] Total (4623 ms)
scala.scalanative.runtime.ByteArray@c4070ad
java.security.DummyMessageDigest@c4043fd
scala.scalanative.runtime.UndefinedBehaviorError
        at java.lang.StackTrace$.currentStackTrace$$anonfun$1(Unknown Source)
        at java.lang.StackTrace$$$Lambda$2.applyVoid(Unknown Source)
        at scala.runtime.function.JProcedure1.apply(Unknown Source)
        at scala.scalanative.unsafe.Zone$.apply(Unknown Source)
        at java.lang.StackTrace$.currentStackTrace(Unknown Source)
        at java.lang.Throwable.fillInStackTrace(Unknown Source)
        at scala.scalanative.runtime.package$.throwUndefined(Unknown Source)
        at <none>.(Unknown Source)
        at repro$package$.hello(Unknown Source)
        at hello.main(Unknown Source)
        at <none>.main(Unknown Source)
        at <none>.(Unknown Source)
        at <none>.__libc_start_main(Unknown Source)
        at <none>._start(Unknown Source)

scala-native-crypto isn't picked up.

Gedochao commented 4 weeks ago

@WojciechMazur any clue what could be causing this?

WojciechMazur commented 4 weeks ago

That's the issue with the Scala Native 0.4.x series - it contained a dummy implementation (seen in logs) that was not marked with @stub. Because of that linker assumes that it's a valid definition and includes it. The scala-native-crypto provides an alternative implementation of MessageDigest, however, there is no mechanism that could check if there are multiple definitions somewhere on the classpath. Because of that linker picks the first implementation found on the classpath. There is nothing that can fix in in the scala-cli. I'd recommended switching to Scala Native 0.5.x which has this issue fixed. Alternatively we could release the 0.4.18, however the 0.4.x series is in general no longer maintained or developed.

scarf005 commented 4 weeks ago

thanks for the detailed reply.

There is nothing that can fix in in the scala-cli. I'd recommended switching to Scala Native 0.5.x which has this issue fixed.

guess I'm stuck in a catch-22 situation; I can't use 0.5.x because cats-effect doesn't support it, and i can't use 0.4.x either because of #3141. maybe i should find another native-compatible crypto library.

Gedochao commented 4 weeks ago

Okay... seems there's nothing to fix on our side. Closing this.