Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Regression in v1.19.0: AssertionError with module splitting on and optimizer off. #5159

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

Closed
guillaug opened this issue Apr 28, 2025 · 6 comments
Assignees
Labels
bug Confirmed bug. Needs to be fixed.
Milestone

Comments

@guillaug
Copy link

Scala version : 3.7.0-RC4
ScalaJS version : 1.19.0

Error happens with config ModuleSplitStyle.SmallModulesFor(...) or ModuleSplitStyle.ModuleSplitStyle.SmallestModules.
Does not happen with config ModuleSplitStyle.FewestModules

Error is thrown when running fastLinkJS but not fullLinkJS.

[info] Fast optimizing [...]
[error] java.util.concurrent.ExecutionException: Boxed Error
[error]         at scala.concurrent.impl.Promise$.resolver(Promise.scala:97)
[error]         at scala.concurrent.impl.Promise$.scala$concurrent$impl$Promise$$resolveTry(Promise.scala:89)
[error]         at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:294)
[error]         at scala.concurrent.Promise.complete(Promise.scala:53)
[error]         at scala.concurrent.Promise.complete$(Promise.scala:52)
[error]         at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:197)
[error]         at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:42)
[error]         at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:74)
[error]         at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)
[error]         at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
[error]         at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
[error]         at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
[error]         at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
[error]         at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
[error] Caused by: java.lang.AssertionError: assertion failed: java.util.function.Supplier.$$Lambda$ab10cd11e4c84f9dc7a29a581dc9938e4ecc6132 was not put in a module but has definitions
[error]         at scala.Predef$.assert(Predef.scala:223)
[error]         at org.scalajs.linker.frontend.modulesplitter.ModuleSplitter.$anonfun$assembleModules$2(ModuleSplitter.scala:76)
[error]         at scala.collection.immutable.List.foreach(List.scala:431)
[error]         at org.scalajs.linker.frontend.modulesplitter.ModuleSplitter.assembleModules(ModuleSplitter.scala:72)
[error]         at org.scalajs.linker.frontend.modulesplitter.ModuleSplitter.$anonfun$split$4(ModuleSplitter.scala:56)
[error]         at org.scalajs.logging.Logger.time(Logger.scala:42)
[error]         at org.scalajs.logging.Logger.time$(Logger.scala:40)
[error]         at org.scalajs.sbtplugin.Loggers$SbtLoggerWrapper.time(Loggers.scala:19)
[error]         at org.scalajs.linker.frontend.modulesplitter.ModuleSplitter.split(ModuleSplitter.scala:56)
[error]         at org.scalajs.linker.frontend.LinkerFrontendImpl.$anonfun$link$10(LinkerFrontendImpl.scala:87)
[error]         at org.scalajs.logging.Logger.time(Logger.scala:42)
[error]         at org.scalajs.logging.Logger.time$(Logger.scala:40)
[error]         at org.scalajs.sbtplugin.Loggers$SbtLoggerWrapper.time(Loggers.scala:19)
[error]         at org.scalajs.linker.frontend.LinkerFrontendImpl.$anonfun$link$9(LinkerFrontendImpl.scala:87)
[error]         at scala.util.Success.$anonfun$map$1(Try.scala:255)
[error]         at scala.util.Success.map(Try.scala:213)
[error]         at scala.concurrent.Future.$anonfun$map$1(Future.scala:292)
[error]         at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:42)
[error]         at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:74)
[error]         at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)
[error]         at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
[error]         at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
[error]         at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
[error]         at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
[error]         at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
[error] (ui / Compile / fastLinkJS) java.util.concurrent.ExecutionException: Boxed Error
@sjrd
Copy link
Member

sjrd commented Apr 28, 2025

Thanks for the report. Could you provide a full reproduction, with the code that triggers this issue?

@sjrd
Copy link
Member

sjrd commented Apr 28, 2025

@gzm0 I guess we're missing a call to addInstanceDependency(lambdaClassInfo) here:

lookupOrSynthesizeClass(className, SyntheticClassKind.Lambda(descriptor)) { lambdaClassInfo =>
lambdaClassInfo.instantiated()
lambdaClassInfo.callMethodStatically(MemberNamespace.Constructor, ctorName)
}

which would mimic what we do for "normal" class instantiations here:
if ((flags & ReachabilityInfoInClass.FlagInstantiated) != 0) {
clazz.instantiated()
addInstanceDependency(clazz)
}

I wonder how this was not caught at all by our CI?

@gzm0
Copy link
Contributor

gzm0 commented Apr 28, 2025

I wonder how this was not caught at all by our CI?

I'm not sure we test module splitting w/o optimizer (IIUC we can only get to this w/o optimizer, otherwise the module splitter uses the post optimizer analysis, which will see the synthesized versions.

@sjrd
Copy link
Member

sjrd commented Apr 28, 2025

Huh, yes, that's it. Module splitting + withOptimizer(false) causes the crash. And indeed, we don't test that combination.

So @guillaug: as workaround, re-enable the optimizer in fastLinkJS. (Slightly off-topic: out of curiosity, what's the reason that you deactivate it?)

@sjrd sjrd self-assigned this Apr 28, 2025
@sjrd sjrd added the bug Confirmed bug. Needs to be fixed. label Apr 28, 2025
@sjrd sjrd added this to the v1.19.1 milestone Apr 28, 2025
@sjrd sjrd changed the title Boxed Error when running fastLinkJS with scala 3.7.0-RC4 and ScalaJS 1.19.0 Regression in v1.19.0: AssertionError with module splitting on and optimizer off. Apr 28, 2025
@sjrd sjrd closed this as completed in 1e6540a Apr 28, 2025
sjrd added a commit that referenced this issue Apr 28, 2025
Fix #5159: Register static module dependency on used lambda classes.
@guillaug
Copy link
Author

Ok thanks for the fix !
I confirm that it now works with the optimizer enabled.

I used withOptimizer(false) because I am using ScalaJS + ViteJS which has its own optimizer and I wanted the dev server to reload as fast as possible. I did not measure if it helps or not though.
At some point I also had issue with some of the source maps not working for all ScalaJS source files, so I might have tried to enable source map with withSourceMap(true) and also removed the optimizer.

@sjrd
Copy link
Member

sjrd commented Apr 29, 2025

I used withOptimizer(false) because I am using ScalaJS + ViteJS which has its own optimizer and I wanted the dev server to reload as fast as possible. I did not measure if it helps or not though.

Vite has a JS minifier. It doesn't have Scala.js optimizer that uses types to perform advanced optimizations. If you did not measure, I suspect disabling the optimizer made the setup slower. Without optimizer, Scala.js generates a lot more JS code, which means that much more to reload in the browser. The Scala.js optimizer is incremental and so it is extremely fast in the development cycle. Usually the fact that it produces smaller and faster code improves dev iteration time.

At some point I also had issue with some of the source maps not working for all ScalaJS source files, so I might have tried to enable source map with withSourceMap(true) and also removed the optimizer.

Source maps are enabled by default, though I've heard it's tricky to get them to work well when additional tools work after Scala.js (such as Vite). Here as well, the optimizer shouldn't make a difference between "they work" and "they don't work". It may deteriorate the quality of the debugging experience somewhat, though. That's usually a good reason to temporarily disable the optimizer as you're debugging something.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Confirmed bug. Needs to be fixed.
Projects
None yet
Development

No branches or pull requests

3 participants