From cc20e00afd7e806f2d1a1908971140ce265d0a59 Mon Sep 17 00:00:00 2001 From: haozhang Date: Mon, 31 Aug 2026 16:07:59 +0800 Subject: [PATCH 1/5] Add JDK upgrade warnings for Maven configuration Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1089b5a4-61b3-4d84-805f-6dcc3bc7f654 --- .../build.gradle.kts | 1 + .../JavaUpgradeIssuesInspection.java | 25 ++- .../inspection/JavaUpgradeProblemLocator.java | 144 ++++++++++++++++++ .../JavaUpgradeIssuesDetectionService.java | 2 +- .../appmod/javaupgrade/utils/Constants.java | 2 +- .../JavaUpgradeIssuesInspectionTest.java | 77 ++++++++++ 6 files changed, 243 insertions(+), 8 deletions(-) create mode 100644 PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/inspection/JavaUpgradeProblemLocator.java create mode 100644 PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/test/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/inspection/JavaUpgradeIssuesInspectionTest.java diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/build.gradle.kts b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/build.gradle.kts index e1a7df7b7b9..966344b8be1 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/build.gradle.kts +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/build.gradle.kts @@ -3,6 +3,7 @@ dependencies { implementation(project(":azure-intellij-plugin-lib-java")) // runtimeOnly project(path: ":azure-intellij-plugin-lib", configuration: "instrumentedJar") implementation("com.microsoft.azure:azure-toolkit-ide-common-lib") + testImplementation("org.mockito:mockito-core:5.20.0") intellijPlatform { // Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins. bundledPlugin("com.intellij.java") diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/inspection/JavaUpgradeIssuesInspection.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/inspection/JavaUpgradeIssuesInspection.java index d998ed69044..1812eda0365 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/inspection/JavaUpgradeIssuesInspection.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/inspection/JavaUpgradeIssuesInspection.java @@ -22,8 +22,11 @@ import lombok.extern.slf4j.Slf4j; import org.jetbrains.annotations.NotNull; +import org.jetbrains.idea.maven.project.MavenProject; +import org.jetbrains.idea.maven.project.MavenProjectsManager; import java.util.List; +import java.util.Properties; /** * Inspection that displays Java upgrade issues detected by JavaUpgradeDetectionService. @@ -53,19 +56,19 @@ public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean is return PsiElementVisitor.EMPTY_VISITOR; } - // Get cached issues (computed once at project startup) - final JavaUpgradeIssue jdkIssue = cache.getJdkIssue(); final List dependencyIssues = cache.getDependencyIssues(); + final Properties mavenProperties = getMavenProperties(project, file); return new XmlElementVisitor() { @Override public void visitXmlTag(@NotNull XmlTag tag) { super.visitXmlTag(tag); - // Check for JDK version tags - if (jdkIssue != null) { - if (isJavaVersionProperty(tag) || isCompilerPluginVersionTag(tag)) { - registerProblem(holder, tag, jdkIssue); + if (isJavaVersionProperty(tag) || isCompilerPluginVersionTag(tag)) { + final JavaUpgradeIssue javaIssue = + JavaUpgradeProblemLocator.createJavaVersionIssue(tag, mavenProperties); + if (javaIssue != null) { + registerProblem(holder, tag, javaIssue); } } @@ -93,6 +96,16 @@ public void visitXmlTag(@NotNull XmlTag tag) { }; } + @NotNull + private Properties getMavenProperties(@NotNull Project project, @NotNull PsiFile file) { + if (file.getVirtualFile() == null) { + return new Properties(); + } + final MavenProjectsManager manager = MavenProjectsManager.getInstanceIfCreated(project); + final MavenProject mavenProject = + manager == null ? null : manager.findProject(file.getVirtualFile()); + return mavenProject == null ? new Properties() : mavenProject.getProperties(); + } private void registerProblem(@NotNull ProblemsHolder holder, @NotNull XmlTag tag, @NotNull JavaUpgradeIssue issue) { log.info("Registering Java upgrade issue in inspection: {}", issue); holder.registerProblem( diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/inspection/JavaUpgradeProblemLocator.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/inspection/JavaUpgradeProblemLocator.java new file mode 100644 index 00000000000..90909fb76ec --- /dev/null +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/inspection/JavaUpgradeProblemLocator.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +package com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.inspection; + +import com.intellij.psi.xml.XmlTag; +import com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.dao.JavaUpgradeIssue; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; + +import static com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.service.JavaUpgradeIssuesDetectionService.JDK_DISPLAY_NAME; +import static com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.service.JavaUpgradeIssuesDetectionService.JDK_LEARN_MORE_URL; +import static com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.service.JavaUpgradeIssuesDetectionService.MATURE_JAVA_LTS_VERSION; +import static com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.service.JavaUpgradeIssuesDetectionService.PACKAGE_ID_JDK; +import static com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.utils.Constants.ISSUE_DISPLAY_NAME; + +final class JavaUpgradeProblemLocator { + + private JavaUpgradeProblemLocator() { + } + + static JavaUpgradeIssue createJavaVersionIssue(@NotNull XmlTag versionTag) { + return createJavaVersionIssue(versionTag, new Properties()); + } + + static JavaUpgradeIssue createJavaVersionIssue( + @NotNull XmlTag versionTag, + @NotNull Properties effectiveProperties + ) { + return createJavaVersionIssue( + resolveVersionText(versionTag, effectiveProperties, new HashSet<>())); + } + + static JavaUpgradeIssue createJavaVersionIssue(@Nullable String versionText) { + final Integer version = parseJavaVersion(versionText); + if (version == null || version < 8 || version >= MATURE_JAVA_LTS_VERSION) { + return null; + } + return JavaUpgradeIssue.builder() + .packageId(PACKAGE_ID_JDK) + .packageDisplayName(JDK_DISPLAY_NAME) + .upgradeReason(JavaUpgradeIssue.UpgradeReason.JRE_TOO_OLD) + .severity(JavaUpgradeIssue.Severity.WARNING) + .currentVersion(String.valueOf(version)) + .supportedVersion(">=" + MATURE_JAVA_LTS_VERSION) + .suggestedVersion(String.valueOf(MATURE_JAVA_LTS_VERSION)) + .message(String.format( + ISSUE_DISPLAY_NAME, + JDK_DISPLAY_NAME, + version, + JDK_DISPLAY_NAME, + MATURE_JAVA_LTS_VERSION + )) + .learnMoreUrl(JDK_LEARN_MORE_URL) + .build(); + } + + @Nullable + private static String resolveVersionText( + @NotNull XmlTag versionTag, + @NotNull Properties effectiveProperties, + @NotNull Set resolvingProperties + ) { + final String versionText = versionTag.getValue().getText().trim(); + if (!versionText.startsWith("${") || !versionText.endsWith("}")) { + return versionText; + } + + final String propertyName = versionText.substring(2, versionText.length() - 1); + if (!resolvingProperties.add(propertyName)) { + return null; + } + + XmlTag current = versionTag; + while (current != null) { + final XmlTag properties = "properties".equals(current.getName()) + ? current + : current.findFirstSubTag("properties"); + if (properties != null) { + final XmlTag property = properties.findFirstSubTag(propertyName); + if (property != null) { + return resolveVersionText(property, effectiveProperties, resolvingProperties); + } + } + current = current.getParentTag(); + } + return resolvePropertyValue( + effectiveProperties.getProperty(propertyName), + effectiveProperties, + resolvingProperties + ); + } + + @Nullable + private static String resolvePropertyValue( + @Nullable String value, + @NotNull Properties effectiveProperties, + @NotNull Set resolvingProperties + ) { + if (value == null) { + return null; + } + final String normalized = value.trim(); + if (!normalized.startsWith("${") || !normalized.endsWith("}")) { + return normalized; + } + final String propertyName = normalized.substring(2, normalized.length() - 1); + if (!resolvingProperties.add(propertyName)) { + return null; + } + return resolvePropertyValue( + effectiveProperties.getProperty(propertyName), + effectiveProperties, + resolvingProperties + ); + } + + @Nullable + private static Integer parseJavaVersion(@Nullable String versionText) { + if (versionText == null) { + return null; + } + final String normalized = versionText.trim(); + if (normalized.isEmpty() || normalized.startsWith("${")) { + return null; + } + final String majorVersion = normalized.startsWith("1.") + ? normalized.substring(2) + : normalized; + final int separator = majorVersion.indexOf('.'); + final String major = separator < 0 ? majorVersion : majorVersion.substring(0, separator); + try { + return Integer.parseInt(major); + } catch (NumberFormatException ignored) { + return null; + } + } +} diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/service/JavaUpgradeIssuesDetectionService.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/service/JavaUpgradeIssuesDetectionService.java index d8499172a0b..e831cdf6143 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/service/JavaUpgradeIssuesDetectionService.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/service/JavaUpgradeIssuesDetectionService.java @@ -192,7 +192,7 @@ public String getEolDateForVersion(@Nonnull String version) { ) ); - private static final String JDK_LEARN_MORE_URL = + public static final String JDK_LEARN_MORE_URL = "https://learn.microsoft.com/azure/developer/java/fundamentals/java-support-on-azure"; private static JavaUpgradeIssuesDetectionService instance; diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java index e8a6c0bc8ae..6fdfc906752 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/utils/Constants.java @@ -12,7 +12,7 @@ public class Constants { public static final String SCAN_AND_RESOLVE_CVES_WITH_COPILOT_DISPLAY_NAME = "Scan and Resolve CVEs with Copilot"; public static final String FIX_VULNERABLE_DEPENDENCY_WITH_COPILOT_PROMPT = "Fix the vulnerable dependency %s by using #appmod-validate-cves-for-java"; public static final String FIX_VULNERABLE_DEPENDENCY_WITH_COPILOT_DISPLAY_NAME = "Fix the vulnerable dependency with Copilot"; - public static final String ISSUE_DISPLAY_NAME = "Your project uses %s %s. Consider upgrading to %s to the latest LTS version for better performance and support"; + public static final String ISSUE_DISPLAY_NAME = "Your project uses %s %s. Consider upgrading %s to %s, the latest LTS version, for better performance and support"; public static final String APPMOD_CVE_AGENT_NAME = "modernize-java-security"; public static final String APPMOD_UPGRADE_AGENT_NAME = "modernize-java-upgrade"; } diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/test/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/inspection/JavaUpgradeIssuesInspectionTest.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/test/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/inspection/JavaUpgradeIssuesInspectionTest.java new file mode 100644 index 00000000000..c8bb985d589 --- /dev/null +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/test/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/inspection/JavaUpgradeIssuesInspectionTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +package com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.inspection; + +import com.intellij.psi.xml.XmlTag; +import com.intellij.psi.xml.XmlTagValue; +import com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.dao.JavaUpgradeIssue; +import org.junit.Test; + +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class JavaUpgradeIssuesInspectionTest { + + @Test + public void createsJavaIssueFromPomJavaVersion() { + final JavaUpgradeIssue issue = JavaUpgradeProblemLocator.createJavaVersionIssue("8"); + + assertEquals("8", issue.getCurrentVersion()); + assertEquals(JavaUpgradeIssue.UpgradeReason.JRE_TOO_OLD, issue.getUpgradeReason()); + } + + @Test + public void acceptsLegacyJavaVersionSyntax() { + final JavaUpgradeIssue issue = JavaUpgradeProblemLocator.createJavaVersionIssue("1.8"); + + assertEquals("8", issue.getCurrentVersion()); + } + + @Test + public void ignoresSupportedOrPropertyReferenceVersions() { + assertNull(JavaUpgradeProblemLocator.createJavaVersionIssue("21")); + assertNull(JavaUpgradeProblemLocator.createJavaVersionIssue("${java.version}")); + } + + @Test + public void resolvesJavaVersionFromAnotherMavenProperty() { + final XmlTag properties = mock(XmlTag.class); + final XmlTag javaVersion = valueTag("${jdk.version}"); + final XmlTag jdkVersion = valueTag("8"); + when(properties.getName()).thenReturn("properties"); + when(properties.findFirstSubTag("jdk.version")).thenReturn(jdkVersion); + when(javaVersion.getParentTag()).thenReturn(properties); + + final JavaUpgradeIssue issue = + JavaUpgradeProblemLocator.createJavaVersionIssue(javaVersion); + + assertEquals("8", issue.getCurrentVersion()); + } + + @Test + public void resolvesJavaVersionFromEffectiveParentProperties() { + final XmlTag javaVersion = valueTag("${parent.java.version}"); + final Properties effectiveProperties = new Properties(); + effectiveProperties.setProperty("parent.java.version", "8"); + + final JavaUpgradeIssue issue = + JavaUpgradeProblemLocator.createJavaVersionIssue(javaVersion, effectiveProperties); + + assertEquals("8", issue.getCurrentVersion()); + } + + private static XmlTag valueTag(String value) { + final XmlTag tag = mock(XmlTag.class); + final XmlTagValue tagValue = mock(XmlTagValue.class); + when(tag.getValue()).thenReturn(tagValue); + when(tagValue.getText()).thenReturn(value); + return tag; + } +} From f7e60914a96a573445540b3f3ad13b72189361d9 Mon Sep 17 00:00:00 2001 From: haozhang Date: Mon, 31 Aug 2026 16:27:34 +0800 Subject: [PATCH 2/5] upgrade java/spring boot promote to right click window --- .../action/UpgradeInProblemsViewAction.java | 132 ++++++++++++++++++ .../META-INF/azure-intellij-plugin-appmod.xml | 6 + .../javaupgrade/action/CveActionsTest.java | 43 ++++++ 3 files changed, 181 insertions(+) create mode 100644 PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/UpgradeInProblemsViewAction.java create mode 100644 PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/test/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/CveActionsTest.java diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/UpgradeInProblemsViewAction.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/UpgradeInProblemsViewAction.java new file mode 100644 index 00000000000..719c92ae9b8 --- /dev/null +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/UpgradeInProblemsViewAction.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + */ + +package com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.action; + +import com.intellij.openapi.actionSystem.ActionUpdateThread; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; +import com.microsoft.azure.toolkit.intellij.appmod.common.AppModPluginInstaller; +import com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.service.JavaVersionNotificationService; +import com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.utils.ProblemsViewUtils; +import com.microsoft.azure.toolkit.intellij.appmod.utils.AppModUtils; +import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.utils.Constants.APPMOD_UPGRADE_AGENT_NAME; +import static com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.utils.Constants.UPGRADE_JAVA_FRAMEWORK_PROMPT; + +/** + * Promotes Java and framework upgrade quick fixes to the Problems View context menu. + */ +@Slf4j +public class UpgradeInProblemsViewAction extends AnAction implements DumbAware { + + private static final Pattern UPGRADE_DESCRIPTION_PATTERN = Pattern.compile( + "Your project uses (.+?) (\\S+)\\. Consider upgrading (.+?) to (\\S+), " + + "the latest LTS version, for better performance and support" + ); + + @Override + public void actionPerformed(@NotNull AnActionEvent event) { + final Project project = event.getData(CommonDataKeys.PROJECT); + if (project == null || project.isDisposed()) { + return; + } + final UpgradeDescription upgrade = + parseUpgradeDescription(ProblemsViewUtils.extractProblemDescription(event)); + if (upgrade == null) { + return; + } + + try { + JavaVersionNotificationService.getInstance().openCopilotChatWithPrompt( + project, + String.format( + UPGRADE_JAVA_FRAMEWORK_PROMPT, + upgrade.packageDisplayName(), + upgrade.currentVersion(), + upgrade.suggestedVersion() + ), + APPMOD_UPGRADE_AGENT_NAME + ); + AppModUtils.logTelemetryEvent( + "openCopilotChatForUpgradeInProblemsViewAction", + Map.of( + "appmodPluginInstalled", + String.valueOf(AppModPluginInstaller.isAppModPluginInstalled()) + ) + ); + } catch (Throwable throwable) { + log.error("Failed to open Copilot chat for Java or framework upgrade", throwable); + } + } + + @Override + public void update(@NotNull AnActionEvent event) { + final Project project = event.getData(CommonDataKeys.PROJECT); + final VirtualFile file = event.getData(CommonDataKeys.VIRTUAL_FILE); + final UpgradeDescription upgrade = + parseUpgradeDescription(ProblemsViewUtils.extractProblemDescription(event)); + final boolean visible = project != null && !project.isDisposed() && + isBuildFile(file) && upgrade != null; + event.getPresentation().setEnabledAndVisible(visible); + if (!visible) { + return; + } + + String actionName = getActionName(upgrade); + if (!AppModPluginInstaller.isAppModPluginInstalled()) { + actionName += AppModPluginInstaller.TO_INSTALL_APP_MODE_PLUGIN; + } + event.getPresentation().setText(actionName); + } + + @Override + public @NotNull ActionUpdateThread getActionUpdateThread() { + return ActionUpdateThread.BGT; + } + + @Nullable + static UpgradeDescription parseUpgradeDescription(@Nullable String description) { + if (description == null) { + return null; + } + final Matcher matcher = UPGRADE_DESCRIPTION_PATTERN.matcher(description); + if (!matcher.find() || !matcher.group(1).equals(matcher.group(3))) { + return null; + } + return new UpgradeDescription(matcher.group(1), matcher.group(2), matcher.group(4)); + } + + @NotNull + static String getActionName(@NotNull UpgradeDescription upgrade) { + return "Upgrade " + upgrade.packageDisplayName() + " with Copilot"; + } + + private static boolean isBuildFile(@Nullable VirtualFile file) { + return file != null && ( + file.getName().equals("pom.xml") || + file.getName().endsWith(".gradle") || + file.getName().endsWith(".gradle.kts") + ); + } + + record UpgradeDescription( + @NotNull String packageDisplayName, + @NotNull String currentVersion, + @NotNull String suggestedVersion + ) { + } +} diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/resources/META-INF/azure-intellij-plugin-appmod.xml b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/resources/META-INF/azure-intellij-plugin-appmod.xml index 29c2ad3de56..63dd5aba7af 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/resources/META-INF/azure-intellij-plugin-appmod.xml +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/resources/META-INF/azure-intellij-plugin-appmod.xml @@ -45,6 +45,12 @@ description="Fix this vulnerable dependency using GitHub Copilot"> + + + Date: Mon, 31 Aug 2026 17:16:12 +0800 Subject: [PATCH 3/5] only keep fix vulnerable deps warning in problem view --- .../resources/META-INF/azure-intellij-plugin-appmod.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/resources/META-INF/azure-intellij-plugin-appmod.xml b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/resources/META-INF/azure-intellij-plugin-appmod.xml index 63dd5aba7af..947419df381 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/resources/META-INF/azure-intellij-plugin-appmod.xml +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/resources/META-INF/azure-intellij-plugin-appmod.xml @@ -51,12 +51,6 @@ description="Upgrade this Java runtime or framework using GitHub Copilot"> - - - Date: Mon, 31 Aug 2026 17:39:29 +0800 Subject: [PATCH 4/5] listen maven import and re-scan --- .../JavaUpgradeCheckStartupActivity.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/JavaUpgradeCheckStartupActivity.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/JavaUpgradeCheckStartupActivity.java index d5b2a73a7dc..a8dfd1d880c 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/JavaUpgradeCheckStartupActivity.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/JavaUpgradeCheckStartupActivity.java @@ -20,6 +20,7 @@ import kotlin.Unit; import kotlin.coroutines.Continuation; import lombok.extern.slf4j.Slf4j; +import org.jetbrains.idea.maven.project.MavenProjectsManager; import reactor.core.publisher.Mono; import javax.annotation.Nonnull; @@ -39,6 +40,16 @@ public class JavaUpgradeCheckStartupActivity implements ProjectActivity, DumbAwa @Override public Object execute(@Nonnull Project project, @Nonnull Continuation continuation) { + MavenProjectsManager.getInstance(project).addManagerListener( + new MavenProjectsManager.Listener() { + @Override + public void projectImportCompleted() { + performJavaUpgradeCheck(project, false); + } + }, + project + ); + // Wait for indexing to complete before running the check DumbService.getInstance(project).runWhenSmart(() -> { // Add a small delay after smart mode to ensure Maven/Gradle sync is done @@ -48,7 +59,7 @@ public Object execute(@Nonnull Project project, @Nonnull Continuation { /* Error during Java upgrade check startup */ @@ -63,7 +74,7 @@ public Object execute(@Nonnull Project project, @Nonnull Continuation Date: Mon, 31 Aug 2026 17:43:16 +0800 Subject: [PATCH 5/5] CVE fix prompt --- .../javaupgrade/action/JavaUpgradeQuickFix.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/JavaUpgradeQuickFix.java b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/JavaUpgradeQuickFix.java index fe265da1e30..a37fa81757e 100644 --- a/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/JavaUpgradeQuickFix.java +++ b/PluginsAndFeatures/azure-toolkit-for-intellij/azure-intellij-plugin-appmod/src/main/java/com/microsoft/azure/toolkit/intellij/appmod/javaupgrade/action/JavaUpgradeQuickFix.java @@ -18,7 +18,9 @@ import java.util.Map; +import static com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.utils.Constants.APPMOD_CVE_AGENT_NAME; import static com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.utils.Constants.APPMOD_UPGRADE_AGENT_NAME; +import static com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.utils.Constants.FIX_VULNERABLE_DEPENDENCY_WITH_COPILOT_PROMPT; import static com.microsoft.azure.toolkit.intellij.appmod.javaupgrade.utils.Constants.UPGRADE_JAVA_FRAMEWORK_PROMPT; /** @@ -56,7 +58,10 @@ public String getName() { public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { try { String prompt = buildPromptForIssue(issue); - JavaVersionNotificationService.getInstance().openCopilotChatWithPrompt(project, prompt, APPMOD_UPGRADE_AGENT_NAME); + final String agentName = issue.getUpgradeReason() == JavaUpgradeIssue.UpgradeReason.CVE + ? APPMOD_CVE_AGENT_NAME + : APPMOD_UPGRADE_AGENT_NAME; + JavaVersionNotificationService.getInstance().openCopilotChatWithPrompt(project, prompt, agentName); AppModUtils.logTelemetryEvent("openCopilotChatForJavaUpgradeQuickFix", Map.of("appmodPluginInstalled", String.valueOf(AppModPluginInstaller.isAppModPluginInstalled()))); } catch (Throwable ex) { log.error("Failed to apply Java upgrade quick fix", ex); @@ -64,6 +69,12 @@ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descri } private String buildPromptForIssue(@NotNull JavaUpgradeIssue issue) { + if (issue.getUpgradeReason() == JavaUpgradeIssue.UpgradeReason.CVE) { + final String coordinate = issue.getCurrentVersion() == null + ? issue.getPackageId() + : issue.getPackageId() + ":" + issue.getCurrentVersion(); + return String.format(FIX_VULNERABLE_DEPENDENCY_WITH_COPILOT_PROMPT, coordinate); + } return String.format( UPGRADE_JAVA_FRAMEWORK_PROMPT, issue.getPackageDisplayName(), issue.getCurrentVersion(), issue.getSuggestedVersion()