Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

ClassCastException when using --import with 0.11.3 #2749

Closed
ckipp01 opened this issue Sep 18, 2023 · 2 comments · Fixed by #2752
Closed

ClassCastException when using --import with 0.11.3 #2749

ckipp01 opened this issue Sep 18, 2023 · 2 comments · Fixed by #2752
Milestone

Comments

@ckipp01
Copy link
Contributor

ckipp01 commented Sep 18, 2023

With the recent release of 0.11.3 I noticed that a few of my plugins all started failing. The common thread of them seem to be that they are all using --import. For example you can replicate with the the mill-github-dependency-graph:

❯ mill --no-server --import ivy:io.chris-kipp::mill-github-dependency-graph::0.2.6 io.kipp.mill.github.dependency.graph.Graph/generate
[build.sc] [48/52] compile
[info] compiling 1 Scala source to /Users/ckipp/Documents/scala-workspace/bloop-config/out/mill-build/compile.dest/classes ...
[info] done compiling
[build.sc] [52/52] methodCodeHashSignatures
Exception in thread "main" java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at mill.main.client.IsolatedMillMainLoader.runMain(IsolatedMillMainLoader.java:58)
        at mill.main.client.MillClientMain.main(MillClientMain.java:64)
Caused by: java.lang.ClassCastException: class scala.collection.immutable.$colon$colon cannot be cast to class scala.Tuple2 (scala.collection.immutable.$colon$colon and scala.Tuple2 are in unnamed module of loader 'app')
        at scala.collection.Iterator$$anon$10.nextCur(Iterator.scala:594)
        at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:608)
        at scala.collection.immutable.List.prependedAll(List.scala:152)
        at scala.collection.immutable.List$.from(List.scala:684)
        at scala.collection.immutable.List$.from(List.scala:681)
        at scala.collection.IterableFactory$Delegate.from(Factory.scala:288)
        at scala.collection.immutable.Iterable$.from(Iterable.scala:35)
        at scala.collection.immutable.Iterable$.from(Iterable.scala:32)
        at scala.collection.IterableFactory$Delegate.from(Factory.scala:288)
        at scala.collection.IterableOps.flatMap(Iterable.scala:684)
        at scala.collection.IterableOps.flatMap$(Iterable.scala:684)
        at scala.collection.AbstractIterable.flatMap(Iterable.scala:933)
        at mill.resolve.Resolve.resolveNonEmptyAndHandle(Resolve.scala:230)
        at mill.resolve.Resolve.resolveNonEmptyAndHandle$(Resolve.scala:223)
        at mill.resolve.Resolve$Tasks$.resolveNonEmptyAndHandle(Resolve.scala:34)
        at mill.resolve.Resolve.$anonfun$resolve0$4(Resolve.scala:207)
        at scala.util.Either.map(Either.scala:382)
        at mill.resolve.Resolve.$anonfun$resolve0$3(Resolve.scala:206)
        at scala.collection.immutable.List.map(List.scala:246)
        at scala.collection.immutable.List.map(List.scala:79)
        at mill.resolve.Resolve.$anonfun$resolve0$2(Resolve.scala:205)
        at scala.collection.immutable.List.map(List.scala:246)
        at scala.collection.immutable.List.map(List.scala:79)
        at mill.resolve.Resolve.$anonfun$resolve0$1(Resolve.scala:204)
        at scala.util.Either.flatMap(Either.scala:352)
        at mill.resolve.Resolve.resolve0(Resolve.scala:203)
        at mill.resolve.Resolve.resolve0$(Resolve.scala:197)
        at mill.resolve.Resolve$Tasks$.resolve0(Resolve.scala:34)
        at mill.resolve.Resolve.resolve(Resolve.scala:194)
        at mill.resolve.Resolve.resolve$(Resolve.scala:189)
        at mill.resolve.Resolve$Tasks$.resolve(Resolve.scala:34)
        at mill.main.RunScript$.$anonfun$evaluateTasksNamed$1(RunScript.scala:24)
        at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
        at mill.main.RunScript$.evaluateTasksNamed(RunScript.scala:24)
        at mill.runner.MillBuildBootstrap$.evaluateWithWatches(MillBuildBootstrap.scala:397)
        at mill.runner.MillBuildBootstrap.$anonfun$processFinalTargets$3(MillBuildBootstrap.scala:307)
        at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
        at mill.runner.MillBuildBootstrap.processFinalTargets(MillBuildBootstrap.scala:307)
        at mill.runner.MillBuildBootstrap.evaluateRec(MillBuildBootstrap.scala:195)
        at mill.runner.MillBuildBootstrap.evaluate(MillBuildBootstrap.scala:47)
        at mill.runner.MillMain$.$anonfun$main0$6(MillMain.scala:213)
        at mill.runner.Watching$.watchLoop(Watching.scala:27)
        at mill.runner.MillMain$.$anonfun$main0$1(MillMain.scala:198)
        at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
        at scala.Console$.withErr(Console.scala:193)
        at mill.api.SystemStreams$.$anonfun$withStreams$2(SystemStreams.scala:62)
        at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
        at scala.Console$.withOut(Console.scala:164)
        at mill.api.SystemStreams$.$anonfun$withStreams$1(SystemStreams.scala:61)
        at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
        at scala.Console$.withIn(Console.scala:227)
        at mill.api.SystemStreams$.withStreams(SystemStreams.scala:60)
        at mill.runner.MillMain$.main0(MillMain.scala:80)
        at mill.runner.MillMain$.main(MillMain.scala:58)
        at mill.runner.MillMain.main(MillMain.scala)
        ... 6 more

