Skip to content

Commit 69aa8fd

Browse files
dhasani23David Hasanihayemaxi
authored andcommitted
feat(amazonq): java21 support (aws#6414)
## Problem Support transformations to Java 21. ## Solution Add support. --- - Treat all work as PUBLIC. Private `feature/x` branches will not be squash-merged at release time. - Your code changes must meet the guidelines in [CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines). - License: I confirm that my contribution is made under the terms of the Apache 2.0 license. --------- Co-authored-by: David Hasani <[email protected]> Co-authored-by: Maxim Hayes <[email protected]>
1 parent 30532e9 commit 69aa8fd

File tree

9 files changed

+81
-11
lines changed

9 files changed

+81
-11
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Feature",
3+
"description": "/transform: support Java 21 transformations"
4+
}

packages/amazonq/test/e2e/amazonq/transformByQ.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,42 @@ describe('Amazon Q Code Transformation', function () {
181181
assert.strictEqual(viewSummaryChatItem?.body?.includes('view a summary'), true)
182182
})
183183

184+
it('CANNOT do a Java 21 to Java 17 transformation', async () => {
185+
sinon.stub(startTransformByQ, 'getValidSQLConversionCandidateProjects').resolves([])
186+
sinon.stub(GumbyController.prototype, 'validateLanguageUpgradeProjects' as keyof GumbyController).resolves([
187+
{
188+
name: 'qct-sample-java-8-app-main',
189+
path: '/Users/alias/Desktop/qct-sample-java-8-app-main',
190+
JDKVersion: JDKVersion.JDK21,
191+
},
192+
])
193+
tab.addChatMessage({ command: '/transform' })
194+
await tab.waitForEvent(() => tab.getChatItems().length > 3, {
195+
waitTimeoutInMs: 5000,
196+
waitIntervalInMs: 1000,
197+
})
198+
const projectForm = tab.getChatItems().pop()
199+
assert.strictEqual(projectForm?.formItems?.[0]?.id ?? undefined, 'GumbyTransformLanguageUpgradeProjectForm')
200+
201+
const projectFormItemValues = {
202+
GumbyTransformLanguageUpgradeProjectForm: '/Users/alias/Desktop/qct-sample-java-8-app-main',
203+
GumbyTransformJdkFromForm: '21',
204+
GumbyTransformJdkToForm: '17',
205+
}
206+
const projectFormValues: Record<string, string> = { ...projectFormItemValues }
207+
tab.clickCustomFormButton({
208+
id: 'gumbyLanguageUpgradeTransformFormConfirm',
209+
text: 'Confirm',
210+
formItemValues: projectFormValues,
211+
})
212+
await tab.waitForEvent(() => tab.getChatItems().length > 4, {
213+
waitTimeoutInMs: 5000,
214+
waitIntervalInMs: 1000,
215+
})
216+
const errorMessage = tab.getChatItems().pop()
217+
assert.strictEqual(errorMessage?.body, CodeWhispererConstants.invalidFromToJdkChatMessage)
218+
})
219+
184220
it('Can provide metadata file for a SQL conversion', async () => {
185221
sinon.stub(startTransformByQ, 'getValidSQLConversionCandidateProjects').resolves([
186222
{

packages/core/src/amazonqGumby/chat/controller/controller.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,12 @@ export class GumbyController {
483483
message.tabID
484484
)
485485

486+
// do not allow downgrades (only this combination can be selected in the UI)
487+
if (fromJDKVersion === JDKVersion.JDK21 && toJDKVersion === JDKVersion.JDK17) {
488+
this.messenger.sendUnrecoverableErrorResponse('invalid-from-to-jdk', message.tabID)
489+
return
490+
}
491+
486492
await processLanguageUpgradeTransformFormInput(pathToProject, fromJDKVersion, toJDKVersion)
487493
await this.messenger.sendSkipTestsPrompt(message.tabID)
488494
})

packages/core/src/amazonqGumby/chat/controller/messenger/messenger.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export type UnrecoverableErrorType =
5151
| 'unsupported-target-db'
5252
| 'error-parsing-sct-file'
5353
| 'invalid-zip-no-sct-file'
54+
| 'invalid-from-to-jdk'
5455

5556
export enum GumbyNamedMessages {
5657
COMPILATION_PROGRESS_MESSAGE = 'gumbyProjectCompilationMessage',
@@ -176,7 +177,9 @@ export class Messenger {
176177
this.dispatcher.sendAsyncEventProgress(
177178
new AsyncEventProgressMessage(tabID, {
178179
inProgress: true,
179-
message: CodeWhispererConstants.userPatchDescriptionChatMessage,
180+
message: CodeWhispererConstants.userPatchDescriptionChatMessage(
181+
transformByQState.getTargetJDKVersion() ?? ''
182+
),
180183
})
181184
)
182185

@@ -233,6 +236,10 @@ export class Messenger {
233236
value: JDKVersion.JDK17,
234237
label: JDKVersion.JDK17,
235238
},
239+
{
240+
value: JDKVersion.JDK21,
241+
label: JDKVersion.JDK21,
242+
},
236243
],
237244
})
238245

@@ -246,6 +253,10 @@ export class Messenger {
246253
value: JDKVersion.JDK17,
247254
label: JDKVersion.JDK17,
248255
},
256+
{
257+
value: JDKVersion.JDK21,
258+
label: JDKVersion.JDK21,
259+
},
249260
],
250261
})
251262

@@ -481,6 +492,9 @@ export class Messenger {
481492
case 'invalid-zip-no-sct-file':
482493
message = CodeWhispererConstants.invalidMetadataFileNoSctFile
483494
break
495+
case 'invalid-from-to-jdk':
496+
message = CodeWhispererConstants.invalidFromToJdkChatMessage
497+
break
484498
}
485499

486500
this.sendJobFinishedMessage(tabID, message)

packages/core/src/amazonqGumby/chat/controller/messenger/messengerUtils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ export default class MessengerUtils {
5252
javaHomePrompt += ` ${CodeWhispererConstants.macJavaVersionHomeHelpChatMessage(11)}`
5353
} else if (jdkVersion === JDKVersion.JDK17) {
5454
javaHomePrompt += ` ${CodeWhispererConstants.macJavaVersionHomeHelpChatMessage(17)}`
55+
} else if (jdkVersion === JDKVersion.JDK21) {
56+
javaHomePrompt += ` ${CodeWhispererConstants.macJavaVersionHomeHelpChatMessage(21)}`
5557
}
5658
} else {
5759
javaHomePrompt += ` ${CodeWhispererConstants.linuxJavaHomeHelpChatMessage}`

packages/core/src/codewhisperer/commands/startTransformByQ.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ async function validateJavaHome(): Promise<boolean> {
119119
javaVersionUsedByMaven = JDKVersion.JDK11
120120
} else if (javaVersionUsedByMaven === '17.') {
121121
javaVersionUsedByMaven = JDKVersion.JDK17
122+
} else if (javaVersionUsedByMaven === '21.') {
123+
javaVersionUsedByMaven = JDKVersion.JDK21
122124
}
123125
}
124126
if (javaVersionUsedByMaven !== transformByQState.getSourceJDKVersion()) {

packages/core/src/codewhisperer/models/constants.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ export const AWSTemplateCaseInsensitiveKeyWords = ['cloudformation', 'cfn', 'tem
2424

2525
const patchDescriptions: { [key: string]: string } = {
2626
'Prepare minimal upgrade to Java 17':
27-
'This diff patch covers the set of upgrades for Springboot, JUnit, and PowerMockito frameworks.',
27+
'This diff patch covers the set of upgrades for Springboot, JUnit, and PowerMockito frameworks in Java 17.',
28+
'Prepare minimal upgrade to Java 21':
29+
'This diff patch covers the set of upgrades for Springboot, JUnit, and PowerMockito frameworks in Java 21.',
2830
'Popular Enterprise Specifications and Application Frameworks upgrade':
2931
'This diff patch covers the set of upgrades for Jakarta EE 10, Hibernate 6.2, and Micronaut 3.',
3032
'HTTP Client Utilities, Apache Commons Utilities, and Web Frameworks':
@@ -505,14 +507,14 @@ export const codeTransformLocThreshold = 100000
505507
export const jobStartedChatMessage =
506508
'I am starting to transform your code. It can take 10 to 30 minutes to upgrade your code, depending on the size of your project. To monitor progress, go to the Transformation Hub. If I run into any issues, I might pause the transformation to get input from you on how to proceed.'
507509

508-
export const chooseTransformationObjective = `I can help you with the following tasks:\n- Upgrade your Java 8 and Java 11 codebases to Java 17, or upgrade Java 17 code with up to date libraries and other dependencies.\n- Convert embedded SQL code for Oracle to PostgreSQL database migrations in AWS DMS. [Learn more](https://docs.aws.amazon.com/dms/latest/userguide/schema-conversion-embedded-sql.html).\n\nWhat would you like to do? You can enter "language upgrade" or "sql conversion".`
510+
export const chooseTransformationObjective = `I can help you with the following tasks:\n- Upgrade your Java 8, Java 11, and Java 17 codebases to Java 17 or Java 21.\n- Upgrade Java 17 or Java 21 code with up-to-date libraries and other dependencies.\n- Convert embedded SQL code for Oracle to PostgreSQL database migrations in AWS DMS. [Learn more](https://docs.aws.amazon.com/dms/latest/userguide/schema-conversion-embedded-sql.html).\n\nWhat would you like to do? You can enter "language upgrade" or "sql conversion".`
509511

510512
export const chooseTransformationObjectivePlaceholder = 'Enter "language upgrade" or "sql conversion"'
511513

512-
export const userPatchDescriptionChatMessage = `
514+
export const userPatchDescriptionChatMessage = (version: string) => `
513515
If you'd like to update and test your code with fewer changes at a time, I can divide the transformation results into separate diff patches. If applicable to your application, I can split up the diffs up into the following groups of upgrades. Here are the upgrades included in each diff:
514516
515-
• Minimal Compatible Library Upgrade to Java 17: Dependencies to the minimum compatible versions in Java 17, including Springboot, JUnit, and PowerMockito.
517+
• Minimal Compatible Library Upgrade to Java ${version}: Dependencies to the minimum compatible versions in Java ${version}, including Springboot, JUnit, and PowerMockito.
516518
517519
• Popular Enterprise Specifications Application Frameworks: Popular enterprise and application frameworks like Jakarta EE, Hibernate, and Micronaut 3.
518520
@@ -597,6 +599,9 @@ export const invalidMetadataFileErrorParsing =
597599
export const invalidMetadataFileNoSctFile =
598600
"An .sct file is required for transformation. Make sure that you've uploaded the .zip file you retrieved from your schema conversion in AWS DMS."
599601

602+
export const invalidFromToJdkChatMessage =
603+
"I can't transform a project from Java 21 to Java 17, but I can upgrade Java 21 code with up to date libraries and other dependencies. Try again with a supported language upgrade."
604+
600605
export const sqlMetadataFileReceived =
601606
'I found the following source database, target database, and host based on the schema conversion metadata you provided:'
602607

@@ -669,7 +674,7 @@ export const noPomXmlFoundChatMessage = `I couldn\'t find a project that I can u
669674
export const noJavaHomeFoundChatMessage = `Sorry, I couldn\'t locate your Java installation. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`
670675

671676
export const dependencyVersionsErrorMessage =
672-
'I could not find any other versions of this dependency in your local Maven repository. Try transforming the dependency to make it compatible with Java 17, and then try transforming this module again.'
677+
'I could not find any other versions of this dependency in your local Maven repository. Try transforming the dependency to make it compatible with your target Java version, and then try transforming this module again.'
673678

674679
export const errorUploadingWithExpiredUrl = `The upload error may have been caused by the expiration of the S3 pre-signed URL that was used to upload code artifacts to Q Code Transformation. The S3 pre-signed URL expires in 30 minutes. This could be caused by any delays introduced by intermediate services in your network infrastructure. Please investigate your network configuration and consider allowlisting 'amazonq-code-transformation-us-east-1-c6160f047e0.s3.amazonaws.com' to skip any reviewing that might delay the upload. For more information, see the [Amazon Q documentation](${codeTransformTroubleshootAllowS3Access}).`
675680

@@ -719,7 +724,7 @@ export const changesAppliedNotificationMultipleDiffs = (currentPatchIndex: numbe
719724
}
720725
}
721726

722-
export const noOpenProjectsFoundChatMessage = `I couldn\'t find a project that I can upgrade. Currently, I support Java 8, Java 11, and Java 17 projects built on Maven. Make sure your project is open in the IDE. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`
727+
export const noOpenProjectsFoundChatMessage = `I couldn\'t find a project that I can upgrade. Currently, I support Java 8, Java 11, Java 17, and Java 21 projects built on Maven. Make sure your project is open in the IDE. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`
723728

724729
export const noOpenFileFoundChatMessage = `Sorry, there isn't a source file open right now that I can generate a test for. Make sure you open a source file so I can generate tests.`
725730

@@ -731,7 +736,7 @@ export const unitTestGenerationCancelMessage = 'Unit test generation cancelled.'
731736

732737
export const tooManyRequestErrorMessage = 'Too many requests. Please wait before retrying.'
733738

734-
export const noJavaProjectsFoundChatMessage = `I couldn\'t find a project that I can upgrade. Currently, I support Java 8, Java 11, and Java 17 projects built on Maven. Make sure your project is open in the IDE. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`
739+
export const noJavaProjectsFoundChatMessage = `I couldn\'t find a project that I can upgrade. Currently, I support Java 8, Java 11, Java 17, and Java 21 projects built on Maven. Make sure your project is open in the IDE. For more information, see the [Amazon Q documentation](${codeTransformPrereqDoc}).`
735740

736741
export const linkToDocsHome = 'https://docs.aws.amazon.com/amazonq/latest/aws-builder-use-ug/code-transformation.html'
737742

packages/core/src/codewhisperer/models/model.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,7 @@ export enum JDKVersion {
649649
JDK8 = '8',
650650
JDK11 = '11',
651651
JDK17 = '17',
652+
JDK21 = '21',
652653
UNSUPPORTED = 'UNSUPPORTED',
653654
}
654655

@@ -740,7 +741,7 @@ export class TransformByQState {
740741

741742
private sourceJDKVersion: JDKVersion | undefined = undefined
742743

743-
private targetJDKVersion: JDKVersion = JDKVersion.JDK17
744+
private targetJDKVersion: JDKVersion | undefined = undefined
744745

745746
private produceMultipleDiffs: boolean = false
746747

@@ -1132,7 +1133,7 @@ export class TransformByQState {
11321133
this.payloadFilePath = ''
11331134
this.metadataPathSQL = ''
11341135
this.sourceJDKVersion = undefined
1135-
this.targetJDKVersion = JDKVersion.JDK17
1136+
this.targetJDKVersion = undefined
11361137
this.sourceDB = undefined
11371138
this.targetDB = undefined
11381139
this.sourceServerName = ''

packages/core/src/codewhisperer/service/transformByQ/transformApiHandler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ export async function startJob(uploadId: string) {
439439
transformationSpec: {
440440
transformationType: CodeWhispererConstants.transformationType, // shared b/w language upgrades & sql conversions for now
441441
source: { language: sourceLanguageVersion }, // dummy value of JDK8 used for SQL conversions just so that this API can be called
442-
target: { language: targetLanguageVersion }, // always JDK17
442+
target: { language: targetLanguageVersion }, // JAVA_17 or JAVA_21
443443
},
444444
})
445445
getLogger().info('CodeTransformation: called startJob API successfully')

0 commit comments

Comments
 (0)