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

CompletionException in BSP server for buildTarget/jvmRunEnvironment request #2643

Closed
lefou opened this issue Jun 29, 2023 · 22 comments · Fixed by #2692
Closed

CompletionException in BSP server for buildTarget/jvmRunEnvironment request #2643

lefou opened this issue Jun 29, 2023 · 22 comments · Fixed by #2692
Milestone

Comments

@lefou
Copy link
Member

lefou commented Jun 29, 2023

@tgodzik wrote:

I checked with 0.11.1 and the same exact thing seems to be happening:

[Trace - 04:37:26 PM] Received response 'buildTarget/jvmRunEnvironment - (16)' in 364ms
Result: null
Error: {
  "code": -32603,
  "message": "Internal error.",
  "data": "java.util.concurrent.CompletionException: java.lang.Exception: Failure during task evaluation: MillBsp.compile Compilation failed\n\tat java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:332)\n\tat java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:347)\n\tat java.base/java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:708)\n\tat java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)\n\tat java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162)\n\tat mill.bsp.worker.MillBuildServer.$anonfun$completable$1(MillBuildServer.scala:670)\n\tat mill.bsp.worker.MillBuildServer.$anonfun$completable$1$adapted(MillBuildServer.scala:658)\n\tat scala.concurrent.impl.Promise$Transformation.run(Promise.scala:484)\n\tat java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)\n\tat java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)\n\tat java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)\n\tat java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)\n\tat java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)\n\tat java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)\nCaused by: java.lang.Exception: Failure during task evaluation: MillBsp.compile Compilation failed\n\tat mill.eval.Evaluator.$anonfun$evalOrThrow$default$1$1(Evaluator.scala:41)\n\tat mill.eval.EvaluatorImpl$EvalOrThrow.apply(EvaluatorImpl.scala:66)\n\tat mill.bsp.worker.MillBuildServer.$anonfun$completableTasks$1(MillBuildServer.scala:627)\n\tat mill.bsp.worker.MillBuildServer.$anonfun$completable$1(MillBuildServer.scala:661)\n\t... 8 more\n"
}

Originally posted by @tgodzik in #2499 (comment)

@lefou
Copy link
Member Author

lefou commented Jun 29, 2023

Reformated stack trace

java.util.concurrent.CompletionException: java.lang.Exception: Failure during task evaluation: MillBsp.compile Compilation failed
    at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:332)
    at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:347)
    at java.base/java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:708)
    at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
    at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162)
    at mill.bsp.worker.MillBuildServer.$anonfun$completable$1(MillBuildServer.scala:670)
    at mill.bsp.worker.MillBuildServer.$anonfun$completable$1$adapted(MillBuildServer.scala:658)
    at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:484)
    at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
    at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
Caused by: java.lang.Exception: Failure during task evaluation: MillBsp.compile Compilation failed
    at mill.eval.Evaluator.$anonfun$evalOrThrow$default$1$1(Evaluator.scala:41)
    at mill.eval.EvaluatorImpl$EvalOrThrow.apply(EvaluatorImpl.scala:66)
    at mill.bsp.worker.MillBuildServer.$anonfun$completableTasks$1(MillBuildServer.scala:627)
    at mill.bsp.worker.MillBuildServer.$anonfun$completable$1(MillBuildServer.scala:661)\n\t... 8 more

@carlosedp
Copy link
Contributor

I'm debugging some stuck errors in Metals while using mill-bsp and added some logs and a capture to scalameta/metals#4652.

I also see this CompletionException error in it.

@lefou
Copy link
Member Author

lefou commented Jul 3, 2023

There is another stack trace reported by Damian, https://matrix.to/#/!zXvttAKLPnvdnmiYsY:matrix.am/$124RiHjSmCeBGxv7U4GCApafH7L5-Q9FGA91kV92ib0?via=matrix.am&via=gitter.im&via=matrix.org

2023.07.03 09:35:38 INFO  BSP server: Jul 03, 2023 9:35:38 AM org.eclipse.lsp4j.jsonrpc.RemoteEndpoint fallbackResponseError
2023.07.03 09:35:38 INFO  BSP server: SEVERE: Internal error: java.nio.file.NoSuchFileException: /Users/damian/code/repos/github/DamianReeves/morphir-scala/out/generateScriptSources.super/mill/runner/MillBuildRootModule/generateScriptSources.dest
2023.07.03 09:35:38 INFO  BSP server: java.util.concurrent.CompletionException: java.nio.file.NoSuchFileException: /Users/damian/code/repos/github/DamianReeves/morphir-scala/out/generateScriptSources.super/mill/runner/MillBuildRootModule/generateScriptSources.dest
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:332)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:347)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:708)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2194)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.bsp.worker.MillBuildServer.$anonfun$completable$1(MillBuildServer.scala:670)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.bsp.worker.MillBuildServer.$anonfun$completable$1$adapted(MillBuildServer.scala:658)
2023.07.03 09:35:38 INFO  BSP server: 	at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:484)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1423)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1311)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1840)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1806)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
2023.07.03 09:35:38 INFO  BSP server: Caused by: java.nio.file.NoSuchFileException: /Users/damian/code/repos/github/DamianReeves/morphir-scala/out/generateScriptSources.super/mill/runner/MillBuildRootModule/generateScriptSources.dest
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/sun.nio.fs.UnixFileSystemProvider.implDelete(UnixFileSystemProvider.java:248)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:105)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.nio.file.Files.delete(Files.java:1152)
2023.07.03 09:35:38 INFO  BSP server: 	at os.remove$all$.apply(FileOps.scala:331)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.eval.GroupEvaluator.evaluateGroupCached(GroupEvaluator.scala:120)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.eval.GroupEvaluator.evaluateGroupCached$(GroupEvaluator.scala:35)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.eval.EvaluatorImpl.evaluateGroupCached(EvaluatorImpl.scala:17)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.eval.EvaluatorCore.$anonfun$evaluate0$2(EvaluatorCore.scala:116)
2023.07.03 09:35:38 INFO  BSP server: 	at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:467)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.eval.ExecutionContexts$RunNow$.execute(ExecutionContexts.scala:13)
2023.07.03 09:35:38 INFO  BSP server: 	at scala.concurrent.impl.Promise$Transformation.submitWithValue(Promise.scala:429)
2023.07.03 09:35:38 INFO  BSP server: 	at scala.concurrent.impl.Promise$DefaultPromise.submitWithValue(Promise.scala:338)
2023.07.03 09:35:38 INFO  BSP server: 	at scala.concurrent.impl.Promise$DefaultPromise.dispatchOrAddCallbacks(Promise.scala:312)
2023.07.03 09:35:38 INFO  BSP server: 	at scala.concurrent.impl.Promise$DefaultPromise.map(Promise.scala:182)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.eval.EvaluatorCore.$anonfun$evaluate0$1(EvaluatorCore.scala:92)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.eval.EvaluatorCore.$anonfun$evaluate0$1$adapted(EvaluatorCore.scala:90)
2023.07.03 09:35:38 INFO  BSP server: 	at scala.collection.immutable.VectorStatics$.foreachRec(Vector.scala:2122)
2023.07.03 09:35:38 INFO  BSP server: 	at scala.collection.immutable.VectorStatics$.foreachRec(Vector.scala:2128)
2023.07.03 09:35:38 INFO  BSP server: 	at scala.collection.immutable.Vector.foreach(Vector.scala:2128)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.eval.EvaluatorCore.evaluate0(EvaluatorCore.scala:90)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.eval.EvaluatorCore.$anonfun$evaluate$1(EvaluatorCore.scala:43)
2023.07.03 09:35:38 INFO  BSP server: 	at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.eval.EvaluatorCore.evaluate(EvaluatorCore.scala:34)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.eval.EvaluatorCore.evaluate$(EvaluatorCore.scala:26)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.eval.EvaluatorImpl.evaluate(EvaluatorImpl.scala:17)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.eval.EvaluatorImpl$EvalOrThrow.apply(EvaluatorImpl.scala:64)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.bsp.worker.MillBuildServer.$anonfun$completableTasks$1(MillBuildServer.scala:627)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.bsp.worker.MillBuildServer.$anonfun$completable$1(MillBuildServer.scala:661)
2023.07.03 09:35:38 INFO  BSP server: 	... 8 more
2023.07.03 09:35:38 INFO  BSP server: 
2023.07.03 09:35:38 INFO  mill-bsp should support `buildTarget/jvmRunEnvironment`, but it fails.
org.eclipse.lsp4j.jsonrpc.ResponseErrorException: Internal error.
	at org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.handleResponse(RemoteEndpoint.java:209)
	at org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.consume(RemoteEndpoint.java:193)
	at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.handleMessage(StreamMessageProducer.java:194)
	at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.listen(StreamMessageProducer.java:94)
	at org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor.run(ConcurrentMessageProcessor.java:113)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:577)
	at java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.lang.Thread.run(Thread.java:1589)

2023.07.03 09:35:38 INFO  BSP server: Jul 03, 2023 9:35:39 AM org.eclipse.lsp4j.jsonrpc.RemoteEndpoint fallbackResponseError
2023.07.03 09:35:38 INFO  BSP server: SEVERE: Internal error: java.lang.ClassNotFoundException: munit.Framework
2023.07.03 09:35:38 INFO  BSP server: java.util.concurrent.CompletionException: java.lang.ClassNotFoundException: munit.Framework
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:332)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:347)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:708)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2194)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.bsp.worker.MillBuildServer.$anonfun$completable$1(MillBuildServer.scala:670)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.bsp.worker.MillBuildServer.$anonfun$completable$1$adapted(MillBuildServer.scala:658)
2023.07.03 09:35:38 INFO  BSP server: 	at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:484)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1423)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1311)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1840)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1806)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
2023.07.03 09:35:39 INFO  Failed to run request with params ScalaTestClassesResult
org.eclipse.lsp4j.jsonrpc.ResponseErrorException: Internal error.
	at org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.handleResponse(RemoteEndpoint.java:209)
	at org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.consume(RemoteEndpoint.java:193)
	at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.handleMessage(StreamMessageProducer.java:194)
	at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.listen(StreamMessageProducer.java:94)
	at org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor.run(ConcurrentMessageProcessor.java:113)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:577)
	at java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.lang.Thread.run(Thread.java:1589)

2023.07.03 09:35:38 INFO  BSP server: Caused by: java.lang.ClassNotFoundException: munit.Framework
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.api.ClassLoader$$anon$1.findClass(ClassLoader.scala:35)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
2023.07.03 09:35:38 INFO  BSP server: 	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.testrunner.Framework$.framework(Framework.scala:9)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.bsp.worker.MillScalaBuildServer.$anonfun$buildTargetScalaTestClasses$9(MillScalaBuildServer.scala:113)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.util.Jvm$.inprocess(Jvm.scala:254)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.bsp.worker.MillScalaBuildServer.$anonfun$buildTargetScalaTestClasses$7(MillScalaBuildServer.scala:121)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.bsp.worker.MillBuildServer.$anonfun$completableTasks$3(MillBuildServer.scala:628)
2023.07.03 09:35:38 INFO  BSP server: 	at scala.collection.immutable.Vector2.map(Vector.scala:2152)
2023.07.03 09:35:38 INFO  BSP server: 	at scala.collection.immutable.Vector2.map(Vector.scala:441)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.bsp.worker.MillBuildServer.$anonfun$completableTasks$1(MillBuildServer.scala:628)
2023.07.03 09:35:38 INFO  BSP server: 	at mill.bsp.worker.MillBuildServer.$anonfun$completable$1(MillBuildServer.scala:661)
2023.07.03 09:35:38 INFO  BSP server: 	... 8 more
2023.07.03 09:35:38 INFO  BSP server: 

As I spotted this line:

Caused by: java.nio.file.NoSuchFileException: /Users/damian/code/repos/github/DamianReeves/morphir-scala/out/generateScriptSources.super/mill/runner/MillBuildRootModule/generateScriptSources.dest

I think it might be related to this comment: #2629 (comment)

I have some suspicion, since I currently try to adapt GenIdea to the new bootstrap process. It's unvalidated, but maybe we should check it. It could be, we sometimes use the wrong evaluator when evaluating tasks. E.g. in BSP, we search for all root modules and transitively collect other modules, then we only keep them for later resolution of sources, resources and classpaths. But depending on the root module, we need to use different evaluators (evaluator configs, e.g. root directory, classpath, etc.). I'm not sure this is always the case.

@DamianReeves
Copy link

Has anyone else made any progress on this issue. This has become a huge problem for my team and I'm at the point of thinking of switching our rather large Mill build back to sbt so teammates can get working IDEs/ VSCode..

@lefou
Copy link
Member Author

lefou commented Aug 2, 2023

@lihaoyi Is there an easy API to find to which project (main or meta-build) a module belongs, when I have the module at hand? I think there is not, but I also think we need it to make better choices in the evaluator about the T.dest folder of a target.

From looking at the stacktraces, it looks like we try to evaluate a task that belongs to the meta-build in the context of the main build, resulting in using a cache location that does not exists.

 This is the path I think it should use instead:
-.../out/generateScriptSources.super/mill/runner/MillBuildRootModule/generateScriptSources.dest
+.../out/mill-build/generateScriptSources.super/mill/runner/MillBuildRootModule/generateScriptSources.dest

@lihaoyi
Copy link
Member

lihaoyi commented Aug 2, 2023

I don't think there's a way to check what project a module depends on. In theory, each set of modules should be in a totally different classloader and one depth in MillBuildBootstrap resulting in an evaluator with one root module folder