You can see it happening in CI here. It is also happening with my ci-release plugins as you can see here with the same error.

Let me know if there is anything else I can provide.

@carlosedp
Copy link
Contributor

This is happening to my zio-temporal demo app as well (on 0.11.3... on .2 works fine).

❯ ./mill client.run
[build.sc] [26/52] sources.super.mill.scalalib.JavaModule.sources
Exception in thread "MillServerActionRunner" java.lang.ClassCastException: class scala.collection.immutable.$colon$colon cannot be cast to class scala.Tuple2 (scala.collection.immutable.$colon$colon and scala.Tuple2 are in unnamed module of loader 'app')
	at scala.collection.Iterator$$anon$10.nextCur(Iterator.scala:594)
	at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:608)
	at scala.collection.immutable.List.prependedAll(List.scala:152)
	at scala.collection.immutable.List$.from(List.scala:684)
	at scala.collection.immutable.List$.from(List.scala:681)
	at scala.collection.IterableFactory$Delegate.from(Factory.scala:288)
	at scala.collection.immutable.Iterable$.from(Iterable.scala:35)
	at scala.collection.immutable.Iterable$.from(Iterable.scala:32)
	at scala.collection.IterableFactory$Delegate.from(Factory.scala:288)
	at scala.collection.IterableOps.flatMap(Iterable.scala:684)
	at scala.collection.IterableOps.flatMap$(Iterable.scala:684)
	at scala.collection.AbstractIterable.flatMap(Iterable.scala:933)
	at mill.resolve.Resolve.resolveNonEmptyAndHandle(Resolve.scala:230)
	at mill.resolve.Resolve.resolveNonEmptyAndHandle$(Resolve.scala:223)
	at mill.resolve.Resolve$Tasks$.resolveNonEmptyAndHandle(Resolve.scala:34)
	at mill.resolve.Resolve.$anonfun$resolve0$4(Resolve.scala:207)
	at scala.util.Either.map(Either.scala:382)
	at mill.resolve.Resolve.$anonfun$resolve0$3(Resolve.scala:206)
	at scala.collection.immutable.List.map(List.scala:246)
	at scala.collection.immutable.List.map(List.scala:79)
	at mill.resolve.Resolve.$anonfun$resolve0$2(Resolve.scala:205)
	at scala.collection.immutable.List.map(List.scala:246)
	at scala.collection.immutable.List.map(List.scala:79)
	at mill.resolve.Resolve.$anonfun$resolve0$1(Resolve.scala:204)
	at scala.util.Either.flatMap(Either.scala:352)
	at mill.resolve.Resolve.resolve0(Resolve.scala:203)
	at mill.resolve.Resolve.resolve0$(Resolve.scala:197)
	at mill.resolve.Resolve$Tasks$.resolve0(Resolve.scala:34)
	at mill.resolve.Resolve.resolve(Resolve.scala:194)
	at mill.resolve.Resolve.resolve$(Resolve.scala:189)
	at mill.resolve.Resolve$Tasks$.resolve(Resolve.scala:34)
	at mill.main.RunScript$.$anonfun$evaluateTasksNamed$1(RunScript.scala:24)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
	at mill.main.RunScript$.evaluateTasksNamed(RunScript.scala:24)
	at mill.runner.MillBuildBootstrap$.evaluateWithWatches(MillBuildBootstrap.scala:397)
	at mill.runner.MillBuildBootstrap.$anonfun$processFinalTargets$3(MillBuildBootstrap.scala:307)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
	at mill.runner.MillBuildBootstrap.processFinalTargets(MillBuildBootstrap.scala:307)
	at mill.runner.MillBuildBootstrap.evaluateRec(MillBuildBootstrap.scala:195)
	at mill.runner.MillBuildBootstrap.evaluate(MillBuildBootstrap.scala:47)
	at mill.runner.MillMain$.$anonfun$main0$6(MillMain.scala:213)
	at mill.runner.Watching$.watchLoop(Watching.scala:27)
	at mill.runner.MillMain$.$anonfun$main0$1(MillMain.scala:198)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
	at scala.Console$.withErr(Console.scala:193)
	at mill.api.SystemStreams$.$anonfun$withStreams$2(SystemStreams.scala:62)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
	at scala.Console$.withOut(Console.scala:164)
	at mill.api.SystemStreams$.$anonfun$withStreams$1(SystemStreams.scala:61)
	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
	at scala.Console$.withIn(Console.scala:227)
	at mill.api.SystemStreams$.withStreams(SystemStreams.scala:60)
	at mill.runner.MillMain$.main0(MillMain.scala:80)
	at mill.runner.MillServerMain$.main0(MillServerMain.scala:83)
	at mill.runner.MillServerMain$.main0(MillServerMain.scala:35)
	at mill.runner.Server.$anonfun$handleRun$1(MillServerMain.scala:186)
	at java.base/java.lang.Thread.run(Thread.java:833)

