-
Notifications
You must be signed in to change notification settings - Fork 121
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
Zinc incremental compilation behaviour is different when executed in the single jvm vs two consecutive runs #1493
Comments
If you want Java sources to participate in the incremental compilation, then you might need to use Zinc to compile Java so we can analyze them. I didn't read the repro project in detail, but https://github.com/ov7a/zinc-example/blob/4fadc653f6d37f64ec9dd829e5d8b87bf3b14184/src/main/scala/Main.scala#L94-L103 looks suspicious, if it's literally just calling javac. |
Is there a way to use zinc only for scala incremental compilation? In other words, is there an API to provide info about java classes changes? Since zinc is supposed to be used in build tools, I would expect it to be agnostic to that (Imagining fictional scenario with groovy or someNewJVMLangugage compilation).
Yes, it does. I used the plain call for simplicity. Even if the scenario is wrong, I don't understand why, despite providing the same inputs to zinc compiler, I (should) get different results depending on the method of invocation. |
Zinc can compile against JAR files that was compiled from pure Java, so you would probably have to pass information in that way. The mixed compilation is not just a Zinc thing, but it's a feature of Scala compiler to be able to interoperate Scala and Java entities, so Zinc provides an incremental compilation on top of it.
Incremental compilation works by tracking artifacts outputs and language level dependencies. So if the relevant symbols are not tracked, we can't really expect anything to behave correctly. On the other hand, if you could reproduce your result with sbt, then maybe there's a caching bug or whatever? |
Understood, thanks for clarification.
Sorry, I don't get that. I understand that the scenario in the reproducer may be incorrect, but this does not explain the inconsistency between the results. I expect the result to be the same (even if it's a wrong result) when I provide the same inputs to Zinc. Can you at least give some pointers on where to look for implicit inputs?
Can you clarify, please? I think I narrowed it down to Zinc already. In the reproducer, "sbt run" is used for convenience, but I can reproduce the behavior without sbt (running in IDE). I can update the reproducer to run it with plain java if needed. |
Programs are sequence of p⇒q logic, where the precondition p needs to hold for the result to be ok. Otherwise, it's undefined or unsound. I think, Zinc makes the assumption that all
What I'm saying is the if you can reproduce the first run, second run type of behavior using sbt, which is a reference usage of Zinc, then that might point to some bug in Zinc is all I'm saying. |
steps
Please see the reproducer
and its execution:
In short, it does the following:
If all these steps are executed in a single sbt run, zinc does not see the updated java class properly. If 1-2 and 3-4 are made in two consecutive runs, it works as expected.
I can observe this behavior with zinc 1.10.4, 1.10.0, 1.9.6.
problem
I suspect it has something to do with the internal caches of zinc. However, I haven't found a proper way to clear them.
expectation
I expect the behavior to be the same: the state should be preserved in compileAnalysis, and all the necessary data should be there. Apparently, that's not the case.
I expect the same output to be produced if the same inputs are used, independent of the environment.
notes
Somebody may suspect that it depends on the loaded jars, but I get the same issue with the hardcoded, explicit paths to pre-downloaded jars.
The reproducer is a very rough approximation of how Gradle (8.10) works.
I stumbled across this issue while investigating
The only relevant change in 1.10.1 is fixed stamps for empty files/directories, but I can't reproduce Gradle's issue in isolation. If anyone has ideas about what can be an (implicit) input, it would be appreciated.
The text was updated successfully, but these errors were encountered: