-
Notifications
You must be signed in to change notification settings - Fork 323
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
Fix incremental compilation of SPI in Java helper libraries #8129
Conversation
To test this (since this cannot be unit tested), I've created a Python script: import os
clazz = """
package org.enso.database;
import org.enso.base.file_format.FileFormatSPI;
@org.openide.util.lookup.ServiceProvider(service = FileFormatSPI.class)
public class TestFormatSPI extends FileFormatSPI {
@Override
protected String getModuleName() {
return "Standard.Database.Connection.Connection";
}
@Override
protected String getTypeName() {
return "Connection";
}
}
"""
path = "std-bits/database/src/main/java/org/enso/database/TestFormatSPI.java"
enso_script = """
from Standard.Base import all
from Standard.Database import all
import Standard.Base.System.File_Format as File_Format_Module
main =
IO.println "First pass:"
IO.println <| Panic.recover Any <| File_Format_Module.format_types
IO.println ""
IO.println "Second pass:"
File_Format_Module.format_types.each IO.println
"""
with open("load-formats.enso", "w") as f:
f.write(enso_script)
with open(path, "w") as f:
f.write(clazz)
print("Wrote file: " + path)
os.system("sbt buildEngineDistribution")
os.system("enso run load-formats.enso")
os.remove(path)
print("Deleted file: " + path)
os.system("sbt buildEngineDistribution")
os.system("enso run load-formats.enso")
os.remove("load-formats.enso") It creates a new File_Format type in Running that script on current
As we can see, currently the script reproduces the CI issue - after removing the added new class - the first pass of loading the formats fails with |
…emoved too late and required 2 recompilations to work
After applying the patch from this PR and re-running the repro Python script, we get:
As we can see, this time the missing file gets immediately detected and a rebuild of
then, the first pass succeeds without the issue that used to happen on the repro before:
meaning that the problem should be fixed and our incremental CI builds should no longer suffer from this issue! 🎉 |
This is what SBT logs look like with
|
May be related #8006 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks promising!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice attempt to fix the problem that once forced us to split runtime
into runtime-service-id-instrument
, etc. Good to see the sbt
limitations can be overcome when one understands the sbt
design.
) | ||
} | ||
|
||
(classFilePath, hasSource) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Iterates the current project to find all .class
files in META-INF/services/serviceConfig
and checks if they have .java
source.
s"to ensure that the SPI definition is up-to-date." | ||
) | ||
IO.delete(serviceConfig) | ||
kept.foreach { case (path, _) => IO.delete(path) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deletes the META-INF/services
file and deletes the .class
files for the kept ones. Great idea.
@@ -2122,6 +2122,9 @@ lazy val `std-base` = project | |||
.settings( | |||
frgaalJavaCompilerSetting, | |||
autoScalaLibrary := false, | |||
Compile / compile / compileInputs := (Compile / compile / compileInputs) | |||
.dependsOn(SPIHelpers.ensureSPIConsistency) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we do this for all projects that have Compile / compile /compileInputs
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As noted in the docs - I'm not sure if this will work well with mixed-Scala projects - since as you noticed - I check for existence of a .java
file corresponding to .class
.
In case of mixed projects - that file may not exist if the service is written in Scala.
If we can guarantee we won't have such a case, I guess we could try to set it as a global setting, if I recall correctly it should be possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to merge the current PR, because it solves the most immediate issue and got through CI.
But if we decide in the discussion that we want to amend how we 'register' this 'hook', I'm happy to do a followup PR updating that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this wouldn't work if service was defined on a mixed project that has both Java and Scala service providers. For that to work you would have to add 33a06c9 as well.
But... it looks like we no longer have that case, so this is fine.
Pull Request Description
services
configuration was not cleaned and SPI definitions were leaking between PRs, causing random failures:Important Notes
Checklist
Please ensure that the following checklist has been satisfied before submitting the PR:
Scala,
Java,
and
Rust
style guides. In case you are using a language not listed above, follow the Rust style guide.
./run ide build
.