Skip to content
New issue

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

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

Already on GitHub? Sign in 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
Collaborator

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants