You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Given a CrossScalaNativeModule, multiple classloaders are used,
Since we cache the output nativeConfig, it can happen that a nativeConfig generated
with a Classloader is used when linking with another classloader.
This can lead to ClassCastException since objects from different classloader can't be shared.
app[aarch64-macos-none].nativeLink java.lang.ClassCastException: class scala.scalanative.build.Config$Impl cannot be cast to class scala.scalanative.build.Config (scala.scalanative.build.Config$Impl is in unnamed module of loader mill.api.ClassLoader$$anon$1 @278c6ad9; scala.scalanative.build.Config is in unnamed module of loader mill.api.ClassLoader$$anon$1 @3d4e7cb1)
mill.scalanativelib.worker.ScalaNativeWorkerImpl.nativeLink(ScalaNativeWorkerImpl.scala:105)
mill.scalanativelib.ScalaNativeModule.$anonfun$nativeLink$4(ScalaNativeModule.scala:286)
mill.scalanativelib.ScalaNativeModule$ScalaNativeBridge.$anonfun$apply$1(ScalaNativeModule.scala:159)
mill.api.CachedFactory.withValue(CachedFactory.scala:39)
mill.scalanativelib.ScalaNativeModule$ScalaNativeBridge.apply(ScalaNativeModule.scala:158)
mill.scalanativelib.ScalaNativeModule.$anonfun$nativeLink$3(ScalaNativeModule.scala:287)
app[aarch64-windows-gnu].nativeLink scala.scalanative.build.BuildException: Failed to compile /Users/lorenzo/scala/scala-native-cross/out/app/aarch64-windows-gnu/nativeWorkdir.dest/native/dependencies/nativelib_native0.5_3-0.5.6-0/scala-native/nativeThreadTLS.c
app[x86_64-linux-gnu].nativeLink java.lang.ClassCastException: class scala.scalanative.build.Config$Impl cannot be cast to class scala.scalanative.build.Config (scala.scalanative.build.Config$Impl is in unnamed module of loader mill.api.ClassLoader$$anon$1 @2bd047bc; scala.scalanative.build.Config is in unnamed module of loader mill.api.ClassLoader$$anon$1 @709c8fd6)
mill.scalanativelib.worker.ScalaNativeWorkerImpl.nativeLink(ScalaNativeWorkerImpl.scala:105)
mill.scalanativelib.ScalaNativeModule.$anonfun$nativeLink$4(ScalaNativeModule.scala:286)
mill.scalanativelib.ScalaNativeModule$ScalaNativeBridge.$anonfun$apply$1(ScalaNativeModule.scala:159)
mill.api.CachedFactory.withValue(CachedFactory.scala:39)
mill.scalanativelib.ScalaNativeModule$ScalaNativeBridge.apply(ScalaNativeModule.scala:158)
mill.scalanativelib.ScalaNativeModule.$anonfun$nativeLink$3(ScalaNativeModule.scala:287)
Possible solutions
Add the module as the cache key, to make a module always use the same ClassLoader.
Workaround
Pass -j 1 so a single Classloader is used.
The text was updated successfully, but these errors were encountered:
This issue is rather in the design space. The NativeConfig is shared API and its runtime class is also shared by all classloaders that are supposed to load it. Yet, it's (currently) not designed to be shared, as it seems to depend on some non-shared classes.
I think your proposed solutions are rather workarounds since they just try to limit the scope of the config object to the originating classloader. Any proper solution need to somehow brigde the actual configuration from one classloader to the other. Does the actual config implementation already support some kind of serialization or file persistence? If yes, saving and loading a config file might be the robustest solution, which probably can happen on demand. If not we could either use some JSON serialization or fall back to use reflection to copy the classloader-specific config holder class over. There is also the option to expose all config values in the NativeConfig class and re-read it over that API. But that depends on the kind of config objects, which I'm not familiar with.
Given a
Cross
ScalaNativeModule
, multiple classloaders are used,Since we cache the output
nativeConfig
, it can happen that anativeConfig
generatedwith a Classloader is used when linking with another classloader.
This can lead to
ClassCastException
since objects from different classloader can't be shared.Repro
Output
Possible solutions
Workaround
Pass
-j 1
so a single Classloader is used.The text was updated successfully, but these errors were encountered: