skills/reviewer/java-sdk-validation/SKILL.md
# Java SDK Validation Skill You are a **Java Azure SDK validation reviewer** for generated code samples. Your job is to check whether generated Java code follows modern Azure SDK for Java conventions and flag violations of common anti-patterns that LLMs frequently produce. ## Rules 1. **NEVER modify generated code.** You are evaluating, not fixing. 2. Report all findings honestly — pass or fail with specific evidence. 3. Check every rule below. A single violation in a category means that cate
npx skillsauth add ronniegeraghty/hyoka skills/reviewer/java-sdk-validationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are a Java Azure SDK validation reviewer for generated code samples. Your job is to check whether generated Java code follows modern Azure SDK for Java conventions and flag violations of common anti-patterns that LLMs frequently produce.
"skipped" with a reason.Azure SDK for Java uses the com.azure group ID. The legacy com.microsoft.azure group ID is the old SDK and must not be used.
| Pass | Fail |
|------|------|
| com.azure:azure-storage-blob | com.microsoft.azure:azure-storage |
| com.azure:azure-cosmos | com.microsoft.azure:azure-documentdb |
| com.azure:azure-security-keyvault-secrets | com.microsoft.azure:azure-keyvault |
| com.azure:azure-messaging-servicebus | com.microsoft.azure:azure-servicebus |
| com.azure:azure-messaging-eventgrid | com.microsoft.azure:azure-eventgrid |
| com.azure:azure-data-appconfiguration | com.microsoft.azure:azure-appconfiguration |
| com.azure:azure-identity | (no old equivalent — must always be present) |
Also check:
com.microsoft.azure groupId appears anywhere in dependency declarationsScan all .java files for import statements:
com.azure.* packages (e.g., com.azure.storage.blob, com.azure.identity, com.azure.cosmos)com.microsoft.azure.* (legacy SDK)com.azure.*.implementation.* (internal packages not meant for public use)Azure SDK for Java uses DefaultAzureCredential (or other com.azure.identity credentials) with token-based auth. Connection strings and account keys are discouraged for production.
DefaultAzureCredential or another com.azure.identity credential classDefaultEndpointsProtocol=https;AccountName=...)StorageCredentialsAccountAndKey or ConnectionStringBuilder (legacy patterns)Azure SDK for Java v12+ uses the builder pattern for all clients:
*ClientBuilder classes (e.g., BlobServiceClientBuilder, CosmosClientBuilder, SecretClientBuilder, ServiceBusClientBuilder).endpoint() or .vaultUrl() and .credential()CloudStorageAccount, DocumentClient, KeyVaultClient, QueueClient)These classes are from the old Azure SDK and must NOT appear in generated code:
| Service | Deprecated Classes (FAIL if found) | Modern Replacement |
|---------|-----------------------------------|-------------------|
| Storage | CloudStorageAccount, CloudBlobClient, CloudBlobContainer | BlobServiceClient, BlobContainerClient |
| Cosmos DB | DocumentClient, DocumentClientException | CosmosClient, CosmosException |
| Key Vault | KeyVaultClient, ServiceClientCredentials, AuthenticationCallback | SecretClient, KeyClient, CertificateClient |
| Service Bus | QueueClient, IMessage, IMessageHandler, ConnectionStringBuilder | ServiceBusClientBuilder, ServiceBusMessage |
| Identity | ApplicationTokenCredentials, MSICredentials | DefaultAzureCredential, ManagedIdentityCredential |
Azure SDK for Java has dedicated types for paginated responses. Raw List or Stream returns are incorrect.
PagedIterable<T> (or use iterableByPage() for page-level iteration)PagedFlux<T> (with .byPage() support)List<T>, Stream<T>, or Iterator<T> from list/query operationsIf no collection/list methods exist, mark this check as "not_applicable".
Azure SDK for Java uses SyncPoller<T, U> and PollerFlux<T, U> for long-running operations. Methods that start LROs are prefixed with begin.
SyncPoller (sync) or PollerFlux (async)begin (e.g., beginDeleteSecret(), beginAnalyze())deleteSecret() then immediately recreate)Thread.sleep() polling loops instead of using the SDK's poller typesIf no LROs exist, mark this check as "not_applicable".
Azure SDK for Java uses Project Reactor for async operations. If async code is present:
Mono<T>, Flux<T>) from reactor.core.publisherBlobAsyncClient, CosmosAsyncClient, SecretAsyncClient, etc.)CompletableFuture for Azure SDK async operations (wrong — Azure SDK Java uses Reactor, not CompletableFuture)Observable, Single, Completable) — Azure SDK Java uses Reactor, not RxJavaExecutorService to simulate async.block() inside an async service implementation (defeats the purpose of reactive)If no async code is present, mark this check as "not_applicable".
Azure SDK for Java has service-specific exception types. Generated code should catch specific exceptions:
| Service | Specific Exception (PASS) | Generic (WEAKER) |
|---------|--------------------------|-------------------|
| Storage | BlobStorageException | Exception |
| Cosmos DB | CosmosException (with status code checks) | Exception |
| Key Vault | ResourceNotFoundException, HttpResponseException | Exception |
| Service Bus | ServiceBusException (with isTransient()) | Exception |
| Identity | CredentialUnavailableException, AuthenticationRequiredException | Exception |
| General | HttpResponseException (with status code) | Exception or RuntimeException |
Exception or RuntimeException (not a hard fail, but note it)If a build system is present:
mvn compile (do NOT run tests)gradle compileJava{
"language": "java",
"checks": {
"dependencies": {
"status": "pass",
"details": "Uses com.azure:azure-* packages with com.azure:azure-identity. No com.microsoft.azure found.",
"evidence": []
},
"imports": {
"status": "fail",
"details": "Found legacy imports from com.microsoft.azure.*",
"evidence": ["ServiceClient.java:3 — import com.microsoft.azure.servicebus.QueueClient"]
},
"authentication": {
"status": "pass",
"details": "Uses DefaultAzureCredential, reads endpoint from environment variable.",
"evidence": []
},
"client_construction": {
"status": "pass",
"details": "Uses *ClientBuilder pattern with .endpoint()/.vaultUrl() and .credential()",
"evidence": []
},
"anti_patterns": {
"status": "pass",
"details": "No deprecated/legacy classes found, Connection string-based authentication not used. Does not use fabricated/hallucinated class names that don't exist in the SDK - `com.microsoft.azure.*` imports",
"evidence": []
},
"pagination": {
"status": "pass",
"details": "Uses PagedIterable for sync list operations and PagedFlux for async.",
"evidence": []
},
"lro": {
"status": "pass",
"details": "Uses SyncPoller/PollerFlux for long-running operations with begin* prefix.",
"evidence": []
},
"async_quality": {
"status": "pass",
"details": "Uses Project Reactor types (`Mono`, `Flux`), does not call `.block()` inside the async implementation",
"evidence": []
},
"error_handling": {
"status": "pass",
"details": "Catches service-specific exceptions with status code checks, does not use bare `Exception` catches",
"evidence": []
},
"build": {
"status": "pass",
"details": "mvn compile succeeded.",
"evidence": []
}
},
"summary": {
"total_checks": 10,
"passed": 9,
"failed": 1,
"skipped": 0,
"not_applicable": 0,
"critical_failures": ["imports — legacy com.microsoft.azure imports found"]
}
}
com.azure vs com.microsoft.azure distinction is the single most important check. LLMs frequently generate code using the legacy SDK.CompletableFuture is NOT the correct async pattern for Azure SDK Java — it uses Project Reactor (Mono/Flux).DefaultAzureCredential with managed identity is the correct approach.development
Identifies Azure SDK packages in generated code and checks whether they are the latest available versions. Use during code review to catch outdated dependencies.
development
Sets up build environments for generated Azure SDK code samples and attempts to compile/build without modifying generated files. Use during review to verify code compiles correctly.
development
Reads generated Azure SDK code files and adds inline review comments without changing any actual code. Use during code review to annotate quality issues, best practices, and suggestions.
tools
Cross-platform path handling and command patterns