-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Buck is inconsistent in dependency resolution order between java tests and binaries, problematic with duplicates #1830
Comments
Could you post the errors for "Buck uses different lookup order for tests and binaries, this may make all the tests pass but binary may fail with "Method not found in production"." I'm not sure what you are talking about here. Since to my understanding, as long as dependencies are all listed, there shouldn't be problems building/running due to missing dependencies. |
@bobyangyf Hi Bob, please see the example I linked in description I constructed with resources: https://github.com/romanoid/buck-tinkering/blob/master/deps-experiment/buildables/BUCK I may construct more sophisticated example with opensource library usages if needed for clarification, I though having clear minimal example is preferred though. Reiterating, tests see resource contents as: While java binary sees resources as: |
I see. |
I don't like option 1 since it gives individual developers no control at all to resolve conflicts (if they happen to depend on 2 versions), so it provides the worse behavior possible. It is still good from consistency perspective though. |
Depending on 2 versions is never a good thing ;) There is too much of the code base (well beyond just java) that enforces lexicographic sorting and relies on such behaviour. |
…ing regressions. This is integration test for facebook#1830. When issue is fixed, the test will be updated accordingly. Meanwhile as well as after the fix, test will indicate any regressions in the dependency conflict resolution order.
"Depending on 2 versions is never a good thing ;)" – totally agree, but that's not something easy to solve for us at the moment. @styurin @ttsugriy, do you share the same opinion as @bobyangyf ? |
…ing regressions. This is integration test for facebook#1830. When issue is fixed, the test will be updated accordingly. Meanwhile as well as after the fix, test will indicate any regressions in the dependency conflict resolution order.
…ing regressions. This is integration test for facebook#1830. When issue is fixed, the test will be updated accordingly. Meanwhile as well as after the fix, test will indicate any regressions in the dependency conflict resolution order.
Meanwhile, can you please take a look on #1841 this should be useful regardless. |
I've talked to them internally regarding this already. |
…ing regressions. This is integration test for facebook#1830. When issue is fixed, the test will be updated accordingly. Meanwhile as well as after the fix, test will indicate any regressions in the dependency conflict resolution order.
Sounds good, I'll have PR shortly. (in addition to #1841) |
…o java binaries. See facebook#1830 for details.
PR: #1844 |
…ing regressions. This is integration test for facebook#1830. When issue is fixed, the test will be updated accordingly. Meanwhile as well as after the fix, test will indicate any regressions in the dependency conflict resolution order.
…ing regressions. This is integration test for facebook#1830. When issue is fixed, the test will be updated accordingly. Meanwhile as well as after the fix, test will indicate any regressions in the dependency conflict resolution order.
…ing regressions. This is integration test for facebook#1830. When issue is fixed, the test will be updated accordingly. Meanwhile as well as after the fix, test will indicate any regressions in the dependency conflict resolution order.
This solution is facebook#1 option for issue mentioned in facebook#1830
Agree that we should unify classpath creation in all mentioned cases. A few thoughts:
Since Java doesn't have notion of dependency graphs (classpath is a flat list), it doesn't enforce sorting or traversal order. I suggest we choose some stable ordering produced by traversing the graph of dependencies. |
@jkeljo any specific reasons why we sort classpath entries? |
…ency ordering Summary: Roman's research regarding dependency ordering: facebook/buck#1830 Reviewers: shangx Reviewed By: shangx Differential Revision: https://code.uberinternal.com/D3190249
I'm planning to work on fixing this issue, please comment and advice!
We've noticed issue with Buck resolving dependencies in different order for different (but related targets).
This is especially dangerous in the case if any duplicates are present in classpath.
Common reason for it is repository including multiple versions of 3rdparty library different modules need (or authors assume different version is needed), then suddenly one of these modules depends on another. (see example)
Buck uses different lookup order for tests and binaries, this may make all the tests pass but binary may fail with "Method not found in production".
Behaviors:
java_binary: lexicographically earlier target selected first (in case of common version naming, lowest version), sorting happens in AbstractSourcePathResolver
java_test: I haven't looked into implementation details yet, but experiments shown postorder DFS with direct children sorted.
Additionally, if any attempt to trace class path is made with buck query, buck query uses BFS, which is different for both.
Demonstrated in experiment:
https://github.com/romanoid/buck-tinkering/blob/master/deps-experiment/buildables/BUCK
This uses resources instead of java files since they are lighter and easier to trace, but behavior is same for .class files
Proposed changes: I'd like to update both java_test and java_binary to be consistent in dependency traversal order.
Options we have (please add if I'm missing some):
Options I like the most are:
Either behavior change should be no-op for people who don't have duplicates.
One other notice: this is potentially breaking change for anyone who has duplicates in classpath. How do you handle such cases?
I were considering to (if possible) add a new .buckconfig setting for java to keep old behavior but change default to new behavior.
Please advice,
Roman
The text was updated successfully, but these errors were encountered: