From d137560809932a88af5ea1ed83d610cc53db1e13 Mon Sep 17 00:00:00 2001 From: adrian-velonis1 <85172912+adrian-velonis1@users.noreply.github.com> Date: Thu, 18 Jul 2024 09:48:44 -0400 Subject: [PATCH 1/2] PD-4878: dependency language https://datical.atlassian.net/browse/PD-4878 --- docs/code/architecture/dependencies.md | 36 +++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/code/architecture/dependencies.md b/docs/code/architecture/dependencies.md index 1893868..7d90e0d 100644 --- a/docs/code/architecture/dependencies.md +++ b/docs/code/architecture/dependencies.md @@ -2,7 +2,7 @@ ## Overall Strategy -Because Liquibase is often used as a library in other applications, we keep our external dependency list as small as possible. +Because Liquibase is often used as a library in other applications, we keep our external dependency list as small as possible. The problems we are trying to avoid are: > Liquibase is a library in user's application X, and Liquibase has a dependency on library Y version 4.5. @@ -10,7 +10,7 @@ The problems we are trying to avoid are: > **Variation 1:** But application X itself depends on Y version 3.1. Or 5.2. > The actual version of Y in the classpath is controlled by the application, and they will ensure their version is used which may not be compatible with what Liquibase calls. > -> **Variation 2:** But application X explicitly excludes library Y, therefore Liquibase has no access to the expected functions. +> **Variation 2:** But application X explicitly excludes library Y, therefore Liquibase has no access to the expected functions. When new functionality could leverage existing 3rd party libraries, the tradeoff to make is weighing the **_value of reuse vs. the danger of incorrect versions_** being used. @@ -18,39 +18,40 @@ When new functionality could leverage existing 3rd party libraries, the tradeoff In making the decision to add a dependency, we use the following guidelines: -- How complex is the code being depended on? +- How complex is the code being depended on? - The simpler the usage is, the more we prefer to rewrite the functionality -- How stable is the dependency? +- How stable is the dependency? - The fewer major/breaking releases there have been historically and/or are on the horizon, the more comfortable we are with the dependency -- How common is the dependency? - - The more likely the dependency is to be used by other applications, the **_less_** comfortable we are with the dependency. This is a bit counter-intuitive, but since the root problem is version conflicts then more usage equals more chances for conflicts. +- How common is the dependency? + - The more likely the dependency is to be used by other applications, the **_less_** comfortable we are with the dependency. This is a bit counter-intuitive, but since the root problem is version conflicts then more usage equals more chances for conflicts. - How broken will Liquibase be if the dependency is different or missing? - The more isolated the use of the dependency is, the more comfortable we are with the dependency. Especially if the code using it can gracefully handle differences in versions and/or missing functions. - What other dependencies does it bring along? - - Repeat the review for all transitive dependencies introduced by the new dependency -- What is the license of the dependency? - - To avoid roadblocks to using Liquibase, we don't use dependencies licenses with "viral" aspects to them. The GPL license can be problematic for this reason, and even the LGPL can be concerning to users. The more permissive the license, the more comfortable we are with the dependency. + - Repeat the review for all transitive dependencies introduced by the new dependency +- What is the license of the dependency? + - To avoid roadblocks to using Liquibase, we don't use dependencies licenses with "viral" aspects to them. The GPL license can be problematic for this reason, and even the LGPL can be concerning to users. The more permissive the license, the more comfortable we are with the dependency. ## Examples ### Apache Commons Lang -Apache's commons-lang.jar is a very popular (don't include) library containing simple, helper functions (don't include). It is very stable (include). It would be used throughout the entire codebase, so a missing dependency would completely break Liquibase (don't include) +Apache's commons-lang.jar is a popular library containing simple, helper functions. It would be used throughout the entire codebase, so a missing dependency would cause Liquibase to fail. -**Verdict:** We did not add it as a dependency because the individual functions as we needed them were simple enough to re-implement. Over time, the number of "copied" functions has grown and perhaps it's worth switching to using the dependency now given how stable it is. -But nothing has pushed us to make that switch yet. +**Verdict:** We did not add it as a dependency because the individual functions as we needed them were simple enough to re-implement. Over time, the number of "copied" functions has grown and perhaps it's worth switching to using the dependency now given how stable it is. But nothing has pushed us to make that switch yet. ### OpenCSV -Liquibase's loadData feature requires CSV parsing, which is a complex operation (include). OpenCSV is a popular library for parsing, but CSV parsing is not a super-common requirement in other applications (borderline include). -OpenCSV in general is stable (include), and if the library is missing it is only the loadData change that stops working (include). +Liquibase's loadData feature requires CSV parsing, which is a complex operation. OpenCSV is a popular library for parsing, but CSV parsing is not a super-common requirement in other applications. + +If the library is missing, only the loadData change stops working. **Verdict:** Included OpenCSV as a dependency. CSV parsing is complex code we don't want to maintain, and OpenCSV is a stable library therefore it is best to use it. ### Apache HttpClient -Liquibase's HTTP support requires HTTP client functionality (include). Apache's HttpClient is a popular library for HTTP client functionality, with many applications also using that library (exclude). -The library is growing and improving with major changes between versions 3,4, and 5 (exclude). Currently, the behavior we need is relatively simple and mostly available through the standard `java.net` packages. +Liquibase's HTTP support requires HTTP client functionality. Apache's HttpClient is a popular library for HTTP client functionality, with many applications also using that library. + +The library is growing and improving with major changes between versions 3, 4, and 5. Currently, the behavior we need is relatively simple and mostly available through the standard `java.net` packages. **Verdict:** We used the standard `java.net` packages for the HTTP support, and did not add Apache HttpClient as a dependency. If our HTTP needs change over time, we can revisit the decision. @@ -64,5 +65,4 @@ Liquibase avoids this because: 1. The renaming often causes problems within the dependency code - If the dependency uses reflection to find classes, the renaming can break that in ways not easily detected 2. It obfuscates the libraries users are exposed to - - In order to correctly track their own application's security, users need easy and standard ways to see **_all_** the libraries they are using in their supply chain - + - In order to correctly track their own application's security, users need easy and standard ways to see **_all_** the libraries they are using in their supply chain From ae149afcf9735771a59151ecf14a0cfbbce05f23 Mon Sep 17 00:00:00 2001 From: adrian-velonis1 <85172912+adrian-velonis1@users.noreply.github.com> Date: Thu, 18 Jul 2024 11:19:32 -0400 Subject: [PATCH 2/2] PD-4826: Apache Commons Lang dependency 4.27.0 https://datical.atlassian.net/browse/PD-4826 --- docs/code/architecture/dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/code/architecture/dependencies.md b/docs/code/architecture/dependencies.md index 7d90e0d..873bd89 100644 --- a/docs/code/architecture/dependencies.md +++ b/docs/code/architecture/dependencies.md @@ -37,7 +37,7 @@ In making the decision to add a dependency, we use the following guidelines: Apache's commons-lang.jar is a popular library containing simple, helper functions. It would be used throughout the entire codebase, so a missing dependency would cause Liquibase to fail. -**Verdict:** We did not add it as a dependency because the individual functions as we needed them were simple enough to re-implement. Over time, the number of "copied" functions has grown and perhaps it's worth switching to using the dependency now given how stable it is. But nothing has pushed us to make that switch yet. +**Verdict:** Included Apache Commons Lang as a dependency in Liquibase 4.27.0+. Over time, the number of its helper functions we've re-implemented has increased, so it became worthwhile to include it outright. ### OpenCSV