I use some plugins as can be seen at https://github.com/carlosedp/zio-temporal-hello/blob/main/build.sc

lihaoyi added a commit that referenced this issue Sep 18, 2023
fixes #2749

The basic problem is that the signature of `Discover.apply()` changed,
but it only changed in the argument's generic type parameters, so it was
nominally the same type after erasure, and accepted the `Map[Class[_],
Seq]` even though it was expecting a `Map[Class[_], (Seq, Seq)]`, but
later on in the code it would blow up with a `ClassCastException`

This causes problems with Mill plugins containing external modules,
which have their own `Discover[T]` macro pre-expanded and would not get
re-compiled with the new 0.11.3 version of Mill.

This PR works around the problem by adding a forwarder
`Discover.apply(value: Map[Class, Seq])` that does the right thing and
expands the `Seq` into a `(Seq, Seq)`, while adding a dummy paramter to
`case class Discover` to avoid conflicts. A similar forwarder
`Discover.<init>(value: Map[Class, Seq])` is needed to preserve binary
compatibility (I think?)

Tested manually via `./mill -i dev.run example/basic/1-simple-scala
--import ivy:io.chris-kipp::mill-github-dependency-graph::0.2.6
io.kipp.mill.github.dependency.graph.Graph/generate`, which fails before
this PR and passes after

---------

Co-authored-by: Chris Kipp <ckipp@pm.me>
Co-authored-by: Tobias Roeser <le.petit.fou@web.de>
@lefou lefou added this to the 0.11.4 milestone Sep 19, 2023
@lihaoyi
Copy link
Member

lihaoyi commented Sep 19, 2023

Fixed in 0.11.4

nightscape added a commit to nightscape/mill-ci-release that referenced this issue Sep 28, 2023
This should fix the ClassCastException during release:
com-lihaoyi/mill#2749
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants