From 32960d613ad5d39dc7128a68395a1a311f8a46c3 Mon Sep 17 00:00:00 2001
From: Sheng Chen <sheche@microsoft.com>
Date: Mon, 3 Jun 2024 15:20:23 +0800
Subject: [PATCH 1/6] Support HCR for gradle build server projects

---
 .../java/debug/plugin/internal/Compile.java   |  7 +-----
 .../internal/JavaHotCodeReplaceProvider.java  | 24 +++++++++++++++++++
 .../java/debug/plugin/internal/JdtUtils.java  |  9 +++++++
 3 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java
index 9cb6fbbfa..fb3aede51 100644
--- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java
+++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java
@@ -58,7 +58,7 @@ public static Object compile(CompileParams params, IProgressMonitor monitor) {
             }
         }
 
-        if (isBspProject(mainProject) && !ProjectUtils.isGradleProject(mainProject)) {
+        if (JdtUtils.isBspProject(mainProject) && !ProjectUtils.isGradleProject(mainProject)) {
             // Just need to trigger a build for the target project, the Gradle build server will
             // handle the build dependencies for us.
             try {
@@ -153,11 +153,6 @@ private static boolean isUnmanagedFolder(IProject project) {
             && ProjectUtils.isJavaProject(project);
     }
 
-    private static boolean isBspProject(IProject project) {
-        return project != null && ProjectUtils.isJavaProject(project)
-            && ProjectUtils.hasNature(project, "com.microsoft.gradle.bs.importer.GradleBuildServerProjectNature");
-    }
-
     private static IProject getDefaultProject() {
         return getWorkspaceRoot().getProject(ProjectsManager.DEFAULT_PROJECT_NAME);
     }
diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaHotCodeReplaceProvider.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaHotCodeReplaceProvider.java
index 2bf905c89..ac90f55cb 100644
--- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaHotCodeReplaceProvider.java
+++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaHotCodeReplaceProvider.java
@@ -34,16 +34,20 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.eclipse.core.resources.IBuildConfiguration;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.resources.IResourceChangeEvent;
 import org.eclipse.core.resources.IResourceChangeListener;
 import org.eclipse.core.resources.IResourceDelta;
 import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.IncrementalProjectBuilder;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.core.runtime.Path;
 import org.eclipse.jdt.core.ICompilationUnit;
 import org.eclipse.jdt.core.IJavaElement;
@@ -54,6 +58,7 @@
 import org.eclipse.jdt.core.util.IClassFileReader;
 import org.eclipse.jdt.core.util.ISourceAttribute;
 import org.eclipse.jdt.internal.core.util.Util;
+import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
 import org.eclipse.jdt.ls.core.internal.JobHelpers;
 
 import com.microsoft.java.debug.core.Configuration;
@@ -319,6 +324,25 @@ public void onClassRedefined(Consumer<List<String>> consumer) {
 
     @Override
     public CompletableFuture<List<String>> redefineClasses() {
+        try {
+            IProject mainProject = null;
+            List<IJavaProject> javaProjects = ResolveClasspathsHandler.getJavaProjectFromType(context.getMainClass());
+            if (javaProjects.size() == 1) {
+                mainProject = javaProjects.get(0).getProject();
+            }
+
+            if (mainProject != null && JdtUtils.isBspProject(mainProject)) {
+                ResourcesPlugin.getWorkspace().build(
+                    new IBuildConfiguration[]{mainProject.getActiveBuildConfig()},
+                    IncrementalProjectBuilder.INCREMENTAL_BUILD,
+                    false /*buildReference*/,
+                    new NullProgressMonitor()
+                );
+            }
+        } catch (CoreException e) {
+            JavaLanguageServerPlugin.log(e);
+        }
+
         JobHelpers.waitForBuildJobs(10 * 1000);
         return CompletableFuture.supplyAsync(() -> {
             List<String> classNames = new ArrayList<>();
diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
index a4c06c6d4..99268ee81 100644
--- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
+++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
@@ -40,6 +40,7 @@
 import org.eclipse.jdt.launching.JavaRuntime;
 import org.eclipse.jdt.launching.sourcelookup.containers.JavaProjectSourceContainer;
 import org.eclipse.jdt.launching.sourcelookup.containers.PackageFragmentRootSourceContainer;
+import org.eclipse.jdt.ls.core.internal.ProjectUtils;
 
 import com.microsoft.java.debug.core.DebugException;
 import com.microsoft.java.debug.core.StackFrameUtility;
@@ -415,4 +416,12 @@ public static boolean isSameFile(IResource resource1, IResource resource2) {
 
         return Objects.equals(resource1.getLocation(), resource2.getLocation());
     }
+
+    /**
+     * Check if the project is managed by Gradle Build Server
+     */
+    public static boolean isBspProject(IProject project) {
+        return project != null && ProjectUtils.isJavaProject(project)
+            && ProjectUtils.hasNature(project, "com.microsoft.gradle.bs.importer.GradleBuildServerProjectNature");
+    }
 }

From ddb956a988247e607eb03cff7816ebe0f56dc5b9 Mon Sep 17 00:00:00 2001
From: Sheng Chen <sheche@microsoft.com>
Date: Mon, 3 Jun 2024 15:28:25 +0800
Subject: [PATCH 2/6] Fix checkstyle violations

---
 .../java/com/microsoft/java/debug/plugin/internal/JdtUtils.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
index 99268ee81..12d0938bd 100644
--- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
+++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
@@ -418,7 +418,7 @@ public static boolean isSameFile(IResource resource1, IResource resource2) {
     }
 
     /**
-     * Check if the project is managed by Gradle Build Server
+     * Check if the project is managed by Gradle Build Server.
      */
     public static boolean isBspProject(IProject project) {
         return project != null && ProjectUtils.isJavaProject(project)

From b09c23b6d7044390d4af76674673ea73db7520c5 Mon Sep 17 00:00:00 2001
From: Sheng Chen <sheche@microsoft.com>
Date: Tue, 4 Jun 2024 12:43:40 +0800
Subject: [PATCH 3/6] Fix NPE when auto build is disabled

Signed-off-by: Sheng Chen <sheche@microsoft.com>
---
 .../java/debug/plugin/internal/Compile.java   | 68 ++++++++++++-------
 1 file changed, 45 insertions(+), 23 deletions(-)

diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java
index fb3aede51..1f371b13a 100644
--- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java
+++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java
@@ -14,6 +14,7 @@
 package com.microsoft.java.debug.plugin.internal;
 
 import java.util.ArrayList;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.logging.Logger;
 
@@ -28,14 +29,16 @@
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.OperationCanceledException;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.IType;
 import org.eclipse.jdt.ls.core.internal.BuildWorkspaceStatus;
 import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
 import org.eclipse.jdt.ls.core.internal.ProjectUtils;
 import org.eclipse.jdt.ls.core.internal.ResourceUtils;
+import org.eclipse.jdt.ls.core.internal.handlers.BuildWorkspaceHandler;
 import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager;
+import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.extended.ProjectBuildParams;
 
 import com.microsoft.java.debug.core.Configuration;
 
@@ -45,10 +48,15 @@ public class Compile {
     private static final int GRADLE_BS_COMPILATION_ERROR = 100;
 
     public static Object compile(CompileParams params, IProgressMonitor monitor) {
-        IProject mainProject = params == null ? null : ProjectUtils.getProject(params.getProjectName());
-        if (mainProject == null) {
+        if (params == null) {
+            throw new IllegalArgumentException("The compile parameters should not be null.");
+        }
+
+        IProject mainProject = null;
+        if (StringUtils.isNotBlank(params.getProjectName())) {
+            mainProject = ProjectUtils.getProject(params.getProjectName());
+        } else if (mainProject == null && StringUtils.isNotBlank(params.getMainClass())) {
             try {
-                // Q: is infer project by main class name necessary? perf impact?
                 List<IJavaProject> javaProjects = ResolveClasspathsHandler.getJavaProjectFromType(params.getMainClass());
                 if (javaProjects.size() == 1) {
                     mainProject = javaProjects.get(0).getProject();
@@ -78,20 +86,37 @@ public static Object compile(CompileParams params, IProgressMonitor monitor) {
             return BuildWorkspaceStatus.SUCCEED;
         }
 
-        try {
-            if (monitor.isCanceled()) {
-                return BuildWorkspaceStatus.CANCELLED;
-            }
+        if (monitor.isCanceled()) {
+            return BuildWorkspaceStatus.CANCELLED;
+        }
 
-            long compileAt = System.currentTimeMillis();
-            if (params != null && params.isFullBuild()) {
-                ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.CLEAN_BUILD, monitor);
-                ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, monitor);
-            } else {
-                ResourcesPlugin.getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, monitor);
+        ProjectBuildParams buildParams = new ProjectBuildParams();
+        List<TextDocumentIdentifier> identifiers = new LinkedList<>();
+        buildParams.setFullBuild(params.isFullBuild);
+        for (IJavaProject javaProject : ProjectUtils.getJavaProjects()) {
+            if (ProjectsManager.getDefaultProject().equals(javaProject.getProject())) {
+                continue;
             }
-            logger.info("Time cost for ECJ: " + (System.currentTimeMillis() - compileAt) + "ms");
+            // we only build project which is not a BSP project, in case that the compile request is triggered by
+            // HCR with auto-build disabled, the build for BSP projects will be triggered by JavaHotCodeReplaceProvider.
+            if (!JdtUtils.isBspProject(javaProject.getProject())) {
+                identifiers.add(new TextDocumentIdentifier(javaProject.getProject().getLocationURI().toString()));
+            }
+        }
+        if (identifiers.size() == 0) {
+            return BuildWorkspaceStatus.SUCCEED;
+        }
+
+        buildParams.setIdentifiers(identifiers);
+        long compileAt = System.currentTimeMillis();
+        BuildWorkspaceHandler buildWorkspaceHandler = new BuildWorkspaceHandler(JavaLanguageServerPlugin.getProjectsManager());
+        BuildWorkspaceStatus status = buildWorkspaceHandler.buildProjects(buildParams, monitor);
+        logger.info("Time cost for ECJ: " + (System.currentTimeMillis() - compileAt) + "ms");
+        if (status == BuildWorkspaceStatus.FAILED || status == BuildWorkspaceStatus.CANCELLED) {
+            return status;
+        }
 
+        try {
             IResource currentResource = mainProject;
             if (isUnmanagedFolder(mainProject) && StringUtils.isNotBlank(params.getMainClass())) {
                 IType mainType = ProjectUtils.getJavaProject(mainProject).findType(params.getMainClass());
@@ -135,17 +160,14 @@ public static Object compile(CompileParams params, IProgressMonitor monitor) {
                 }
             }
 
-            if (problemMarkers.isEmpty()) {
-                return BuildWorkspaceStatus.SUCCEED;
+            if (!problemMarkers.isEmpty()) {
+                return BuildWorkspaceStatus.WITH_ERROR;
             }
-
-            return BuildWorkspaceStatus.WITH_ERROR;
         } catch (CoreException e) {
-            JavaLanguageServerPlugin.logException("Failed to build workspace.", e);
-            return BuildWorkspaceStatus.FAILED;
-        } catch (OperationCanceledException e) {
-            return BuildWorkspaceStatus.CANCELLED;
+            JavaLanguageServerPlugin.log(e);
         }
+
+        return BuildWorkspaceStatus.SUCCEED;
     }
 
     private static boolean isUnmanagedFolder(IProject project) {

From d82ecb812edafb945c5ac08ea5f519dce5f48744 Mon Sep 17 00:00:00 2001
From: Sheng Chen <sheche@microsoft.com>
Date: Fri, 14 Jun 2024 14:49:45 +0800
Subject: [PATCH 4/6] Address comments

---
 .../java/debug/plugin/internal/Compile.java   | 15 +----
 .../internal/JavaHotCodeReplaceProvider.java  | 61 +++++++++++++------
 .../java/debug/plugin/internal/JdtUtils.java  | 25 ++++++++
 3 files changed, 68 insertions(+), 33 deletions(-)

diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java
index 1f371b13a..245281816 100644
--- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java
+++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java
@@ -52,20 +52,7 @@ public static Object compile(CompileParams params, IProgressMonitor monitor) {
             throw new IllegalArgumentException("The compile parameters should not be null.");
         }
 
-        IProject mainProject = null;
-        if (StringUtils.isNotBlank(params.getProjectName())) {
-            mainProject = ProjectUtils.getProject(params.getProjectName());
-        } else if (mainProject == null && StringUtils.isNotBlank(params.getMainClass())) {
-            try {
-                List<IJavaProject> javaProjects = ResolveClasspathsHandler.getJavaProjectFromType(params.getMainClass());
-                if (javaProjects.size() == 1) {
-                    mainProject = javaProjects.get(0).getProject();
-                }
-            } catch (CoreException e) {
-                JavaLanguageServerPlugin.logException("Failed to resolve project from main class name.", e);
-            }
-        }
-
+        IProject mainProject = JdtUtils.getMainProject(params.getProjectName(), params.getMainClass());
         if (JdtUtils.isBspProject(mainProject) && !ProjectUtils.isGradleProject(mainProject)) {
             // Just need to trigger a build for the target project, the Gradle build server will
             // handle the build dependencies for us.
diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaHotCodeReplaceProvider.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaHotCodeReplaceProvider.java
index ac90f55cb..0507bf895 100644
--- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaHotCodeReplaceProvider.java
+++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaHotCodeReplaceProvider.java
@@ -34,6 +34,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.apache.commons.lang3.StringUtils;
 import org.eclipse.core.resources.IBuildConfiguration;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IMarker;
@@ -60,6 +61,7 @@
 import org.eclipse.jdt.internal.core.util.Util;
 import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
 import org.eclipse.jdt.ls.core.internal.JobHelpers;
+import org.eclipse.jdt.ls.core.internal.ProjectUtils;
 
 import com.microsoft.java.debug.core.Configuration;
 import com.microsoft.java.debug.core.DebugException;
@@ -68,6 +70,7 @@
 import com.microsoft.java.debug.core.IDebugSession;
 import com.microsoft.java.debug.core.StackFrameUtility;
 import com.microsoft.java.debug.core.adapter.AdapterUtils;
+import com.microsoft.java.debug.core.adapter.Constants;
 import com.microsoft.java.debug.core.adapter.ErrorCode;
 import com.microsoft.java.debug.core.adapter.HotCodeReplaceEvent;
 import com.microsoft.java.debug.core.adapter.IDebugAdapterContext;
@@ -109,6 +112,8 @@ public class JavaHotCodeReplaceProvider implements IHotCodeReplaceProvider, IRes
 
     private List<String> deltaClassNames = new ArrayList<>();
 
+    private String mainProject = "";
+
     /**
      * Visitor for resource deltas.
      */
@@ -274,6 +279,7 @@ public void initialize(IDebugAdapterContext context, Map<String, Object> options
         }
         this.context = context;
         currentDebugSession = context.getDebugSession();
+        this.mainProject = ((String) options.get(Constants.PROJECT_NAME));
     }
 
     @Override
@@ -324,25 +330,7 @@ public void onClassRedefined(Consumer<List<String>> consumer) {
 
     @Override
     public CompletableFuture<List<String>> redefineClasses() {
-        try {
-            IProject mainProject = null;
-            List<IJavaProject> javaProjects = ResolveClasspathsHandler.getJavaProjectFromType(context.getMainClass());
-            if (javaProjects.size() == 1) {
-                mainProject = javaProjects.get(0).getProject();
-            }
-
-            if (mainProject != null && JdtUtils.isBspProject(mainProject)) {
-                ResourcesPlugin.getWorkspace().build(
-                    new IBuildConfiguration[]{mainProject.getActiveBuildConfig()},
-                    IncrementalProjectBuilder.INCREMENTAL_BUILD,
-                    false /*buildReference*/,
-                    new NullProgressMonitor()
-                );
-            }
-        } catch (CoreException e) {
-            JavaLanguageServerPlugin.log(e);
-        }
-
+        triggerBuildForBspProject();
         JobHelpers.waitForBuildJobs(10 * 1000);
         return CompletableFuture.supplyAsync(() -> {
             List<String> classNames = new ArrayList<>();
@@ -761,4 +749,39 @@ private List<StackFrame> getStackFrames(ThreadReference thread, boolean refresh)
             }
         });
     }
+
+    /**
+     * Trigger build separately if the main project is a BSP project.
+     * This is because auto build for BSP project will not update the class files to disk.
+     */
+    private void triggerBuildForBspProject() {
+        // check if the workspace contains BSP project first. This is for performance consideration.
+        // Due to that getJavaProjectFromType() is a heavy operation.
+        if (!containsBspProjects()) {
+            return;
+        }
+
+        IProject mainProject = JdtUtils.getMainProject(this.mainProject, context.getMainClass());
+        if (mainProject != null && JdtUtils.isBspProject(mainProject)) {
+            try {
+                ResourcesPlugin.getWorkspace().build(
+                    new IBuildConfiguration[]{mainProject.getActiveBuildConfig()},
+                    IncrementalProjectBuilder.INCREMENTAL_BUILD,
+                    false /*buildReference*/,
+                    new NullProgressMonitor()
+                );
+            } catch (CoreException e) {
+                // ignore compilation errors
+            }
+        }
+    }
+
+    private boolean containsBspProjects() {
+        for (IJavaProject javaProject : ProjectUtils.getJavaProjects()) {
+            if (JdtUtils.isBspProject(javaProject.getProject())) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
index 12d0938bd..424d55673 100644
--- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
+++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
@@ -40,6 +40,7 @@
 import org.eclipse.jdt.launching.JavaRuntime;
 import org.eclipse.jdt.launching.sourcelookup.containers.JavaProjectSourceContainer;
 import org.eclipse.jdt.launching.sourcelookup.containers.PackageFragmentRootSourceContainer;
+import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
 import org.eclipse.jdt.ls.core.internal.ProjectUtils;
 
 import com.microsoft.java.debug.core.DebugException;
@@ -424,4 +425,28 @@ public static boolean isBspProject(IProject project) {
         return project != null && ProjectUtils.isJavaProject(project)
             && ProjectUtils.hasNature(project, "com.microsoft.gradle.bs.importer.GradleBuildServerProjectNature");
     }
+
+    /**
+     * Get main project according to the main project name or main class name,
+     * or return <code>null</code> if the main project cannot be resolved.
+     */
+    public static IProject getMainProject(String mainProjectName, String mainClassName) {
+        IProject mainProject = null;
+        if (StringUtils.isNotEmpty(mainProjectName)) {
+            mainProject = ProjectUtils.getProject(mainProjectName);
+        }
+        
+        if (mainProject == null && StringUtils.isNotBlank(mainClassName)) {
+            try {
+                List<IJavaProject> javaProjects = ResolveClasspathsHandler.getJavaProjectFromType(mainClassName);
+                if (javaProjects.size() == 1) {
+                    mainProject = javaProjects.get(0).getProject();
+                }
+            } catch (CoreException e) {
+                JavaLanguageServerPlugin.logException("Failed to resolve project from main class name.", e);
+            }
+        }
+
+        return mainProject;
+    }
 }

From d47cf07962babed9c661e70b4a195adc1f37690b Mon Sep 17 00:00:00 2001
From: Sheng Chen <sheche@microsoft.com>
Date: Fri, 14 Jun 2024 15:19:00 +0800
Subject: [PATCH 5/6] Fix checkstyle violations

---
 .../debug/plugin/internal/JavaHotCodeReplaceProvider.java | 8 +++-----
 .../microsoft/java/debug/plugin/internal/JdtUtils.java    | 2 +-
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaHotCodeReplaceProvider.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaHotCodeReplaceProvider.java
index 0507bf895..3a2b2f3df 100644
--- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaHotCodeReplaceProvider.java
+++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JavaHotCodeReplaceProvider.java
@@ -34,7 +34,6 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import org.apache.commons.lang3.StringUtils;
 import org.eclipse.core.resources.IBuildConfiguration;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IMarker;
@@ -59,7 +58,6 @@
 import org.eclipse.jdt.core.util.IClassFileReader;
 import org.eclipse.jdt.core.util.ISourceAttribute;
 import org.eclipse.jdt.internal.core.util.Util;
-import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
 import org.eclipse.jdt.ls.core.internal.JobHelpers;
 import org.eclipse.jdt.ls.core.internal.ProjectUtils;
 
@@ -112,7 +110,7 @@ public class JavaHotCodeReplaceProvider implements IHotCodeReplaceProvider, IRes
 
     private List<String> deltaClassNames = new ArrayList<>();
 
-    private String mainProject = "";
+    private String mainProjectName = "";
 
     /**
      * Visitor for resource deltas.
@@ -279,7 +277,7 @@ public void initialize(IDebugAdapterContext context, Map<String, Object> options
         }
         this.context = context;
         currentDebugSession = context.getDebugSession();
-        this.mainProject = ((String) options.get(Constants.PROJECT_NAME));
+        this.mainProjectName = ((String) options.get(Constants.PROJECT_NAME));
     }
 
     @Override
@@ -761,7 +759,7 @@ private void triggerBuildForBspProject() {
             return;
         }
 
-        IProject mainProject = JdtUtils.getMainProject(this.mainProject, context.getMainClass());
+        IProject mainProject = JdtUtils.getMainProject(this.mainProjectName, context.getMainClass());
         if (mainProject != null && JdtUtils.isBspProject(mainProject)) {
             try {
                 ResourcesPlugin.getWorkspace().build(
diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
index 424d55673..9a9ffdfec 100644
--- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
+++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
@@ -435,7 +435,7 @@ public static IProject getMainProject(String mainProjectName, String mainClassNa
         if (StringUtils.isNotEmpty(mainProjectName)) {
             mainProject = ProjectUtils.getProject(mainProjectName);
         }
-        
+
         if (mainProject == null && StringUtils.isNotBlank(mainClassName)) {
             try {
                 List<IJavaProject> javaProjects = ResolveClasspathsHandler.getJavaProjectFromType(mainClassName);

From 615b666efc2d11afffd8cd0f7aad14c2c70805f7 Mon Sep 17 00:00:00 2001
From: Sheng Chen <sheche@microsoft.com>
Date: Fri, 14 Jun 2024 15:53:41 +0800
Subject: [PATCH 6/6] Use isNotBlank()

---
 .../java/com/microsoft/java/debug/plugin/internal/JdtUtils.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
index 9a9ffdfec..66562ae74 100644
--- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
+++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtUtils.java
@@ -432,7 +432,7 @@ public static boolean isBspProject(IProject project) {
      */
     public static IProject getMainProject(String mainProjectName, String mainClassName) {
         IProject mainProject = null;
-        if (StringUtils.isNotEmpty(mainProjectName)) {
+        if (StringUtils.isNotBlank(mainProjectName)) {
             mainProject = ProjectUtils.getProject(mainProjectName);
         }