---
name: java-sdk-validation
description: Authoritative checks for reviewing Java code that targets the Azure SDK for Java — verifies modern `com.azure:*` artifacts (rejecting legacy `com.microsoft.azure:*`), `com.azure.identity` token-based auth, correct client construction, async/Reactor usage, and pom.xml/build.gradle hygiene. Use this skill whenever you are reviewing, grading, or critiquing Java code that touches Azure services — even short snippets, single-file samples, or prompts that only mention "Azure" and Java/Maven/Gradle without naming the SDK. Apply it before scoring or commenting so legacy-SDK and anti-pattern violations are caught on the first pass.
---

# 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 category fails.
4. If a check cannot be determined from the available code (e.g., no pom.xml present), mark it as `"skipped"` with a reason.

## Checks

### 1. Dependency Checks (pom.xml / build.gradle)

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:
- Java source/target version is 8 or above (17 preferred for new projects)
- No `com.microsoft.azure` groupId appears anywhere in dependency declarations

### 2. Import Checks

Scan all `.java` files for import statements:

- **Pass**: imports from `com.azure.*` packages (e.g., `com.azure.storage.blob`, `com.azure.identity`, `com.azure.cosmos`)
- **Fail**: imports from `com.microsoft.azure.*` (legacy SDK)
- **Fail**: imports from `com.azure.*.implementation.*` (internal packages not meant for public use)

### 3. Authentication Pattern

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.

- **Pass**: Uses `DefaultAzureCredential` or another `com.azure.identity` credential class
- **Pass**: Reads endpoint/vault URL from environment variable
- **Fail**: Hardcoded connection strings (e.g., `DefaultEndpointsProtocol=https;AccountName=...`)
- **Fail**: Hardcoded account keys, SAS tokens, client secrets, or certificates in source code
- **Fail**: Uses `StorageCredentialsAccountAndKey` or `ConnectionStringBuilder` (legacy patterns)

### 4. Client Construction

Azure SDK for Java v12+ uses the builder pattern for all clients:

- **Pass**: Uses `*ClientBuilder` classes (e.g., `BlobServiceClientBuilder`, `CosmosClientBuilder`, `SecretClientBuilder`, `ServiceBusClientBuilder`)
- **Pass**: Builder chain includes `.endpoint()` or `.vaultUrl()` and `.credential()`
- **Fail**: Uses legacy client constructors (`CloudStorageAccount`, `DocumentClient`, `KeyVaultClient`, `QueueClient`)

### 5. Deprecated / Legacy Class Anti-Patterns

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` |

### 6. Pagination & Collection Return Types

Azure SDK for Java has dedicated types for paginated responses. Raw `List` or `Stream` returns are incorrect.

- **Pass**: Sync methods return `PagedIterable<T>` (or use `iterableByPage()` for page-level iteration)
- **Pass**: Async methods return `PagedFlux<T>` (with `.byPage()` support)
- **Fail**: Returns raw `List<T>`, `Stream<T>`, or `Iterator<T>` from list/query operations
- **Fail**: Flattens all pages into memory at once (defeats pagination purpose)

If no collection/list methods exist, mark this check as `"not_applicable"`.

### 7. Long-Running Operations (LROs)

Azure SDK for Java uses `SyncPoller<T, U>` and `PollerFlux<T, U>` for long-running operations. Methods that start LROs are prefixed with `begin`.

- **Pass**: LRO methods use `SyncPoller` (sync) or `PollerFlux` (async)
- **Pass**: Method names start with `begin` (e.g., `beginDeleteSecret()`, `beginAnalyze()`)
- **Fail**: Fire-and-forget calls without waiting for completion (e.g., `deleteSecret()` then immediately recreate)
- **Fail**: Manual `Thread.sleep()` polling loops instead of using the SDK's poller types

If no LROs exist, mark this check as `"not_applicable"`.

### 8. Async Implementation Quality

Azure SDK for Java uses Project Reactor for async operations. If async code is present:

- **Pass**: Uses Reactor types (`Mono<T>`, `Flux<T>`) from `reactor.core.publisher`
- **Pass**: Uses async client variants (`BlobAsyncClient`, `CosmosAsyncClient`, `SecretAsyncClient`, etc.)
- **Pass**: Sync clients internally use sync-over-async (this is the SDK's design, not the user's problem)
- **Fail**: Uses `CompletableFuture` for Azure SDK async operations (wrong — Azure SDK Java uses Reactor, not `CompletableFuture`)
- **Fail**: Uses RxJava types (`Observable`, `Single`, `Completable`) — Azure SDK Java uses Reactor, not RxJava
- **Fail**: Wraps sync client in a thread pool / `ExecutorService` to simulate async
- **Fail**: Calls `.block()` inside an async service implementation (defeats the purpose of reactive)

If no async code is present, mark this check as `"not_applicable"`.

### 9. Error Handling

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` |

- **Pass**: Catches service-specific exceptions
- **Weaker**: Catches only generic `Exception` or `RuntimeException` (not a hard fail, but note it)

### 10. Build Verification

If a build system is present:
- **pom.xml**: Run `mvn compile` (do NOT run tests)
- **build.gradle** / **build.gradle.kts**: Run `gradle compileJava`
- Report whether compilation succeeds or fails with error details

## Process

1. Identify all generated Java source files and build files (pom.xml, build.gradle).
2. Run each check (1–10) against the generated code.
3. For each check, record pass/fail/skipped with specific evidence (line numbers, class names, package names).
4. If build verification is possible, attempt it and record the result.
5. Produce the structured JSON output.

## Output Format

```json
{
  "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"]
  }
}
```

## Important Reminders

- This skill validates **Java Azure SDK conventions only**. Do not evaluate general Java code quality, formatting, or style.
- The `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`).
- Connection strings work but are the wrong pattern for production. `DefaultAzureCredential` with managed identity is the correct approach.
- If both sync and async implementations are present, validate each independently.
