aws-sdk-java-v2
AGENTS.md2.6k starsChanged 6 days agoApache-2.0View on GitHub
This is the AWS SDK for Java 2.x: service clients generated at build time from AWS service models, plus the hand-written core runtime, HTTP clients, and high-level libraries they run on. The files under docs/guidelines/ add depth, and each section says when to read one. The Maven reactor has about 500 modules. Run Maven through ./mvnw from the repository root, scoped with -pl to the modules you changed. Files under any target/generated-sources/ directory are regenerated by every build, so an…
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,439 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
The file
Show its rules and text
We split this AGENTS.md into the rules it gives an agent
18 rules. About 0 are common, 3 are distinctive, and 15 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
15
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 18
Use -P quick only to build dependencies, never to verify a change: it skips unit tests, Checkstyle, SpotBugs, and japicmp and still reports …
- Very specific: line 20
If the single-class run or the final check cannot resolve bom-internal, run the dependency build with -pl bom-internal first.
- Very specific: line 21
If the build fails with Attempted to clobber existing file, a target/ directory holds stale generated sources, for example after switching …
- Very specific: line 40
Test the behavior of generated clients with a functional test in test/codegen-generated-classes-test, which generates clients from the test …
- Very specific: line 45
Put new types in an internal package and annotate them @SdkInternalApi, and make a fix in internal code when it can live there.
- Very specific: line 46
Use the SDK's utilities instead of a new dependency or a hand-written version: JsonNodeParser (core/json-utils) for JSON, Lazy and …
- Very specific: line 49
Do not use Optional for parameters, fields, values that are never null, or getters on generated model classes.
- Very specific: line 54
Every public API has Javadoc: a one-sentence summary first, in third person ("Returns the..."), and <p> with no closing tag at the start of …
- Very specific: line 63
Every behavior change comes with a new or updated unit test in the changed module's src/test/java.
- Very specific: line 64
Use JUnit 5 with AssertJ and Mockito, and WireMock to stub HTTP responses, as …
- Very specific: line 67
Keep test-only constructors and methods package-private, and annotate them @SdkTestInternalApi (core/annotations).
- Very specific: line 68
Prefer unit and functional tests that mock dependencies with Mockito or stub HTTP responses with WireMock over integration tests …
- Distinctive: line 69
Check that each test of new behavior fails without your change.
- Very specific: line 73
Never log, or put in toString() or an exception message, credentials, HTTP header values, or members modeled as sensitive.
- Distinctive: line 78
Before opening a pull request, run the final check on every module you changed.
- Very specific: line 80
Do not write the pull request description.
- Distinctive: line 83
Add a changelog entry, as described next.
- Very specific: line 87
Every change customers can observe needs an entry in .changes/next-release/, including a change made only in customization.config.
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md
This is the AWS SDK for Java 2.x: service clients generated at build time from AWS service models, plus the hand-written core runtime, HTTP clients, and high-level libraries they run on. The files under docs/guidelines/ add depth, and each section says when to read one.
Build and test commands
The Maven reactor has about 500 modules. Run Maven through ./mvnw from the repository root, scoped with -pl to the modules you changed.
| Step | Command |
| Dependency build: the module and the modules it depends on, without checks or tests. Run it once, and again after changing an upstream module. | ./mvnw -pl <module> -am -P quick install |
| Single-class run, while iterating | ./mvnw -pl <module> -Dtest=<TestClass> -DfailIfNoTests=true -Dmaven.javadoc.skip=true -Dspotbugs.skip=true test |
| Final check, after your last edit | ./mvnw -pl <changed modules> install |
<changed modules>is a comma-separated list of every module you edited, including upstream ones such asutilsorcore/sdk-core, because the dependency build skips their checks and tests. After autilsorcore/*change, also add the modules that call the changed code.- The final check runs all of the module's unit tests, not just the class you iterated on, so it catches failures in other test classes that your change affects. It also runs Checkstyle, dependency analysis, japicmp, and SpotBugs where the build enables it.
- On JDK 17 the build skips SpotBugs because it is slow there. To check it before opening a pull request, run
./mvnw -pl <module> -Dspotbugs.skip=false process-classes. - Use
-P quickonly to build dependencies, never to verify a change: it skips unit tests, Checkstyle, SpotBugs, and japicmp and still reportsBUILD SUCCESS. Do not runinstallortestfrom the root without-pl. - Build with
install, notcompileortest: modules depend on shaded jars that exist only afterpackage. - If the single-class run or the final check cannot resolve
bom-internal, run the dependency build with-pl bom-internalfirst. - If the build fails with
Attempted to clobber existing file, atarget/directory holds stale generated sources, for example after switching branches. Addcleanbeforeinstalland rerun. - The final check and the single-class run on
services/*,services-custom/*, andtest/*build clients that need a region and credentials. Nothing calls AWS, so placeholders work: prefix the command withAWS_REGION=us-west-2 AWS_ACCESS_KEY_ID=akid AWS_SECRET_ACCESS_KEY=skid. Leave the two credential variables off any run that includescore/auth, whose tests expect them unset; runcore/authin its own final check. - The commands in
README.mdandCONTRIBUTING.mdbuild the whole tree, skip checks with-P quick, or usemvninstead of./mvnw. Use the ones in this section.
Generated code
Files under any target/generated-sources/ directory are regenerated by every build, so an edit there is lost. Never edit them. Change what generates them:
- Service clients and models: the generator in
codegen/turns eachservices/<service>module'ssrc/main/resources/codegen-resources/files into itstarget/generated-sources/sdk. Do not edit any file in those servicecodegen-resources/directories exceptcustomization.config: release automation replaces the others with each service's published model. customization.configis maintained by hand and is the place to adjust one service's generated code. The options it can set are the fields ofcodegen/src/main/java/software/amazon/awssdk/codegen/model/config/customization/CustomizationConfig.java.- Hand-written code that a generated client calls, such as the execution interceptors listed under
interceptorsincustomization.config, lives in the module'ssrc/main/java, usually in aninternalpackage. Edit it directly. core/regionsandcore/aws-core: the generators incodegen-lite/. Their inputscore/regions/src/main/resources/software/amazon/awssdk/regions/internal/region/endpoints.jsonandcore/aws-core/src/main/resources/software/amazon/awssdk/awscore/internal/defaults/sdk-default-configuration.jsonare replaced by release automation; do not edit them.core/sdk-core: theVersionInfo.java.vmtemplate in that module.
Code generator
A change in codegen/ changes every service client. To fix code that every service generates, change the generator rather than one service. Before changing codegen/, read docs/guidelines/code-generation-guidelines.md.
- JavaPoet specs are under
codegen/src/main/java/software/amazon/awssdk/codegen/poet/. A new generated class gets@GeneratedfromPoetUtils.generatedAnnotation(). - Test the behavior of generated clients with a functional test in
test/codegen-generated-classes-test, which generates clients from the test models in itssrc/main/resources/codegen-resources/. Those models are maintained by hand, so edit or add them as the test needs. Marshalling tests for each protocol live intest/protocol-tests. - To verify a change, run the dependency build for one affected
services/<service>module andtest/codegen-generated-classes-test, which installs yourcodegenchange for the code generator plugin, then the final check oncodegen, that service module, andtest/codegen-generated-classes-testwith the placeholder region and credentials above. When generated output changes on purpose, update the expected-output fixtures that thecodegentests compare against.
Code conventions
- Put new types in an
internalpackage and annotate them@SdkInternalApi, and make a fix ininternalcode when it can live there. Add@SdkPublicApior@SdkProtectedApitypes only when the change cannot be made without them. - Use the SDK's utilities instead of a new dependency or a hand-written version:
JsonNodeParser(core/json-utils) for JSON,LazyandCachedSupplier(utils) for lazy and TTL-cached values,Validatefor argument checks, andToStringfortoString(). - Argument and configuration checks use
Validate, which throwsIllegalArgumentExceptionorNullPointerException. Failures at request time throwSdkClientExceptionor anotherSdkExceptionsubtype. Do not throw checked exceptions from public APIs, and do not catch an exception only to rethrow the same type. Messages say what went wrong and how to fix it. Before adding or changing exception handling or a public value class, readdocs/guidelines/aws-sdk-java-v2-general.md. - Log through
software.amazon.awssdk.utils.Logger(private static final Logger logger = Logger.loggerFor(MyClass.class);), not SLF4J directly, unless Checkstyle bans it in that module; then use the logger that neighboring code uses. Do not log at WARN or ERROR an error that is also thrown to the caller. Before adding or changing a log statement, readdocs/guidelines/logging-guidelines.md. - Do not use
Optionalfor parameters, fields, values that are never null, or getters on generated model classes. Return it only when a caller could not otherwise tell that the result may be absent. - Public value classes implement
equals,hashCode, andtoStringover all fields and have anEqualsVerifiertest. CompletableFuture: never drop a future that can fail, and handle its failure withexceptionally,handle, orwhenComplete. Do not calljoin()orget()inside a future chain. Pass an executor to every*Asyncmethod. Propagate cancellation withCompletableFutureUtils.forwardExceptionTo, and where a sync path must wait, useCompletableFutureUtils.joinLikeSync. Before changing code that usesCompletableFuture, readdocs/guidelines/async-programming-guidelines.md.- Reactive Streams: build on
SimplePublisher,ByteBufferStoringSubscriber, andSdkPublisherinstead of writing aPublisherorSubscriberfrom scratch. A change to anyPublisherorSubscriberimplementation needs a Reactive Streams TCK test named<ClassName>TckTestin the same package, likeutils/src/test/java/software/amazon/awssdk/utils/async/SimplePublisherTckTest.java. Before changing aPublisherorSubscriber, readdocs/guidelines/reactive-streams-guidelines.md. - Use code comments sparingly. Add one only for a reason the code cannot show, such as a hidden constraint, a subtle invariant, or a workaround for a specific bug, and never to restate what the code does. Javadoc on public API is separate and follows the next rule.
- Every public API has Javadoc: a one-sentence summary first, in third person ("Returns the..."), and
<p>with no closing tag at the start of each later paragraph. Before adding or changing public or protected API, readdocs/guidelines/javadoc-guidelines.md.
API compatibility
- Never remove, rename, or narrow a public or protected member, or change its signature. Add the new form, keep the old one, and mark it
@Deprecatedwith a@deprecatedJavadoc tag that links the replacement. Oninstall, japicmp fails the build for binary-incompatible or source-incompatible changes in the modules it checks;*.internal.*packages are exempt. - Older generated clients call
@SdkProtectedApimembers, so keep them as backward compatible as public API even though customers do not call them directly.
Testing instructions
- Every behavior change comes with a new or updated unit test in the changed module's
src/test/java. Before adding or changing a test, readdocs/guidelines/testing-guidelines.md. - Use JUnit 5 with AssertJ and Mockito, and WireMock to stub HTTP responses, as
services-custom/s3-transfer-manager/src/test/java/software/amazon/awssdk/transfer/s3/internal/DownloadDirectoryRefusedKeyWireMockTest.javadoes. - Name test methods
methodToTest_when_expectedBehavior, for exampleclose_withCustomExecutor_shouldNotCloseCustomExecutor, and name a class that tests one class<ClassName>Test. - On an error path, assert the exception type and part of its message.
- Keep test-only constructors and methods package-private, and annotate them
@SdkTestInternalApi(core/annotations). - Prefer unit and functional tests that mock dependencies with Mockito or stub HTTP responses with WireMock over integration tests (
src/it/java,*IntegrationTest), which call real AWS services. - Check that each test of new behavior fails without your change.
Security considerations
- Never log, or put in
toString()or an exception message, credentials, HTTP header values, or members modeled as sensitive. - Tests use placeholder credentials such as
akidandskid. Never put real credentials in tests or test resources.
Pull request instructions
- Before opening a pull request, run the final check on every module you changed.
- A pull request sourced by AI tools must be reviewed by a person before it is opened.
- Do not write the pull request description. The person opening the pull request writes it from
.github/PULL_REQUEST_TEMPLATE.md. - Work on a branch named
<alias>/<short-kebab-slug>, where the slug describes the change rather than a ticket, and never commit the change tomaster. External contributors push the branch to their own fork. - Write commit messages as Conventional Commits,
<type>: <description>or<type>(<scope>): <description>, with a type such asfix,feat,docs,refactor,test, orchore, and a subject of 50 characters or fewer in the imperative mood with no trailing period. Add a body only when the reason for the change is not obvious from the diff: wrap it at 72 characters and explain the context behind the change. In the rare case that maintainers approve a breaking change, mark it with aBREAKING CHANGE:footer. Pull requests are squash-merged with the title as the commit subject, so the title follows the same format. - Add a changelog entry, as described next.
Changelog entry
Every change customers can observe needs an entry in .changes/next-release/, including a change made only in customization.config. CI enforces this for non-test Java files. Create the entry with scripts/new-change, which writes the JSON file and stages it with git add. Choose the values first:
-c(category): the changed component's own category, as existing entries in.changes/name it. Use the library name for a library, such asS3 Transfer Manager,Amazon DynamoDB Enhanced Client,Netty NIO HTTP Client,Apache HTTP Client, orAWS CRT HTTP Client; the service name for a service module, such asAmazon S3orAmazon DynamoDB; andAWS SDK for Java v2only for core,utils, and codegen changes.-t(type): one ofbugfix,feature,perf-improvement,deprecation,removal,documentation.-d(description): the user-visible behavior change, with no ticket numbers or internal references.
EDITOR=true python3 scripts/new-change -t <type> -c "<category>" -d "<description>"SDK maintainers leave -u out. An external contributor may pass their own GitHub username with -u; never guess one. Without -u the script opens an editor, and EDITOR=true makes that a no-op. The script reads VISUAL before EDITOR, so if VISUAL is set, unset it or set it to true as well.
Guideline files
| Read before changing | File |
| Anything: design principles, SDK utilities, object methods, exceptions | docs/guidelines/aws-sdk-java-v2-general.md |
Code that uses CompletableFuture | docs/guidelines/async-programming-guidelines.md |
A Publisher or Subscriber | docs/guidelines/reactive-streams-guidelines.md |
| Tests | docs/guidelines/testing-guidelines.md |
| Public or protected API documentation | docs/guidelines/javadoc-guidelines.md |
| Logging | docs/guidelines/logging-guidelines.md |
| The code generator | docs/guidelines/code-generation-guidelines.md |
| Class, method, or test names | docs/guidelines/NamingConventions.md |
Code that returns or stores Optional | docs/guidelines/UseOfOptional.md |
| Constructors and factory methods | docs/guidelines/FavorStaticFactoryMethods.md |
| Client or feature configuration classes | docs/guidelines/ClientConfiguration.md |
| Business metrics (user agent feature IDs) | docs/guidelines/business-metrics-guidelines.md |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

