Community
Participate
Working Groups
Build: 20020625 External tool builders have the following dilemma: if two external tool builders are installed on a single project, the second one will be skipped, since there may not be any changes appearing in the delta since the builder was last run. As an optimization we don't invoke builders if there are no changes in the projects they care about. The hack to work around this was to call forgetLastBuiltState() every time the external tool builder was invoked. This has the unfortunate downside that the above-mentioned optimization can NEVER happen. This means that the tool builder will be invoked on EVERY resource change in EVERY project. We need to supply the external tool builders with a real solution for this. One possibility is that we implement real support for having multiple builders installed with the same name, each receiving its own delta.
I think I have a solution implemented. The main problem is that there must be *some* way to uniquely identify a builder. If someone invokes IProject.build(int kind, String builderName, Map args, IProgressMonitor monitor), then we need to be able to infer which builder instance to invoke. The only information that can use to uniquely identify the builder is the builderName and the arguments. The solution I propose is to uniquely identify a builder by this pair: (builderName, args). This is represented in the build spec by an ICommand object. That way, if someone invokes a builder with the same name and the same arguments, we will reuse the same builder instance. This solution will work for external tools with the limitation that you can't have two identical external tools in a given build spec (same name and arguments). This limitation could be made explicit in the API javadoc. Since this is actually just a relaxation of our previous limitation (that you couldn't have two builders with the same name), there shouldn't be any backwards compatibility problems introduced by this fix. Unfortunately this fix requires a change to the .tree file format, because builders were previously stored in no particular order in this file, keyed only by builder name. If there are multiple builders serialized with the same name on the same project, it is impossible to tell them apart on startup. Since this requires a file format change, I think we should defer releasing the fix until later in the cycle, when we can release as many file-format altering fixes as possible in one shot. This is definitely not a 2.0.1 candidate.
One possible change I'm thinking of that may impact this work. People have requested they can pick an external tool for a builder from the list they already have available from the Run menu. We are looking at how we could do that in release 2.1 One option is all tools that the user creates are available in the Run menu (i.e. all stored in the registry). If you add on of these tools as a builder to a project, we would only add the tool name in the ICommand arguments (instead of all the arguments needed to reconstruct the tool). When asked to run the external tool during the build, the builder would have the tool name in its argument, which we would look-up in the registry. No two tools in the registry will have the same name. The only limitation with the current core solution, is a tool can only be in one spot in the builder order for a project. If they want the same external tool to run before and after a Java builder for example, they would need to copy the tool to another name ("copy" feature we are looking to add for 2.1)
Created attachment 2061 [details] patch file with proposed solution
Simon, is the "registry" you're talking about stored/shared with each project or is it in the workspace metadata?
Jared, the "registry" in my comment above refers to the persistent store where external tools are saved (that is, the .xtools directory). John, the solution of including the arguments, not just the builder name will work for external tool. We have (had) the restriction that each external tool have a unique name, and that unique name is stored as an argument in the ICommand for the external tool builder. John, one concern I have will be performance. The ICommand representing an external tool builder will have quite a few arguments. Will testing each one of these be a speed problem? Given the builder name and the external tool name, that would uniquely indentify each external tool builder. If speed is an issue, lets talk...
For now, closing bugs not planned for 2.1. Will reopen after 2.1 release.
See also the discussion and workaround described in bug 39713
We should re-visit this for 3.1 and see if there is something that we can do. We had a related problem in bug 70650 that caused me to find this bug again.
Created attachment 13952 [details] Patch to org.eclipse.core.resources This patch file enables proper support for multiple builders of this same type in a single project's build spec.
Created attachment 13953 [details] Patch to org.eclipse.core.tests.resources Patch to fix and add tests.
Some limitations: - if you use IProject.build(int, String, Map, IProgressMonitor), you will build the first builder that matches the given name. This was previously deterministic based on the assumption of one builder per name. - builder instances are now stored directly on the BuildCommand objects, rather than in a separate table in the ProjectInfo. This means the code for manipulating the project description must now carefully overlay any new information to avoid unnecessarily losing references to existing builder instances. This also means that destructive changes to the build spec, such as changing builder arguments, will cause the existing builder instance to be lost, and a new builder will be created on the next build. This is unavoidable, because it is impossible to otherwise match the old and new build spec when it changes. The advantage of this fix is that it fixes up long standing problems with stale builder information. Since builders were stored separately, they would be referenced indefinitely until the project was deleted. Builders removed from the build spec would still be referenced, along with their old tree state. Now, stale builder instances and their tree states will be garbage collected as soon as they are removed from the build spec. I will release this fix to 3.1 HEAD the week of August 23. I am not planning on releasing to the 3.0.1 stream due to the sensitivity of the changed areas (workspace serialization code, builder logic).
Fixes released to HEAD.
I think you meant to flag this as 3.1 M2 :-)
Thanks!