diff --git a/docs/.gitignore b/docs/.gitignore index d944721de4..b6c91dc747 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -1,2 +1,4 @@ _site/ Gemfile.lock +vendor/ +.bundle/ diff --git a/docs/what-is-a-diamond-dependency-conflict.md b/docs/0001-what-is-a-diamond-dependency-conflict.md similarity index 92% rename from docs/what-is-a-diamond-dependency-conflict.md rename to docs/0001-what-is-a-diamond-dependency-conflict.md index e80a16bee8..8c0ac1036f 100644 --- a/docs/what-is-a-diamond-dependency-conflict.md +++ b/docs/0001-what-is-a-diamond-dependency-conflict.md @@ -1,3 +1,7 @@ +--- +concepts: true +permalink: /what-is-a-diamond-dependency-conflict +--- # What is a diamond dependency conflict? A diamond dependency conflict is a scenario where two or more @@ -62,4 +66,4 @@ state of compatibility. If you want to understand diamond dependency conflicts more deeply, proceed to the next article, -[Why doesn't the compiler catch diamond dependency conflicts?](why-doesnt-the-compiler-catch-diamond-dependency-conficts.md). +[Why doesn't the compiler catch diamond dependency conflicts?](0002-why-doesnt-the-compiler-catch-diamond-dependency-conficts.md). diff --git a/docs/why-doesnt-the-compiler-catch-diamond-dependency-conficts.md b/docs/0002-why-doesnt-the-compiler-catch-diamond-dependency-conficts.md similarity index 91% rename from docs/why-doesnt-the-compiler-catch-diamond-dependency-conficts.md rename to docs/0002-why-doesnt-the-compiler-catch-diamond-dependency-conficts.md index 7e54921620..d0bd956639 100644 --- a/docs/why-doesnt-the-compiler-catch-diamond-dependency-conficts.md +++ b/docs/0002-why-doesnt-the-compiler-catch-diamond-dependency-conficts.md @@ -1,9 +1,12 @@ +--- +concepts: true +permalink: /why-doesnt-the-compiler-catch-diamond-dependency-conficts +--- # Why doesn't the compiler catch diamond dependency conflicts? -When first introduced to the problem of [diamond dependency -conflicts](what-is-a-diamond-dependency-conflict.md), many people ask: "Why -doesn't the compiler catch it?" To explain why, we need to dive into how the -Java build process works. +When first introduced to the problem of [diamond dependency conflicts](0001-what-is-a-diamond-dependency-conflict.md), +many people ask: "Why doesn't the compiler catch it?" To explain why, we need +to dive into how the Java build process works. When `javac` compiles a program, it verifies that every class, variable, or other type of symbol referenced by the code can be found somewhere. Let's look diff --git a/docs/JLBP-1.md b/docs/JLBP-0001.md similarity index 98% rename from docs/JLBP-1.md rename to docs/JLBP-0001.md index 79f6e6451c..3e64e835a5 100644 --- a/docs/JLBP-1.md +++ b/docs/JLBP-0001.md @@ -1,4 +1,9 @@ -# [JLBP-1] Minimize dependencies +--- +jlbp: + id: JLBP-1 +permalink: /JLBP-1 +--- +# Minimize dependencies Use the minimum number of dependencies that is reasonable. Every dependency of a library is a liability of both diff --git a/docs/JLBP-2.md b/docs/JLBP-0002.md similarity index 97% rename from docs/JLBP-2.md rename to docs/JLBP-0002.md index 9e579975ad..064cb8a0a5 100644 --- a/docs/JLBP-2.md +++ b/docs/JLBP-0002.md @@ -1,4 +1,9 @@ -# [JLBP-2] Minimize API surface +--- +jlbp: + id: JLBP-2 +permalink: /JLBP-2 +--- +# Minimize API surface Avoid exposing types from your dependencies. diff --git a/docs/JLBP-3.md b/docs/JLBP-0003.md similarity index 96% rename from docs/JLBP-3.md rename to docs/JLBP-0003.md index 1b3f868ff6..e157beb834 100644 --- a/docs/JLBP-3.md +++ b/docs/JLBP-0003.md @@ -1,4 +1,9 @@ -# [JLBP-3] Use Semantic Versioning +--- +jlbp: + id: JLBP-3 +permalink: /JLBP-3 +--- +# Use Semantic Versioning Semantic versioning is a convention in which "version numbers and the way they change convey meaning about the underlying code and what has been modified from one diff --git a/docs/JLBP-4.md b/docs/JLBP-0004.md similarity index 89% rename from docs/JLBP-4.md rename to docs/JLBP-0004.md index 0880c23e23..4f9e0ab113 100644 --- a/docs/JLBP-4.md +++ b/docs/JLBP-0004.md @@ -1,14 +1,19 @@ -# [JLBP-4] Avoid dependencies on unstable libraries and features +--- +jlbp: + id: JLBP-4 +permalink: /JLBP-4 +--- +# Avoid dependencies on unstable libraries and features Do not depend on libraries that are pre-1.0 or on unstable features in libraries that are 1.0 or later. Unstable libraries allow breaking changes to their public APIs within the same major version. For libraries following semantic -versioning, this means libraries with a 0.x.y version. See [JLBP-3](JLBP-3.md) +versioning, this means libraries with a 0.x.y version. See [JLBP-3](JLBP-0003.md) for more details on semantic versioning. Unstable features within an otherwise stable library are marked with an annotation such as `@Beta`. See -[JLBP-3](JLBP-3.md) for more details on annotating unstable features. +[JLBP-3](JLBP-0003.md) for more details on annotating unstable features. If your library depends on an unstable library or feature which experiences a breaking change between versions, your library is locked to diff --git a/docs/JLBP-5.md b/docs/JLBP-0005.md similarity index 95% rename from docs/JLBP-5.md rename to docs/JLBP-0005.md index f1e3bcb5d9..436ade20c3 100644 --- a/docs/JLBP-5.md +++ b/docs/JLBP-0005.md @@ -1,4 +1,9 @@ -# [JLBP-5] Avoid dependencies that overlap classes with other dependencies +--- +jlbp: + id: JLBP-5 +permalink: /JLBP-5 +--- +# Avoid dependencies that overlap classes with other dependencies Definition: When the same fully qualified class name is provided by two or more distinct artifacts (different group IDs, different diff --git a/docs/JLBP-6.md b/docs/JLBP-0006.md similarity index 98% rename from docs/JLBP-6.md rename to docs/JLBP-0006.md index c471217a88..1092cb25c2 100644 --- a/docs/JLBP-6.md +++ b/docs/JLBP-0006.md @@ -1,4 +1,9 @@ -# [JLBP-6] Rename artifacts and packages together +--- +jlbp: + id: JLBP-6 +permalink: /JLBP-6 +--- +# Rename artifacts and packages together When a library B in Java depends on another library A through the Maven repository system, library B needs two identifiers to find classes in library A: @@ -45,7 +50,7 @@ Recommendations: - Whether or not you make breaking changes, don't publish the same classes under multiple Maven IDs; this creates a situation where artifacts have "overlapping classes." Another best practice, - [JLBP-5](JLBP-5.md), covers how consumers need to handle such problematic + [JLBP-5](JLBP-0005.md), covers how consumers need to handle such problematic scenarios — don't create new cases! - Corollary 1: Once you have published under a particular Maven ID, you are diff --git a/docs/JLBP-7.md b/docs/JLBP-0007.md similarity index 92% rename from docs/JLBP-7.md rename to docs/JLBP-0007.md index d32a9cb274..b6aa37bb84 100644 --- a/docs/JLBP-7.md +++ b/docs/JLBP-0007.md @@ -1,7 +1,12 @@ -# [JLBP-7] Make breaking transitions easy +--- +jlbp: + id: JLBP-7 +permalink: /JLBP-7 +--- +# Make breaking transitions easy When a library makes an in-place breaking change (meaning that the Java package -is not renamed - see [JLBP-6](JLBP-6.md) for more discussion on renaming rules), +is not renamed - see [JLBP-6](JLBP-0006.md) for more discussion on renaming rules), this can create a lot of work for consumers to adapt to the change. If a change is "atomic" (meaning that the old version of something like a method is removed at the same time the new version is added), all usages of the old method must be diff --git a/docs/JLBP-8.md b/docs/JLBP-0008.md similarity index 85% rename from docs/JLBP-8.md rename to docs/JLBP-0008.md index b9cbbfffbf..330002d2c8 100644 --- a/docs/JLBP-8.md +++ b/docs/JLBP-0008.md @@ -1,10 +1,15 @@ -# [JLBP-8] Advance widely used functionality to a stable version +--- +jlbp: + id: JLBP-8 +permalink: /JLBP-8 +--- +# Advance widely used functionality to a stable version Libraries at 0.x versions and unstable features (which should be marked with annotations if they live in a stable library, as outlined in -[JLBP-3](JLBP-3.md)) make no promises about stability. If they become widely +[JLBP-3](JLBP-0003.md)) make no promises about stability. If they become widely used, they can cause problems when there are surface breakages (which is allowed -per the rules of unstable functionality, explained in [JLBP-3](JLBP-3.md)). If +per the rules of unstable functionality, explained in [JLBP-3](JLBP-0003.md)). If such breakages can cause widespread pain, the unstable features can become de facto GA. Promote widely-used unstable libraries and features to 1.0 and commit to thier APIs, even if the functionality is not complete. @@ -12,7 +17,7 @@ Stability is not about completeness but about guarantees not to break users' code frequently. If the surface needs to change before it stabilizes, follow the process in -[JLBP-7](JLBP-7.md) to minimize disruption to the ecosystem. (TL;DR: Mark the old +[JLBP-7](JLBP-0007.md) to minimize disruption to the ecosystem. (TL;DR: Mark the old surface `@Deprecated` and add the new surface in phase 1, delete the old surface in phase 2). However, if it would take a long time for the ecosystem to complete phase 2 (remove all references to the old surface), consider promoting the diff --git a/docs/JLBP-9.md b/docs/JLBP-0009.md similarity index 92% rename from docs/JLBP-9.md rename to docs/JLBP-0009.md index 9f7f8fb140..be584bffb1 100644 --- a/docs/JLBP-9.md +++ b/docs/JLBP-0009.md @@ -1,4 +1,9 @@ -# [JLBP-9] Support the minimum Java version of your consumers +--- +jlbp: + id: JLBP-9 +permalink: /JLBP-9 +--- +# Support the minimum Java version of your consumers Imagine that library B depends on library A and both work with Java 8. If library A releases a new version that requires Java 11, library B cannot upgrade diff --git a/docs/JLBP-10.md b/docs/JLBP-0010.md similarity index 96% rename from docs/JLBP-10.md rename to docs/JLBP-0010.md index cb272464f2..035df36b69 100644 --- a/docs/JLBP-10.md +++ b/docs/JLBP-0010.md @@ -1,4 +1,9 @@ -# [JLBP-10] Maintain API stability as long as needed for consumers +--- +jlbp: + id: JLBP-10 +permalink: /JLBP-10 +--- +# Maintain API stability as long as needed for consumers Every breaking change that consumers must incorporate into their own code incurs a cost to them. There is the immediate cost of the consumers who are forced to diff --git a/docs/JLBP-11.md b/docs/JLBP-0011.md similarity index 94% rename from docs/JLBP-11.md rename to docs/JLBP-0011.md index d1edc0885c..d28349037c 100644 --- a/docs/JLBP-11.md +++ b/docs/JLBP-0011.md @@ -1,4 +1,9 @@ -# [JLBP-11] Keep dependencies up to date +--- +jlbp: + id: JLBP-11 +permalink: /JLBP-11 +--- +# Keep dependencies up to date Release no later than 6 weeks after any of your dependencies releases a higher version. Time is important, not just how many versions behind, diff --git a/docs/JLBP-12.md b/docs/JLBP-0012.md similarity index 90% rename from docs/JLBP-12.md rename to docs/JLBP-0012.md index 020b2ba1e9..e7a92f4f6a 100644 --- a/docs/JLBP-12.md +++ b/docs/JLBP-0012.md @@ -1,4 +1,9 @@ -# [JLBP-12] Make level of support and API stability clear +--- +jlbp: + id: JLBP-12 +permalink: /JLBP-12 +--- +# Make level of support and API stability clear Document the lifecycle status and corresponding level of support of the library. Examples include: diff --git a/docs/JLBP-13.md b/docs/JLBP-0013.md similarity index 90% rename from docs/JLBP-13.md rename to docs/JLBP-0013.md index f778c49cd3..dac40b5c4b 100644 --- a/docs/JLBP-13.md +++ b/docs/JLBP-0013.md @@ -1,4 +1,9 @@ -# [JLBP-13] Quickly remove references to deprecated features in dependencies +--- +jlbp: + id: JLBP-13 +permalink: /JLBP-13 +--- +# Quickly remove references to deprecated features in dependencies The earlier you remove usages of external deprecated functionality, the more versions of your product will work with your dependency once the diff --git a/docs/JLBP-14.md b/docs/JLBP-0014.md similarity index 97% rename from docs/JLBP-14.md rename to docs/JLBP-0014.md index f224c7f820..13537ebe56 100644 --- a/docs/JLBP-14.md +++ b/docs/JLBP-0014.md @@ -1,4 +1,9 @@ -# [JLBP-14] Specify a single, overridable version of each dependency +--- +jlbp: + id: JLBP-14 +permalink: /JLBP-14 +--- +# Specify a single, overridable version of each dependency Give the version of each dependency as a single value such as `2.3`. Do not use a Maven range such as `[2.3,2.9]`, `[2.3,)`, or even `[2.3]`. diff --git a/docs/JLBP-15.md b/docs/JLBP-0015.md similarity index 96% rename from docs/JLBP-15.md rename to docs/JLBP-0015.md index 51287e9f99..5fca7aa31d 100644 --- a/docs/JLBP-15.md +++ b/docs/JLBP-0015.md @@ -1,4 +1,9 @@ -# [JLBP-15] Publish a BOM for multi-module projects +--- +jlbp: + id: JLBP-15 +permalink: /JLBP-15 +--- +# Publish a BOM for multi-module projects A [BOM](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html) enables consumers of a library to select diff --git a/docs/JLBP-16.md b/docs/JLBP-0016.md similarity index 94% rename from docs/JLBP-16.md rename to docs/JLBP-0016.md index ae20f21d52..9b27fa1263 100644 --- a/docs/JLBP-16.md +++ b/docs/JLBP-0016.md @@ -1,7 +1,12 @@ -# [JLBP-16] Ensure upper version alignment of dependencies for consumers +--- +jlbp: + id: JLBP-16 +permalink: /JLBP-16 +--- +# Ensure upper version alignment of dependencies for consumers For multi-module projects, this best practice assumes you have already applied -[JLBP-15](JLBP-15.md), so that your project has a BOM. +[JLBP-15](JLBP-0015.md), so that your project has a BOM. Upper version alignment is defined in the [glossary](glossary.md). diff --git a/docs/JLBP-17.md b/docs/JLBP-0017.md similarity index 93% rename from docs/JLBP-17.md rename to docs/JLBP-0017.md index 72f7ee8dec..249eabe7b5 100644 --- a/docs/JLBP-17.md +++ b/docs/JLBP-0017.md @@ -1,4 +1,9 @@ -# [JLBP-17] Coordinate rollout of breaking changes +--- +jlbp: + id: JLBP-17 +permalink: /JLBP-17 +--- +# Coordinate rollout of breaking changes When a library introduces a breaking change, consumers can't update to that version until all their other dependencies which also use @@ -10,8 +15,7 @@ Perform the rollout in this manner: 1. Decide whether to introduce the incompatibility in a single release or make the change in two phases. - - The two-phase approach is described in [JLBP-7: Make breaking transitions - easy](JLBP-7.md). + - The two-phase approach is described in [JLBP-7: Make breaking transitions easy](JLBP-0007.md). - If the feature is used by stable code in other libraries, you must use the two-phase approach, except for the types of changes where this is impossible (see below). @@ -36,7 +40,7 @@ Perform the rollout in this manner: - To use the two-phase approach, mark the undesired surface as `@Deprecated` and release. Make sure that all consuming libraries have removed their references to the deprecated functionality. This invokes - [JLBP-13](JLBP-13.md) for consuming libraries. + [JLBP-13](JLBP-0013.md) for consuming libraries. 3. Release the incompatible version and make sure that the version propagates up the dependency tree as quickly as possible. In the case of in-place breakage, diff --git a/docs/JLBP-18.md b/docs/JLBP-0018.md similarity index 95% rename from docs/JLBP-18.md rename to docs/JLBP-0018.md index 551ecd197f..98a052e9a5 100644 --- a/docs/JLBP-18.md +++ b/docs/JLBP-0018.md @@ -1,4 +1,9 @@ -# [JLBP-18] Only shade dependencies as a last resort +--- +jlbp: + id: JLBP-18 +permalink: /JLBP-18 +--- +# Only shade dependencies as a last resort Shading is a process where a dependency is relocated to a different Java package and copied into the same jar as the code that relies on that dependency. @@ -26,7 +31,7 @@ There are a number of problems with shading: of some constants. - It is easy to accidentally fail to relocate classes or other files, resulting in an artifact that overlaps classes and files with the original dependency - (creating the situation described in [JLBP-5](JLBP-5.md)). + (creating the situation described in [JLBP-5](JLBP-0005.md)). - Shading violates many closed source licenses. If the license contains language such as "You must not reverse engineer, decompile, disassemble, modify, or translate the Software", you should consult an attorney before diff --git a/docs/JLBP-19.md b/docs/JLBP-0019.md similarity index 96% rename from docs/JLBP-19.md rename to docs/JLBP-0019.md index 32850104a7..d297dd1b5b 100644 --- a/docs/JLBP-19.md +++ b/docs/JLBP-0019.md @@ -1,4 +1,9 @@ -# [JLBP-19] Place each package in only one module +--- +jlbp: + id: JLBP-19 +permalink: /JLBP-19 +--- +# Place each package in only one module All classes from the same Java package must be in one and only one JAR file in the classpath. diff --git a/docs/JLBP-20.md b/docs/JLBP-0020.md similarity index 95% rename from docs/JLBP-20.md rename to docs/JLBP-0020.md index 9fc5428959..e2e3247265 100644 --- a/docs/JLBP-20.md +++ b/docs/JLBP-0020.md @@ -1,4 +1,9 @@ -# [JLBP-20] Give each jar a module name +--- +jlbp: + id: JLBP-20 +permalink: /JLBP-20 +--- +# Give each jar a module name For compatibility with the Java Platform Module System (JPMS) in Java 9 and later, every JAR you publish should have a module name, even if the library diff --git a/docs/README.md b/docs/README.md index 4a0b196f46..30186d448e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,6 @@ --- -page.title: Google Best Practices for Java Libraries +page: + title: Google Best Practices for Java Libraries permalink: / --- @@ -14,32 +15,18 @@ Java libraries with fewer dependency conflicts and other kinds of problems. The list is open-ended, so new ones may be added from time to time. ## Best practices -- [JLBP-1](JLBP-1.md): Minimize dependencies -- [JLBP-2](JLBP-2.md): Minimize API surface -- [JLBP-3](JLBP-3.md): Use semantic versioning -- [JLBP-4](JLBP-4.md): Avoid dependencies on unstable libraries and features -- [JLBP-5](JLBP-5.md): Avoid dependencies that overlap classes with other - dependencies -- [JLBP-6](JLBP-6.md): Rename artifacts and packages together -- [JLBP-7](JLBP-7.md): Make breaking transitions easy -- [JLBP-8](JLBP-8.md): Advance widely used functionality to a stable version -- [JLBP-9](JLBP-9.md): Support the minimum Java version of your consumers -- [JLBP-10](JLBP-10.md): Maintain API stability as long as needed for consumers -- [JLBP-11](JLBP-11.md): Keep dependencies up to date -- [JLBP-12](JLBP-12.md): Make level of support and API stability clear -- [JLBP-13](JLBP-13.md): Quickly remove references to deprecated features in - dependencies -- [JLBP-14](JLBP-14.md): Specify a single, overridable version of each dependency -- [JLBP-15](JLBP-15.md): Produce a BOM for multi-module projects -- [JLBP-16](JLBP-16.md): Ensure upper version alignment of dependencies for - consumers -- [JLBP-17](JLBP-17.md): Coordinate rollout of breaking changes -- [JLBP-18](JLBP-18.md): Only shade dependencies as a last resort -- [JLBP-19](JLBP-19.md): Place each package in only one module -- [JLBP-20](JLBP-20.md): Give each jar a module name - -## Introductory material and reference -- [What is a diamond dependency conflict?](what-is-a-diamond-dependency-conflict.md) -- [Why doesn't the compiler catch diamond dependency conflicts?](why-doesnt-the-compiler-catch-diamond-dependency-conficts.md) + +{% for p in site.pages %}{% if p.jlbp -%} +- [{{ p.jlbp.id }}]({{ p.url | relative_url }}): {{ p.title }} +{% endif %}{% endfor -%} + +## Concepts + +{% for p in site.pages %}{% if p.concepts -%} +- [{{ p.title}}]({{ p.url | relative_url }}) +{% endif %}{% endfor -%} + +## Reference + - [Glossary](glossary.md): Terms used in the best practices and other places in cloud-opensource-java. diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html index af7e667251..0110830f69 100644 --- a/docs/_layouts/default.html +++ b/docs/_layouts/default.html @@ -1,6 +1,9 @@
+