Yeah it definitely sounds like some of the meta build modules are being evaluated using the wrong evaluator. And this seems to happen only when using mill-bsp. IIRC we cache the evaluator in some parts of the mill-bsp codebase; could it be that cache is being kept around too long when it should instead be invalidated?

@lefou
Copy link
Member Author

lefou commented Aug 2, 2023

Has anyone else made any progress on this issue. This has become a huge problem for my team and I'm at the point of thinking of switching our rather large Mill build back to sbt so teammates can get working IDEs/ VSCode..

@DamianReeves I understand your frustration. I already posted my idea of the issue. The envisioned fix isn't trivial though. Of course, anybody is free to work on whatever they want and extra pressure isn't much rewarding.

Before switching to a completely different build tool, which probably comes with it's own issues, you should consider just downgrading to Mill 0.10.12. BSP support might not be as good as it could be in Mill 0.11, but if the latter is broken for you, it might do. You could also give IntelliJ IDEA a try, which works very well for me and also others, also in the free Community Edition. Donating some developer time towards a fix might be another option.

@lefou
Copy link
Member Author

lefou commented Aug 2, 2023

I don't think there's a way to check what project a module depends on. In theory, each set of modules should be in a totally different classloader and one depth in MillBuildBootstrap resulting in an evaluator with one root module folder

Yeah it definitely sounds like some of the meta build modules are being evaluated using the wrong evaluator. And this seems to happen only when using mill-bsp. IIRC we cache the evaluator in some parts of the mill-bsp codebase; could it be that cache is being kept around too long when it should instead be invalidated?

I think it's rather the fact that we collect all modules, including the ones of the meta-build, when building up the BSP state (we do this to represent all modules, also the meta-build in the IDE). While doing so, we drop the extra information of the project root folder, which would be needed to calculate the correct destination folder (EvaluatorPaths.resolveDestPaths takes a workspacePath).

@tgodzik
Copy link

tgodzik commented Aug 2, 2023

You could also give IntelliJ IDEA a try, which works very well for me and also others, also in the free Community Edition.

I think Intellij doesn't use some specific endpoints that we do, which is why it's working better in this particular case.

@lefou
Copy link
Member Author

lefou commented Aug 2, 2023

You could also give IntelliJ IDEA a try, which works very well for me and also others, also in the free Community Edition.

I think Intellij doesn't use some specific endpoints that we do, which is why it's working better in this particular case.

Oh, I just realized that it was ambiguous, as you can use IDEA as BSP client, or by generating the config with mill.scalalib.GenIdea/idea. I for myself use the latter.

@lefou
Copy link
Member Author

lefou commented Aug 2, 2023

@lihaoyi It would be nice if we could encode the meta-build-ness in something like the foreignSegments or if we could reuse the foreignSegments, as it is probably impossible to have a foreign module and a meta-build module in the same location for the same project. This would also fix the "empty segments" issue, e.g. when rendering the name of a meta-module.

@lihaoyi
Copy link
Member

lihaoyi commented Aug 2, 2023

It's definitely possible. But if the problem is mill-bsp mixing the modules together and losing the distinction between stages, maybe we should just keep the information in mill-bsp instead in some dictionary or something? Since the vast majority of Mill code doesn't need to know about this as far as I can tell, putting it on the Module object itself may be exposing it unnecessarily broadly

@lefou
Copy link
Member Author

lefou commented Aug 2, 2023

It's definitely possible. But if the problem is mill-bsp mixing the modules together and losing the distinction between stages, maybe we should just keep the information in mill-bsp instead in some dictionary or something? Since the vast majority of Mill code doesn't need to know about this as far as I can tell, putting it on the Module object itself may be exposing it unnecessarily broadly

Now, we actually need those info to have a proper unique module name. We also need it in GenIdea. We could share it between GenIdea and BSP, but time has shown that information directly in the core has better maintenance than IDE integration. And good IDE integration is nowadays a must. We probably also need this info later, when we try to make meta-build runnable/inspectable from the CLI.

@DamianReeves
Copy link

@DamianReeves I understand your frustration. I already posted my idea of the issue. The envisioned fix isn't trivial though. Of course, anybody is free to work on whatever they want and extra pressure isn't much rewarding.

Sorry I wasn't meaning to add pressure to you, and more communicating the pressure I am experiencing.
I would really love to try and debug/offer a fix to this. Maybe with some guidance I can do so. We happen to be seeing other BSP errors which I'd love to debug and try and target where we are experiencing it. I just don't have experience debugging/working with BSP.

Sorry again. I was intending to raise urgency (i.e. this is important not a nice to have), not pressure.

@DamianReeves
Copy link

Oh, I just realized that it was ambiguous, as you can use IDEA as BSP client, or by generating the config with mill.scalalib.GenIdea/idea. I for myself use the latter.

We've seen some issues here as well, or my teammate has. I am able to work, but others seem to have issues.

@DamianReeves
Copy link

Given this discussion, is a workaround for me to stop using meta-build?

@lefou
Copy link
Member Author

lefou commented Aug 2, 2023

Given this discussion, is a workaround for me to stop using meta-build?

This is definitely worth a try.

The situation with BSP is currently, that we more or less fly blindfolded, as we don't have proper integration testing for it in Mill. Other BSP servers have it, Metals also runs some, and there is also a bsp-testkit(2), but I still haven't found the time to adapt it to Mill. Once we have integration testing for BSP, we could make and keep it more robust, faster and easier. Currently, it's manual testing and luck to find issues, which is not very rewarding, quite the opposite. Adding some integration testing for our BSP server to assert expected BSP responses for given projects would be a great contribution. I think there is almost no knowledge about Mill internals needed, as it's mostly protocol testing.

@DamianReeves
Copy link

Where can I find this bsp-testkit?

lihaoyi added a commit that referenced this issue Aug 15, 2023
…in BSP to avoid using the wrong evaluator (#2692)

Should fix #2643.

The basic problem is previously BSP always used the `frame(0)` evaluator
passed in to `updateEvaluator`, which is meant specifically for
evaluating user tasks in the root `./build.sc`. However, BSP also
querying of modules and tasks both in `build.sc` as well as meta-builds
in `mill-build/build.sc` and nested meta-builds. This ends up evaluating
the meta-builds in the same `out/` folder as the main build, rather than
in the `out/mill-build/` folders they should be evaluated in.

This PR avoids using the `Evaluator` given in `updateEvaluator`, and
instead preserves the `Evaluator`s we already construct as part of
`MillBuildBootstrap` in `mill.bsp.worker.State`, and passes them as a
`Seq[Evaluator]` from the enclosing `MillBuildBootstrap` code all the
way to the Mill-BSP code so we can associate each `Module` with its
respective `Ealuator`. We then use those associated `Evaluator`s to
perform the actual evaluation throughout the
`Mill{Scala,Java,Jvm,}BuildServer` implementations. There's some
additional re-shaping, so that in case a single BSP API call wants to
query modules/tasks from multiple evaluators at once we properly group
the tasks/modules together according to their respective evaluators for
evaluation.

By passing the `Seq[Evaluator]` from the enclosing `MillBuildBootstrap`,
this also lets us remove the now-redundant call to `MillBuildBootstrap`
buried within `State.scala`. We already have all the necessary data
structures from the enclosing `MillBuildBootstrap` and its evaluators,
so we don't need to re-run the bootstrap process and re-construct all of
it from scratch just for BSP

I haven't managed to reproduce the original error, so confirming the fix
will have to wait until this lands in master and people can try it out.
But I have manually tested using VSCode to load and jump around
`example/basic/1-simple-scala/` and
`example/scalabuilds/10-scala-realistic/`, and it seems all the
references and modules work and are set up correctly. So at least we
have some confidence that this doesn't cause any regressions.

This should also supersede
#2648, since we now no longer
need to re-run the `MillBuildBootstrap`/`RootModuleFinder` logic at all
since we just take the existing list of `Evaluator`s from the enclosing
bootstrap process
@lefou lefou added this to the 0.11.2 milestone Aug 15, 2023
@lefou
Copy link
Member Author

lefou commented Aug 15, 2023

We have merged #2692, which should fix this issue. It would be nice if you could confirm the fix. I started CI job https://github.com/com-lihaoyi/mill/actions/runs/5864992453 to publish a snapshot release.

/cc @tgodzik @DamianReeves

@tgodzik
Copy link

tgodzik commented Aug 18, 2023

We have merged #2692, which should fix this issue. It would be nice if you could confirm the fix. I started CI job https://github.com/com-lihaoyi/mill/actions/runs/5864992453 to publish a snapshot release.

/cc @tgodzik @DamianReeves

Looks to be working! I need to do some more work to make run work in metals, but that should be ready soon. The only issue is that it will still throw an exception when the code doesn't compile, which will show up in the logs and might be annoying for users. Ideally, it would just return last jvmEnvironment especially that this shouldn't be influenced by regular compilation.

@tgodzik
Copy link

tgodzik commented Aug 18, 2023

Ok, the PR is ready scalameta/metals#5566 though I need to refactor things at some point since we get a lot of different options when things can be run (via Dap or via build tool itself or via client)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants