Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions .claude/skills/port-to-jdk21/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
name: port-to-jdk21
description: Port changes from a stage-jdk8-based branch to a stage-based branch, upgrading Java 8 code to Java 21
argument-hint: [source-branch]
allowed-tools: Bash, Read, Edit, Write, Grep, Glob
user-invocable: true
---

# Port Branch Changes from stage-jdk8 (Java 8) to stage (Java 21)

Port changes from the source branch `$ARGUMENTS` (based on `stage-jdk8`) to a new branch based on `stage`.

## Target Branch Naming

The target branch name MUST be derived from the source branch name by removing the `_jdk8` suffix:
- Source: `CLIENT-1234_feature_jdk8` -> Target: `CLIENT-1234_feature`
- If the source branch doesn't have a `_jdk8` suffix, append `_jdk21` to create the target name:
- Source: `bugfix-something` -> Target: `bugfix-something_jdk21`

## Steps

1. **Validate** the source branch `$ARGUMENTS` exists and is based on `stage-jdk8`.
2. **Analyze** the commits on the source branch that are not on `stage-jdk8`:
```
git log --oneline stage-jdk8..$ARGUMENTS
```
3. **Create** the target branch off `stage`:
```
git checkout stage
git pull
git checkout -b <target-branch-name>
```
4. **Cherry-pick** the commits from the source branch onto the target branch. If there are conflicts, resolve them with the Java 21 adaptations listed below.
5. **Adapt** the code for Java 21 idioms (see adaptation rules below).
6. **Purge Maven cache** to avoid stale JDK 8 artifacts causing build failures:
```
mvn dependency:purge-local-repository \
-DreResolve=true \
-DactTransitively=false
```
7. **Build** to verify:
```
mvn clean install -U
```

## Java 8 to Java 21 Adaptation Rules

When porting code, apply these modernization transformations where appropriate:

### Language Features
- **Traditional instanceof + cast** -> Use pattern matching for instanceof
```java
// Java 8
if (obj instanceof String) { String s = (String) obj; use(s); }
// Java 21
if (obj instanceof String s) { use(s); }
```
- **Verbose switch statements** -> Consider switch expressions where cleaner
```java
// Java 8
String result;
switch (x) {
case 1: result = "one"; break;
case 2: result = "two"; break;
default: result = "other"; break;
}
// Java 21
var result = switch (x) {
case 1 -> "one";
case 2 -> "two";
default -> "other";
};
```
- **String concatenation for multiline** -> Consider text blocks where appropriate
- **Explicit types for local variables** -> Use `var` where the type is obvious from context

### API Differences
- **`Collections.unmodifiableList(Arrays.asList(...))`** -> Use `List.of(...)`
- **`Collections.unmodifiableSet(new HashSet<>(Arrays.asList(...)))`** -> Use `Set.of(...)`
- **`string.trim().isEmpty()`** -> Use `string.isBlank()`
- **`!optional.isPresent()`** -> Use `optional.isEmpty()`
- **`.collect(Collectors.toList())`** -> Use `.toList()`
- **Traditional I/O patterns** -> Consider `Files.readString()` / `Files.writeString()` where appropriate

### Project-Specific Differences
- The `stage` branch uses `aerospike-client-jdk21` artifact instead of `aerospike-client-jdk8`
- pom.xml uses `java.version=21` instead of `java.version=1.8` / `java.api=8`
- The `stage` branch may have additional methods (e.g., `estimateKeySize()`) not present in jdk8
- Do NOT modify pom.xml java version settings - those are already correct on `stage`

### Important
- **Be conservative with modernization**: Only modernize code that is part of the change being ported. Do not refactor surrounding unchanged code.
- Preserve the original commit messages when cherry-picking
- If a file does not exist on `stage`, check if the functionality lives in a different file or should be skipped
- After all changes, run `mvn clean install -U` and fix any compilation errors
98 changes: 98 additions & 0 deletions .claude/skills/port-to-jdk8/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
name: port-to-jdk8
description: Port changes from a stage-based branch to a stage-jdk8-based branch, adapting Java 21 code to Java 8 compatibility
argument-hint: [source-branch]
allowed-tools: Bash, Read, Edit, Write, Grep, Glob
user-invocable: true
---

# Port Branch Changes from stage (Java 21) to stage-jdk8 (Java 8)

Port changes from the source branch `$ARGUMENTS` (based on `stage`) to a new branch based on `stage-jdk8`.

## Target Branch Naming

The target branch name MUST be derived from the source branch name by appending `_jdk8`:
- Source: `CLIENT-1234_feature` -> Target: `CLIENT-1234_feature_jdk8`
- Source: `bugfix-something` -> Target: `bugfix-something_jdk8`

## Steps

1. **Validate** the source branch `$ARGUMENTS` exists and is based on `stage`.
2. **Analyze** the commits on the source branch that are not on `stage`:
```
git log --oneline stage..$ARGUMENTS
```
3. **Create** the target branch off `stage-jdk8`:
```
git checkout stage-jdk8
git pull
git checkout -b <target-branch-name>
```
4. **Cherry-pick** the commits from the source branch onto the target branch. If there are conflicts, resolve them with the Java 8 adaptations listed below.
5. **Adapt** the code for Java 8 compatibility (see adaptation rules below).
6. **Purge Maven cache** to avoid stale JDK 21 artifacts causing build failures:
```
mvn dependency:purge-local-repository \
-DreResolve=true \
-DactTransitively=false
```
7. **Build** to verify:
```
mvn clean install -U
```

## Java 21 to Java 8 Adaptation Rules

When porting code, apply these transformations:

### Language Features
- **Records** -> Replace with traditional classes (private final fields, constructor, getters, equals/hashCode/toString)
- **Sealed classes/interfaces** -> Remove `sealed`, `permits`, `non-sealed` keywords; use regular class hierarchy
- **Pattern matching for instanceof** -> Use traditional instanceof + explicit cast
```java
// Java 21
if (obj instanceof String s) { use(s); }
// Java 8
if (obj instanceof String) { String s = (String) obj; use(s); }
```
- **Switch expressions** -> Convert to switch statements or if-else chains
```java
// Java 21
var result = switch (x) {
case 1 -> "one";
case 2 -> "two";
default -> "other";
};
// Java 8
String result;
switch (x) {
case 1: result = "one"; break;
case 2: result = "two"; break;
default: result = "other"; break;
}
```
- **Text blocks (triple quotes)** -> Use string concatenation or `String.join`
- **`var` keyword** -> Replace with explicit types
- **Enhanced switch with arrow syntax** -> Use traditional colon-case syntax

### API Differences
- **`List.of()`, `Set.of()`, `Map.of()`** -> Use `Collections.unmodifiableList(Arrays.asList(...))`, `Collections.unmodifiableSet(new HashSet<>(Arrays.asList(...)))`, or manual map construction
- **`String.isBlank()`** -> Use `string.trim().isEmpty()`
- **`String.strip()`** -> Use `string.trim()`
- **`String.repeat(n)`** -> Use a loop or `String.join("", Collections.nCopies(n, str))`
- **`Optional.isEmpty()`** -> Use `!optional.isPresent()`
- **`Stream.toList()`** -> Use `.collect(Collectors.toList())`
- **`Map.entry()`** -> Use `new AbstractMap.SimpleEntry<>()`
- **`Files.readString()` / `Files.writeString()`** -> Use traditional I/O with `BufferedReader`/`BufferedWriter`

### Project-Specific Differences
- The `stage-jdk8` branch uses `aerospike-client-jdk8` artifact instead of `aerospike-client-jdk21`
- pom.xml uses `java.version=1.8` and `java.api=8` instead of `java.version=21`
- Some features like `estimateKeySize()` do not exist in the jdk8 branch
- Do NOT modify pom.xml java version settings - those are already correct on `stage-jdk8`

### Important
- Preserve the original commit messages when cherry-picking
- If a file does not exist on `stage-jdk8`, check if the functionality lives in a different file or should be skipped
- After all changes, run `mvn clean install -U` and fix any compilation errors
91 changes: 91 additions & 0 deletions .cursor/commands/port-to-jdk21.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Port Branch Changes from stage-jdk8 (Java 8) to stage (Java 21)

Port changes from the source branch (based on `stage-jdk8`) to a new branch based on `stage`.

## Instructions

The user will provide a source branch name as an argument. Use it to perform the port.

## Target Branch Naming

The target branch name MUST be derived from the source branch name by removing the `_jdk8` suffix:
- Source: `CLIENT-1234_feature_jdk8` -> Target: `CLIENT-1234_feature`
- If the source branch doesn't have a `_jdk8` suffix, append `_jdk21` to create the target name:
- Source: `bugfix-something` -> Target: `bugfix-something_jdk21`

## Steps

1. **Validate** the source branch exists and is based on `stage-jdk8`.
2. **Analyze** the commits on the source branch that are not on `stage-jdk8`:
```
git log --oneline stage-jdk8..<source-branch>
```
3. **Create** the target branch off `stage`:
```
git checkout stage
git pull
git checkout -b <target-branch-name>
```
4. **Cherry-pick** the commits from the source branch onto the target branch. If there are conflicts, resolve them with the Java 21 adaptations listed below.
5. **Adapt** the code for Java 21 idioms (see adaptation rules below).
6. **Purge Maven cache** to avoid stale JDK 8 artifacts causing build failures:
```
mvn dependency:purge-local-repository \
-DreResolve=true \
-DactTransitively=false
```
7. **Build** to verify:
```
mvn clean install -U
```

## Java 8 to Java 21 Adaptation Rules

When porting code, apply these modernization transformations where appropriate:

### Language Features
- **Traditional instanceof + cast** -> Use pattern matching for instanceof
```java
// Java 8
if (obj instanceof String) { String s = (String) obj; use(s); }
// Java 21
if (obj instanceof String s) { use(s); }
```
- **Verbose switch statements** -> Consider switch expressions where cleaner
```java
// Java 8
String result;
switch (x) {
case 1: result = "one"; break;
case 2: result = "two"; break;
default: result = "other"; break;
}
// Java 21
var result = switch (x) {
case 1 -> "one";
case 2 -> "two";
default -> "other";
};
```
- **String concatenation for multiline** -> Consider text blocks where appropriate
- **Explicit types for local variables** -> Use `var` where the type is obvious from context

### API Differences
- **`Collections.unmodifiableList(Arrays.asList(...))`** -> Use `List.of(...)`
- **`Collections.unmodifiableSet(new HashSet<>(Arrays.asList(...)))`** -> Use `Set.of(...)`
- **`string.trim().isEmpty()`** -> Use `string.isBlank()`
- **`!optional.isPresent()`** -> Use `optional.isEmpty()`
- **`.collect(Collectors.toList())`** -> Use `.toList()`
- **Traditional I/O patterns** -> Consider `Files.readString()` / `Files.writeString()` where appropriate

### Project-Specific Differences
- The `stage` branch uses `aerospike-client-jdk21` artifact instead of `aerospike-client-jdk8`
- pom.xml uses `java.version=21` instead of `java.version=1.8` / `java.api=8`
- The `stage` branch may have additional methods (e.g., `estimateKeySize()`) not present in jdk8
- Do NOT modify pom.xml java version settings - those are already correct on `stage`

### Important
- **Be conservative with modernization**: Only modernize code that is part of the change being ported. Do not refactor surrounding unchanged code.
- Preserve the original commit messages when cherry-picking
- If a file does not exist on `stage`, check if the functionality lives in a different file or should be skipped
- After all changes, run `mvn clean install -U` and fix any compilation errors
94 changes: 94 additions & 0 deletions .cursor/commands/port-to-jdk8.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Port Branch Changes from stage (Java 21) to stage-jdk8 (Java 8)

