Community
Participate
Working Groups
The JavaBuilder uses the WorkspaceRoot as schedulingRule. That prevents many other jobs/builders to work at the same time. We should investigate whether the scheduling rule could be relaxed to something more focused such as project+JavaModel
New Gerrit change created: https://git.eclipse.org/r/119728
What is the expected behavior if building one project deletes/modifiers .class files needed as dependencies by another project being built at the same time?
(In reply to Stephan Herrmann from comment #2) > What is the expected behavior if building one project deletes/modifiers > .class files needed as dependencies by another project being built at the > same time? With the submitted patch, I've added to the scheduling rule another singleton, which is not the whole workspace and is derived from the JavaModel singleton. With this, it should prevent JavaBuilder to be running in parallel, while not preventing non-Java projects to build in parallel. So expected behaviour would be that it changes nothing. If later, we can make JDT build in parallel, good; but at this time the idea is to not have it preventing other projects from building in parallel. Relaxing the scheduling rule by not making it be the whole workpsace is necessary for that.
The patch is ready for review, doesn't break any test and adds another test showing the value of the change (this change allows other projects to build in parallel without locking the whole workspace). I'm marking it to 4.8.M7 in the hope someone would be able to look at it by then. As mentioned in earlier comments, the taken approach is fairly defensive to minimize the risk of regressions: All JDT project builds would have scheduling rules that would conflict with each other and the scheduling rule is a multi-rule of JDT projects. As a result, no JDT builder would run on parallel and the build of JDT projects would remain sequential, and typical operations performed by builders inside projects would work. This is an important change to make JDT a better citizen of the IDE and not blocking 3rd party projects for using parallel builds.
Is there any chance this can be evaluated for M7?
(In reply to Mickael Istria from comment #5) > Is there any chance this can be evaluated for M7? Sorry, my team has no slots for that. If Stephan wants to invest into this, it's fine with me. Otherwise it will have to wait. Stephan?
(In reply to Dani Megert from comment #6) > (In reply to Mickael Istria from comment #5) > > Is there any chance this can be evaluated for M7? > > Sorry, my team has no slots for that. If Stephan wants to invest into this, > it's fine with me. Otherwise it will have to wait. > > Stephan? Sounds interesting, but there's a long backlog of bugs where I can create more value in the same given time.
Created attachment 274537 [details] Gantt sequential build I've made a basic experiemnt: 1. took the wildfly code base 2. run `mvn eclipse:eclipse` to generate JDT conf files 3. then ran a build with regular code (+ https://github.com/mickaelistria/eclipse-ide-parallel-builds-demo to get the metrics) 4. Tweak JavaBuilder to have getRule() returning null. 5. Clean project (closed workspace, git clean -fxd than repeat `mvn eclipse:eclipse`, reopen project in a fresh workspace) 6. configured preferences to use 4 parallel builds. Some negative points: * Some errors can sometimes show up in the log, for example when a refresh is running at the same time, or for other unknow reason. It happens to ma about 25% of times when testing parallel builds Some positive points: * In majority of cases, builds complete * Classes are identical when builds complete in parallel and sequentially * Parallel build is 30-40% faster than sequential one. Attached are some Gantt chart of how builds are scheduled. On the top-left, you can see the total duration of the build.
Created attachment 274538 [details] Gantt parallel build - null scheduling rule
(In reply to Mickael Istria from comment #8) > Some negative points: > * Some errors can sometimes show up in the log, for example when a refresh > is running at the same time, or for other unknow reason. It happens to ma > about 25% of times when testing parallel builds Those need to be addressed before proceeding. Or do they happen only when 'null' is used?
New Gerrit change created: https://git.eclipse.org/r/126009
In the submitted patch, I've added a preference (which is off by default and not visible) to allow adopters to set the scheduling rule to null for JavaBuilder. This allows easier testing (to decide whether to make it default or not in the future) and adoption for potential interested parties. I'd like to get this preference merged in JDT early in 4.10 to facilitate progress on that matter. As it's off by default and not offered to user, it's close to 0-risk of regression. We can even document it as experimental in the javadoc if you think it's necessary.
Gerrit change https://git.eclipse.org/r/119728 was merged to [master]. Commit: http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=749e6f86b20add3c4fa8193fea1a613d6b0a897b
(In reply to Eclipse Genie from comment #13) > Gerrit change https://git.eclipse.org/r/119728 was merged to [master]. > Commit: > http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/ > ?id=749e6f86b20add3c4fa8193fea1a613d6b0a897b Thanks a lot for the review and merge Manoj!
(In reply to Eclipse Genie from comment #13) > Gerrit change https://git.eclipse.org/r/119728 was merged to [master]. > Commit: > http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/ > ?id=749e6f86b20add3c4fa8193fea1a613d6b0a897b When I click on that link the first several pages of diff show only irrelevant (whitespace?) changes. This is not helpful.
(In reply to Stephan Herrmann from comment #15) > When I click on that link the first several pages of diff show only > irrelevant (whitespace?) changes. This is not helpful. You can look at the commit via Gerrit, and Gerrit has an option in the diff viewer to ignore whitespaces.
Mickael, can you please add this to the 4.10 N&N? Please include the instructions on how to activate this setting.
(In reply to Mickael Istria from comment #16) > (In reply to Stephan Herrmann from comment #15) > > When I click on that link the first several pages of diff show only > > irrelevant (whitespace?) changes. This is not helpful. > > You can look at the commit via Gerrit, and Gerrit has an option in the diff > viewer to ignore whitespaces. I know that there are tools to ignore whitespace, but this clutters the history in unwanted ways. Please avoid this for any future changes!
New Gerrit change created: https://git.eclipse.org/r/129137
(In reply to Stephan Herrmann from comment #18) > I know that there are tools to ignore whitespace, but this clutters the > history in unwanted ways. Please avoid this for any future changes! In platform projects we solved such issues by running the remove whitespace cleanup action and activating the corresponding save action on the projects. This way we avoided unwanted whitespaces changes.
Gerrit change https://git.eclipse.org/r/129137 was merged to [master]. Commit: http://git.eclipse.org/c/www.eclipse.org/eclipse/news.git/commit/?id=c1b196110f9c4a3a10335da838571117934b5260
Created attachment 276198 [details] Document null scheduling rule/parallel builds comparison See as attachment a document explaining a methodology and some results to compare the performance and output of building the same Java/Maven project with the regular workspace scheduling rule vs with null scheduling rule. The results are pretty positive, and so far I didn't notice any pitfall with null scheduling rule/parallel builds compared to regular build. The gain is between 10 and 40% build time. This video gives a good idea of the process and results: http://www.screencast.com/t/FDxlU5fBN This document has for goal to convince JDT, m2e (and JDT-LS) of making the null scheduling rule the default. It's only a preference to change. If you have some other cases you think are important to try, please try them and report, or at least mention them with some points about what make them interesting.
Just found a potential issue with parallel builds and JavaBuilder java.nio.file.FileSystemAlreadyExistsException at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.newFileSystem(ZipFileSystemProvider.java:99) at java.base/java.nio.file.FileSystems.newFileSystem(FileSystems.java:344) at java.base/java.nio.file.FileSystems.newFileSystem(FileSystems.java:293) at org.eclipse.jdt.internal.core.builder.ClasspathJrt.initialize(ClasspathJrt.java:195) at org.eclipse.jdt.internal.core.builder.ClasspathJrt.<init>(ClasspathJrt.java:79) at org.eclipse.jdt.internal.core.builder.ClasspathLocation.forJrtSystem(ClasspathLocation.java:142) at org.eclipse.jdt.internal.core.builder.NameEnvironment.computeClasspathLocations(NameEnvironment.java:309) at org.eclipse.jdt.internal.core.builder.NameEnvironment.<init>(NameEnvironment.java:59) at org.eclipse.jdt.internal.core.builder.JavaBuilder.initializeBuilder(JavaBuilder.java:622) at org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:173) at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:834) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:228) at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:271) at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:324) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:327) at org.eclipse.core.internal.events.BuildManager.lambda$2(BuildManager.java:446) at org.eclipse.core.internal.events.GraphProcessor$1.run(GraphProcessor.java:119) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63) I'll report a sub-task about it.
Mickael, I'm OK to add and review the UI for the preference . Which patch is it?
(In reply to Andrey Loskutov from comment #24) > Mickael, I'm OK to add and review the UI for the preference . Which patch is > it? Cool. Patch is not there yet ;) If no-one did it in the meantime, I'll work on this after EclipseCon and PTO, in early November.
If I understand correctly, the null scheduling rule makes scheduling rely entirely on the topological order derived from project dependencies, right? Do we know, what exactly is covered by these project dependencies? Examples: - What happens when project A creates a jar file (in project A or any other location) that is consumed by project B, without B expressing a dependency on project A? - What happens, when project A generates source code into project D? - What happens when project B directly depends on A's output folder without mentioning project A? - What happens if dependencies are via resources outside the workspace? - ... Some of these situations may already be tricky for sequential builds, but concurrent builds could easily aggravate the situation, no?
We discussed this problem also with Xtext people on Eclipsecon. The difficulty is that different builders seem also to "see" different project dependencies, so xtext builder knows more dependent projects then java builder, but Christian can explain this better. But alone for testing and experiments it would be cool to have a possibility to configure jdt build to have some non workspace rule, for example project rule.
(In reply to Andrey Loskutov from comment #27) > We discussed this problem also with Xtext people on Eclipsecon. The > difficulty is that different builders seem also to "see" different project > dependencies, so xtext builder knows more dependent projects then java > builder, but Christian can explain this better. Workspace API is the only source of truth we can use to deal properly with project dependencies, and an extension point allow projects (by nature or builder, I don't recall and can't check now) to declare additional dependencies dynamically. Those are taken into account by parallel builds. So overall, it seems like a ready to fox issue for xtext. > But alone for testing and experiments it would be cool to have a possibility > to configure jdt build to have some non workspace rule, for example project > rule. The issue with scheduling rule is that whenever we replace a rule by a narrower one, then we need to make sure all included behavior fits in the new rule. But JDT builder is extensible (via annotation processing for example) so we can't be sure all changes during a build remain in the current project. Null rule is no rule. As opposed to a narrower rule, it doesn't restrict what can run in it, so it fits extensibility much better.
(In reply to Mickael Istria from comment #28) > Null rule is no rule. As opposed to a narrower rule, it doesn't restrict > what can run in it, so it fits extensibility much better. "fits extensibility" as in "admits arbitrary havoc"?
> "fits extensibility" as in "admits arbitrary havoc"? :D Admitting arbitrary havoc is our legacy we have to remain backward-compatible with.
(In reply to Mickael Istria from comment #30) > > "fits extensibility" as in "admits arbitrary havoc"? > > :D > Admitting arbitrary havoc is our legacy we have to remain > backward-compatible with. Previously, projects could be executed in a less-than-optimal order. With a null scheduling rule we could see arbitrary race conditions. To me that sounds worse than legacy.
(In reply to Stephan Herrmann from comment #31) > Previously, projects could be executed in a less-than-optimal order. By less-than-optimal, in comment 26, you're mentioning cases that would lead to incorrect topological order -sequentially or in parallel- because dependencies are not expressed in the workspace. So the result of this case is likely to be wrong even with legacy build. Making build parallel doesn't seem worse in those cases. It's about as likely to provide bad results. That said, there may be internal stuff in JDT builder that is affected and wasn't spotted by the examples projects. Do you have an example of "risky" projects that are in this case? I can gladly audit them and add reports to the document.
Preamble 1: I understand my task in JDT as spending the vast majority of my time on corner cases. Seeing that an approach works on sunny days doesn't say much. Preamble 2: In other discussions I have observed a pattern that an existing solution with some flaws is used as a justification for making things a lot worse, still. I do hope this discussion doesn't belong to this pattern. So, what is the current flaw? I was just guessing about less-then-optimal build order. Looking into the implementation we see several mechanisms for propagating changes caused by one builder as to (re-)trigger builders for other projects. Given that this is in productive use in the field we should assume that this works solidly, maybe not 9 nines yet, but several nines. By contrast, what can happen if projects are built in parallel, which have undetected conflicts? I gave two examples: dependency via a jar file rather than via a project, or via code generation from one project into another. In both cases we could end up with concurrent read and write of the same resource. What's the consequence? ResourceException? Deadlock? Do we have a solid story to ensure that *every* build produces correct output even when conflicting projects are built concurrently? Until the latter question is answered affirmatively, I suggest to make the desired configuration option an undocumented / experimental switch, e.g. via system property. Experts can play with it, but we don't imply to users that this is a feature ready for production use. (In reply to Mickael Istria from comment #28) > Workspace API is the only source of truth we can use to deal properly with > project dependencies, and an extension point allow projects (by nature or > builder, I don't recall and can't check now) to declare additional > dependencies dynamically. Those are taken into account by parallel builds. Admittedly I'm not aware of such extension point. Where should I look to learn about additional (dynamic?) dependencies?
New Gerrit change created: https://git.eclipse.org/r/131659
(In reply to Stephan Herrmann from comment #33) > Preamble 2: In other discussions I have observed a pattern that an existing > solution with some flaws is used as a justification for making things a lot > worse, still. I do hope this discussion doesn't belong to this pattern. I don't hope so neither. Your concerns are more than welcome and are seriously taken into consideration before we can assume a relaxed scheduling rule can be made the default or even exposed as a choice to the use. > By contrast, what can happen if projects are built in parallel, which have > undetected conflicts? I gave two examples: dependency via a jar file rather > than via a project, or via code generation from one project into another. In > both cases we could end up with concurrent read and write of the same > resource. What's the consequence? ResourceException? Deadlock? Do we have a > solid story to ensure that *every* build produces correct output even when > conflicting projects are built concurrently? Ok, I'll try to look at those cases in more details and will report what works/doesn't work/should be improved on the matter of handling deltas in parallel build and JDT builders. If you also want to have a look at it in parallel, that would be welcome. > Until the latter question is answered affirmatively, I suggest to make the > desired configuration option an undocumented / experimental switch, e.g. via > system property. Experts can play with it, but we don't imply to users that > this is a feature ready for production use. +1 for that. It's actually already more or less the current case (it's preference to control things and a 3rd party plugin for experts allows to control it). > (In reply to Mickael Istria from comment #28) > Admittedly I'm not aware of such extension point. Where should I look to > learn about additional (dynamic?) dependencies? It's org.eclipse.core.resources.builders/builder@dynamicReferences
(In reply to Mickael Istria from comment #35) > (In reply to Stephan Herrmann from comment #33) > > Preamble 2: In other discussions I have observed a pattern that an existing > > solution with some flaws is used as a justification for making things a lot > > worse, still. I do hope this discussion doesn't belong to this pattern. > > I don't hope so neither. Your concerns are more than welcome and are > seriously taken into consideration before we can assume a relaxed scheduling > rule can be made the default or even exposed as a choice to the use. Would be good to capture the scenarios in test cases. > > Until the latter question is answered affirmatively, I suggest to make the > > desired configuration option an undocumented / experimental switch, e.g. via > > system property. Experts can play with it, but we don't imply to users that > > this is a feature ready for production use. > > +1 for that. It's actually already more or less the current case (it's > preference to control things and a 3rd party plugin for experts allows to > control it). You don't need a plug-in for that, it can be done via ini file. I suggest to send detailed steps on cross-project-issues and test that configuration. However, for most people it is easier if they can just set system property.
Investigation can for sure continue; but it's now late to introduce more experimental changes for 4.11 as we're entering the RC cycle within a few hours.
(In reply to Dani Megert from comment #36) > You don't need a plug-in for that, it can be done via ini file. I suggest to > send detailed steps on cross-project-issues and test that configuration. @Mickael, did this happen? If not, can this be done for 4.11 before M3?
(In reply to Lars Vogel from comment #38) > @Mickael, did this happen? If not, can this be done for 4.11 before M3? Nope, and at the moment I'm too deeply in other tasks to properly take care of this topic. There will probably be many questions once announced on cross-project and answering will require more dedication than I an currently providre. It's still in my backlog with relatively high priority, but not top #3 at the moment. If anyone wants to handle some on the next steps, that's more than welcome.
Bulk move out of 4.11
New Gerrit change created: https://git.eclipse.org/r/137742
(In reply to Eclipse Genie from comment #41) > New Gerrit change created: https://git.eclipse.org/r/137742 why?
Gerrit change https://git.eclipse.org/r/137742 was merged to [master]. Commit: http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?id=f130788d4def96e08510f33bfc111f61e9a63fd9
(In reply to Mickael Istria from comment #42) > (In reply to Eclipse Genie from comment #41) > > New Gerrit change created: https://git.eclipse.org/r/137742 > > why? See bug 544890.
Next version of the patch must include a test that covers and reproduce stack at https://bugs.eclipse.org/bugs/show_bug.cgi?id=544890#c3 ,and a fix.
(In reply to Mickael Istria from comment #45) > Next version of the patch must include a test that covers and reproduce > stack at https://bugs.eclipse.org/bugs/show_bug.cgi?id=544890#c3 ,and a fix. The issue got surfaced by having many (400 in my case) projects in the workspace and by increasing the Java build state version.
(In reply to Dani Megert from comment #46) > (In reply to Mickael Istria from comment #45) > > Next version of the patch must include a test that covers and reproduce > > stack at https://bugs.eclipse.org/bugs/show_bug.cgi?id=544890#c3 ,and a fix. > The issue got surfaced by having many (400 in my case) projects in the > workspace and by increasing the Java build state version. It is independent on the number of projects. The code in org.eclipse.jdt.core.JavaCore.initializeAfterLoad(IProgressMonitor) can't work at all after this change: https://git.eclipse.org/r/#/c/119728/17/org.eclipse.jdt.core/model/org/eclipse/jdt/core/JavaCore.java. Project.touch() requires WorkspaceRoot rule, but initializeAfterLoad() line 4573 uses MultiRule to run the task: An internal error occurred during: "Initializing Java Tooling". Attempted to beginRule: R/, does not match outer scope rule: MultiRule[P/CSVReader, ... at org.eclipse.core.runtime.Assert.isLegal(Assert.java:66) at org.eclipse.core.internal.jobs.ThreadJob.illegalPush(ThreadJob.java:137) at org.eclipse.core.internal.jobs.ThreadJob.push(ThreadJob.java:392) at org.eclipse.core.internal.jobs.ImplicitJobs.begin(ImplicitJobs.java:66) at org.eclipse.core.internal.jobs.JobManager.beginRule(JobManager.java:297) at org.eclipse.core.internal.resources.WorkManager.checkIn(WorkManager.java:124) at org.eclipse.core.internal.resources.Workspace.prepareOperation(Workspace.java:2243) at org.eclipse.core.internal.resources.Project.touch(Project.java:1319) at org.eclipse.jdt.core.JavaCore$1.run(JavaCore.java:4562) at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2295) at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2322) at org.eclipse.jdt.core.JavaCore.initializeAfterLoad(JavaCore.java:4571) at org.eclipse.jdt.internal.ui.InitializeAfterLoadJob$RealJob.run(InitializeAfterLoadJob.java:39) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63) The fix for this concrete error above would be to change line 4573 from new MultiRule(Arrays.stream(projects).map(IJavaProject::getResource).toArray(ISchedulingRule[]::new)), to workspace.getRoot(). But this means, other places in the patch need to be checked again, at lest one shows exact same error pattern: https://git.eclipse.org/r/#/c/119728/17/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
*** Bug 526690 has been marked as a duplicate of this bug. ***
Looking at the bugs/duplicates which mention Windows builds I'm wondering if the blocking or sometimes long builds on workspaces with lots of projects might in a way be related to something OS-specific (Windows). Our team is using the same setup (using Oomph) all over the place on similar or same workstations. The ones using Linux/MacOS seems to have lot less trouble than on Windows...
At the moment, there is no obvious value in making JDT builder parallel (parallel builds are more profitable for builders that runs external scripts), and JDT has been demonstrated as being a bit hard to make parallel. So I'm removing it from my bucket. Maybe I'll work on it later, maybe not (it mostly depends on whether build time is the #1 resource gain in Eclipse IDE and JDT-LS, but at the moment, I think m2e is a better candidate for time savings). If anyone wants to continue this work in the meantime, it's very welcome.