Port changes from the source branch (based on `stage`) to a new branch based on `stage-jdk8`.

## Instructions

The user will provide a source branch name as an argument. Use it to perform the port.

## Target Branch Naming

The target branch name MUST be derived from the source branch name by appending `_jdk8`:
- Source: `CLIENT-1234_feature` -> Target: `CLIENT-1234_feature_jdk8`
- Source: `bugfix-something` -> Target: `bugfix-something_jdk8`

## Steps

1. **Validate** the source branch exists and is based on `stage`.
2. **Analyze** the commits on the source branch that are not on `stage`:
```
git log --oneline stage..<source-branch>
```
3. **Create** the target branch off `stage-jdk8`:
```
git checkout stage-jdk8
git pull
git checkout -b <target-branch-name>
```
4. **Cherry-pick** the commits from the source branch onto the target branch. If there are conflicts, resolve them with the Java 8 adaptations listed below.
5. **Adapt** the code for Java 8 compatibility (see adaptation rules below).
6. **Purge Maven cache** to avoid stale JDK 21 artifacts causing build failures:
```
mvn dependency:purge-local-repository \
-DreResolve=true \
-DactTransitively=false
```
7. **Build** to verify:
```
mvn clean install -U
```

## Java 21 to Java 8 Adaptation Rules

When porting code, apply these transformations:

### Language Features
- **Records** -> Replace with traditional classes (private final fields, constructor, getters, equals/hashCode/toString)
- **Sealed classes/interfaces** -> Remove `sealed`, `permits`, `non-sealed` keywords; use regular class hierarchy
- **Pattern matching for instanceof** -> Use traditional instanceof + explicit cast
```java
// Java 21
if (obj instanceof String s) { use(s); }
// Java 8
if (obj instanceof String) { String s = (String) obj; use(s); }
```
- **Switch expressions** -> Convert to switch statements or if-else chains
```java
// Java 21
var result = switch (x) {
case 1 -> "one";
case 2 -> "two";
default -> "other";
};
// Java 8
String result;
switch (x) {
case 1: result = "one"; break;
case 2: result = "two"; break;
default: result = "other"; break;
}
```
- **Text blocks (triple quotes)** -> Use string concatenation or `String.join`
- **`var` keyword** -> Replace with explicit types
- **Enhanced switch with arrow syntax** -> Use traditional colon-case syntax

### API Differences
- **`List.of()`, `Set.of()`, `Map.of()`** -> Use `Collections.unmodifiableList(Arrays.asList(...))`, `Collections.unmodifiableSet(new HashSet<>(Arrays.asList(...)))`, or manual map construction
- **`String.isBlank()`** -> Use `string.trim().isEmpty()`
- **`String.strip()`** -> Use `string.trim()`
- **`String.repeat(n)`** -> Use a loop or `String.join("", Collections.nCopies(n, str))`
- **`Optional.isEmpty()`** -> Use `!optional.isPresent()`
- **`Stream.toList()`** -> Use `.collect(Collectors.toList())`
- **`Map.entry()`** -> Use `new AbstractMap.SimpleEntry<>()`
- **`Files.readString()` / `Files.writeString()`** -> Use traditional I/O with `BufferedReader`/`BufferedWriter`

### Project-Specific Differences
- The `stage-jdk8` branch uses `aerospike-client-jdk8` artifact instead of `aerospike-client-jdk21`
- pom.xml uses `java.version=1.8` and `java.api=8` instead of `java.version=21`
- Some features like `estimateKeySize()` do not exist in the jdk8 branch
- Do NOT modify pom.xml java version settings - those are already correct on `stage-jdk8`

### Important
- Preserve the original commit messages when cherry-picking
- If a file does not exist on `stage-jdk8`, check if the functionality lives in a different file or should be skipped
- After all changes, run `mvn clean install -U` and fix any compilation errors
Loading
Loading