From 9df6f5dbe303e6927d5abe4b559d32541d9880a7 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Sun, 23 Apr 2023 17:11:38 +0800 Subject: [PATCH 01/72] Support specifying the exception types you want to break on (#481) * support specifying the exception types you want to break on --- .github/CODEOWNERS | 2 +- .../java/debug/core/DebugSession.java | 98 ++++++++++++++++--- .../java/debug/core/DebugSettings.java | 4 +- .../java/debug/core/IDebugSession.java | 2 + ...SetExceptionBreakpointsRequestHandler.java | 7 +- .../java/debug/core/protocol/Requests.java | 9 ++ 6 files changed, 104 insertions(+), 18 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3f8625455..b11684f52 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @testforstephen @jdneo @Eskibear @CsCherrYY \ No newline at end of file +* @testforstephen @jdneo \ No newline at end of file diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java index 1c7990f16..9dfea1a98 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java @@ -16,16 +16,26 @@ import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.StringUtils; + import com.sun.jdi.ObjectCollectedException; +import com.sun.jdi.ReferenceType; import com.sun.jdi.ThreadReference; +import com.sun.jdi.VMDisconnectedException; import com.sun.jdi.VirtualMachine; +import com.sun.jdi.event.ClassPrepareEvent; +import com.sun.jdi.request.ClassPrepareRequest; import com.sun.jdi.request.EventRequest; import com.sun.jdi.request.EventRequestManager; import com.sun.jdi.request.ExceptionRequest; +import io.reactivex.disposables.Disposable; + public class DebugSession implements IDebugSession { private VirtualMachine vm; private EventHub eventHub = new EventHub(); + private List eventRequests = new ArrayList<>(); + private List subscriptions = new ArrayList<>(); public DebugSession(VirtualMachine virtualMachine) { vm = virtualMachine; @@ -136,9 +146,27 @@ public void setExceptionBreakpoints(boolean notifyCaught, boolean notifyUncaught @Override public void setExceptionBreakpoints(boolean notifyCaught, boolean notifyUncaught, String[] classFilters, String[] classExclusionFilters) { + setExceptionBreakpoints(notifyCaught, notifyUncaught, null, classFilters, classExclusionFilters); + } + + @Override + public void setExceptionBreakpoints(boolean notifyCaught, boolean notifyUncaught, String[] exceptionTypes, + String[] classFilters, String[] classExclusionFilters) { EventRequestManager manager = vm.eventRequestManager(); - ArrayList legacy = new ArrayList<>(manager.exceptionRequests()); - manager.deleteEventRequests(legacy); + + try { + ArrayList legacy = new ArrayList<>(manager.exceptionRequests()); + manager.deleteEventRequests(legacy); + manager.deleteEventRequests(eventRequests); + } catch (VMDisconnectedException ex) { + // ignore since removing breakpoints is meaningless when JVM is terminated. + } + subscriptions.forEach(subscription -> { + subscription.dispose(); + }); + subscriptions.clear(); + eventRequests.clear(); + // When no exception breakpoints are requested, no need to create an empty exception request. if (notifyCaught || notifyUncaught) { // from: https://www.javatips.net/api/REPLmode-master/src/jm/mode/replmode/REPLRunner.java @@ -153,20 +181,48 @@ public void setExceptionBreakpoints(boolean notifyCaught, boolean notifyUncaught // a thread to be available, and queries it by calling allThreads(). // See org.eclipse.debug.jdi.tests.AbstractJDITest for the example. - // get only the uncaught exceptions - ExceptionRequest request = manager.createExceptionRequest(null, notifyCaught, notifyUncaught); - request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); - if (classFilters != null) { - for (String classFilter : classFilters) { - request.addClassFilter(classFilter); + if (exceptionTypes == null || exceptionTypes.length == 0) { + ExceptionRequest request = manager.createExceptionRequest(null, notifyCaught, notifyUncaught); + request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); + if (classFilters != null) { + for (String classFilter : classFilters) { + request.addClassFilter(classFilter); + } } + if (classExclusionFilters != null) { + for (String exclusionFilter : classExclusionFilters) { + request.addClassExclusionFilter(exclusionFilter); + } + } + request.enable(); + return; } - if (classExclusionFilters != null) { - for (String exclusionFilter : classExclusionFilters) { - request.addClassExclusionFilter(exclusionFilter); + + for (String exceptionType : exceptionTypes) { + if (StringUtils.isBlank(exceptionType)) { + continue; + } + + // register exception breakpoint in the future loaded classes. + ClassPrepareRequest classPrepareRequest = manager.createClassPrepareRequest(); + classPrepareRequest.addClassFilter(exceptionType); + classPrepareRequest.enable(); + eventRequests.add(classPrepareRequest); + + Disposable subscription = eventHub.events() + .filter(debugEvent -> debugEvent.event instanceof ClassPrepareEvent + && eventRequests.contains(debugEvent.event.request())) + .subscribe(debugEvent -> { + ClassPrepareEvent event = (ClassPrepareEvent) debugEvent.event; + createExceptionBreakpoint(event.referenceType(), notifyCaught, notifyUncaught, classFilters, classExclusionFilters); + }); + subscriptions.add(subscription); + + // register exception breakpoint in the loaded classes. + for (ReferenceType refType : vm.classesByName(exceptionType)) { + createExceptionBreakpoint(refType, notifyCaught, notifyUncaught, classFilters, classExclusionFilters); } } - request.enable(); } } @@ -195,4 +251,22 @@ public IMethodBreakpoint createFunctionBreakpoint(String className, String funct int hitCount) { return new MethodBreakpoint(vm, this.getEventHub(), className, functionName, condition, hitCount); } + + private void createExceptionBreakpoint(ReferenceType refType, boolean notifyCaught, boolean notifyUncaught, + String[] classFilters, String[] classExclusionFilters) { + EventRequestManager manager = vm.eventRequestManager(); + ExceptionRequest request = manager.createExceptionRequest(refType, notifyCaught, notifyUncaught); + request.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD); + if (classFilters != null) { + for (String classFilter : classFilters) { + request.addClassFilter(classFilter); + } + } + if (classExclusionFilters != null) { + for (String exclusionFilter : classExclusionFilters) { + request.addClassExclusionFilter(exclusionFilter); + } + } + request.enable(); + } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java index f59f10043..eaafdd064 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java @@ -19,7 +19,7 @@ import com.google.gson.JsonSyntaxException; import com.google.gson.annotations.SerializedName; import com.microsoft.java.debug.core.protocol.JsonUtils; -import com.microsoft.java.debug.core.protocol.Requests.ClassFilters; +import com.microsoft.java.debug.core.protocol.Requests.ExceptionFilters; import com.microsoft.java.debug.core.protocol.Requests.StepFilters; public final class DebugSettings { @@ -39,7 +39,7 @@ public final class DebugSettings { public String javaHome; public HotCodeReplace hotCodeReplace = HotCodeReplace.MANUAL; public StepFilters stepFilters = new StepFilters(); - public ClassFilters exceptionFilters = new ClassFilters(); + public ExceptionFilters exceptionFilters = new ExceptionFilters(); public boolean exceptionFiltersUpdated = false; public int limitOfVariablesPerJdwpRequest = 100; public int jdwpRequestTimeout = 3000; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/IDebugSession.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/IDebugSession.java index 4e4078c87..f490fb0c0 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/IDebugSession.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/IDebugSession.java @@ -38,6 +38,8 @@ public interface IDebugSession { void setExceptionBreakpoints(boolean notifyCaught, boolean notifyUncaught, String[] classFilters, String[] classExclusionFilters); + void setExceptionBreakpoints(boolean notifyCaught, boolean notifyUncaught, String[] exceptionTypes, String[] classFilters, String[] classExclusionFilters); + IMethodBreakpoint createFunctionBreakpoint(String className, String functionName, String condition, int hitCount); Process process(); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetExceptionBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetExceptionBreakpointsRequestHandler.java index 3a4e642c8..62a30595a 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetExceptionBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetExceptionBreakpointsRequestHandler.java @@ -26,8 +26,8 @@ import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; import com.microsoft.java.debug.core.protocol.Messages.Response; import com.microsoft.java.debug.core.protocol.Requests.Arguments; -import com.microsoft.java.debug.core.protocol.Requests.ClassFilters; import com.microsoft.java.debug.core.protocol.Requests.Command; +import com.microsoft.java.debug.core.protocol.Requests.ExceptionFilters; import com.microsoft.java.debug.core.protocol.Requests.SetExceptionBreakpointsArguments; import com.microsoft.java.debug.core.protocol.Types; import com.sun.jdi.event.VMDeathEvent; @@ -77,10 +77,11 @@ public synchronized CompletableFuture handle(Command command, Argument } private void setExceptionBreakpoints(IDebugSession debugSession, boolean notifyCaught, boolean notifyUncaught) { - ClassFilters exceptionFilters = DebugSettings.getCurrent().exceptionFilters; + ExceptionFilters exceptionFilters = DebugSettings.getCurrent().exceptionFilters; + String[] exceptionTypes = (exceptionFilters == null ? null : exceptionFilters.exceptionTypes); String[] classFilters = (exceptionFilters == null ? null : exceptionFilters.allowClasses); String[] classExclusionFilters = (exceptionFilters == null ? null : exceptionFilters.skipClasses); - debugSession.setExceptionBreakpoints(notifyCaught, notifyUncaught, classFilters, classExclusionFilters); + debugSession.setExceptionBreakpoints(notifyCaught, notifyUncaught, exceptionTypes, classFilters, classExclusionFilters); } @Override diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Requests.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Requests.java index 697eef93d..09de7bfd9 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Requests.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Requests.java @@ -67,6 +67,15 @@ public static class ClassFilters { public String[] skipClasses = new String[0]; } + public static class ExceptionFilters extends ClassFilters { + /** + * Specifies that exceptions which are instances of refType will be reported. + * Note: this will include instances of sub-types. If null, all instances + * will be reported. + */ + public String[] exceptionTypes = new String[0]; + } + public static class StepFilters extends ClassFilters { /** * Deprecated - please use {@link ClassFilters#skipClasses } instead. From 87fae71227a58888d56b54c68fc47eaf24087102 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Mon, 24 Apr 2023 13:05:08 +0800 Subject: [PATCH 02/72] Support set exception breakpoint asynchronously & bump veriosn to 0.45.0 (#482) * Support set exception breakpoint asynchronously & bump veriosn to 0.45.0 --- com.microsoft.java.debug.core/pom.xml | 2 +- .../com/microsoft/java/debug/core/DebugSession.java | 12 ++++++++++++ .../com/microsoft/java/debug/core/IDebugSession.java | 3 +++ .../SetExceptionBreakpointsRequestHandler.java | 4 +++- com.microsoft.java.debug.plugin/.classpath | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 4 ++-- com.microsoft.java.debug.plugin/pom.xml | 4 ++-- com.microsoft.java.debug.repository/category.xml | 2 +- com.microsoft.java.debug.repository/pom.xml | 2 +- com.microsoft.java.debug.target/pom.xml | 2 +- pom.xml | 2 +- 11 files changed, 28 insertions(+), 11 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index f253b45da..a347b1883 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.44.0 + 0.45.0 com.microsoft.java.debug.core jar diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java index 9dfea1a98..fbad52fe2 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java @@ -226,6 +226,18 @@ public void setExceptionBreakpoints(boolean notifyCaught, boolean notifyUncaught } } + @Override + public void setExceptionBreakpoints(boolean notifyCaught, boolean notifyUncaught, String[] exceptionTypes, + String[] classFilters, String[] classExclusionFilters, boolean async) { + if (async) { + AsyncJdwpUtils.runAsync(() -> { + setExceptionBreakpoints(notifyCaught, notifyUncaught, exceptionTypes, classFilters, classExclusionFilters); + }); + } else { + setExceptionBreakpoints(notifyCaught, notifyUncaught, exceptionTypes, classFilters, classExclusionFilters); + } + } + @Override public Process process() { return vm.process(); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/IDebugSession.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/IDebugSession.java index f490fb0c0..6cc3f3a46 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/IDebugSession.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/IDebugSession.java @@ -40,6 +40,9 @@ public interface IDebugSession { void setExceptionBreakpoints(boolean notifyCaught, boolean notifyUncaught, String[] exceptionTypes, String[] classFilters, String[] classExclusionFilters); + void setExceptionBreakpoints(boolean notifyCaught, boolean notifyUncaught, String[] exceptionTypes, String[] classFilters, String[] classExclusionFilters, + boolean async); + IMethodBreakpoint createFunctionBreakpoint(String className, String functionName, String condition, int hitCount); Process process(); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetExceptionBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetExceptionBreakpointsRequestHandler.java index 62a30595a..b51c5fe27 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetExceptionBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetExceptionBreakpointsRequestHandler.java @@ -38,6 +38,7 @@ public class SetExceptionBreakpointsRequestHandler implements IDebugRequestHandl private boolean isInitialized = false; private boolean notifyCaught = false; private boolean notifyUncaught = false; + private boolean asyncJDWP = false; @Override public List getTargetCommands() { @@ -53,6 +54,7 @@ public synchronized CompletableFuture handle(Command command, Argument if (!isInitialized) { isInitialized = true; debugSession = context.getDebugSession(); + asyncJDWP = context.asyncJDWP(); DebugSettings.addDebugSettingChangeListener(this); debugSession.getEventHub().events().subscribe(debugEvent -> { if (debugEvent.event instanceof VMDeathEvent @@ -81,7 +83,7 @@ private void setExceptionBreakpoints(IDebugSession debugSession, boolean notifyC String[] exceptionTypes = (exceptionFilters == null ? null : exceptionFilters.exceptionTypes); String[] classFilters = (exceptionFilters == null ? null : exceptionFilters.allowClasses); String[] classExclusionFilters = (exceptionFilters == null ? null : exceptionFilters.skipClasses); - debugSession.setExceptionBreakpoints(notifyCaught, notifyUncaught, exceptionTypes, classFilters, classExclusionFilters); + debugSession.setExceptionBreakpoints(notifyCaught, notifyUncaught, exceptionTypes, classFilters, classExclusionFilters, this.asyncJDWP); } @Override diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index 3f86555d4..0fc9cfb6c 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -11,6 +11,6 @@ - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 3bc8a69fc..f04641553 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true -Bundle-Version: 0.44.0 +Bundle-Version: 0.45.0 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.11.0.jar, ., lib/rxjava-2.2.21.jar, lib/reactive-streams-1.0.4.jar, - lib/com.microsoft.java.debug.core-0.44.0.jar + lib/com.microsoft.java.debug.core-0.45.0.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index 75466e4df..b8d0b7582 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.44.0 + 0.45.0 com.microsoft.java.debug.plugin eclipse-plugin @@ -56,7 +56,7 @@ com.microsoft.java com.microsoft.java.debug.core - 0.44.0 + 0.45.0 diff --git a/com.microsoft.java.debug.repository/category.xml b/com.microsoft.java.debug.repository/category.xml index cd199eabf..38801a366 100644 --- a/com.microsoft.java.debug.repository/category.xml +++ b/com.microsoft.java.debug.repository/category.xml @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.repository/pom.xml b/com.microsoft.java.debug.repository/pom.xml index 48d8b7f68..096a5ecc9 100644 --- a/com.microsoft.java.debug.repository/pom.xml +++ b/com.microsoft.java.debug.repository/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.44.0 + 0.45.0 com.microsoft.java.debug.repository eclipse-repository diff --git a/com.microsoft.java.debug.target/pom.xml b/com.microsoft.java.debug.target/pom.xml index 537f0ddcd..c333a4d02 100644 --- a/com.microsoft.java.debug.target/pom.xml +++ b/com.microsoft.java.debug.target/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.44.0 + 0.45.0 com.microsoft.java.debug.tp ${base.name} :: Target Platform diff --git a/pom.xml b/pom.xml index fcfa85628..4eda39462 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ${base.name} :: Parent The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug - 0.44.0 + 0.45.0 pom Java Debug Server for Visual Studio Code From 31f79a5f3ab7efb1d66904fcdfdceb547aae4b83 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Fri, 12 May 2023 11:28:27 +0800 Subject: [PATCH 03/72] Add a task to sign maven artifacts with gpg (#485) * Add a task to sign maven artifacts with gpg --- scripts/publishMaven.js | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/scripts/publishMaven.js b/scripts/publishMaven.js index 1f960766c..deb75fb8b 100644 --- a/scripts/publishMaven.js +++ b/scripts/publishMaven.js @@ -1,7 +1,8 @@ /** * Usage: - * node publishMaven.js -task [upload|promote] + * node publishMaven.js -task [gpg][upload|promote] * + * gpg: Sign artifacts with GPG. * upload: Upload artifacts to a nexus staging repo. * promote: Promote a repo to get it picked up by Maven Central. */ @@ -33,7 +34,9 @@ main(configs, artifactFolder); function main() { const argv = process.argv; const task = argv[argv.indexOf("-task") + 1]; - if (task === "upload") { + if (task === "gpg") { + gpgSign(configs, artifactFolder); + } else if (task === "upload") { uploadToStaging(configs, artifactFolder); } else if (task === "promote") { promoteToCentral(configs); @@ -43,6 +46,27 @@ function main() { } } +/** + * Task gpg: Sign artifacts with GPG. + * + * Required binaries: + * - gpg + * + * Required Environment Variables: + * - artifactFolder: folder containing *.jar/*.pom files. + * - GPGPASS: passphrase of GPG key. + */ +function gpgSign(configs, artifactFolder) { + const props = ["artifactFolder", "gpgpass" ]; + for (const prop of props) { + if (!configs[prop]) { + console.error(`${prop} is not set.`); + process.exit(1); + } + } + addChecksumsAndGpgSignature(configs, artifactFolder); +} + /** * Task upload: Upload artifacts to a nexus staging repo. * @@ -141,7 +165,7 @@ function addChecksumsAndGpgSignature(configs, artifactFolder) { fs.readdirSync(modulePath) .filter(name => name.endsWith(".md5") || name.endsWith(".sha1") || name.endsWith(".asc")) .forEach(name => fs.unlinkSync(path.join(modulePath, name))); - + const files = fs.readdirSync(modulePath); for (let file of files) { // calc md5. @@ -153,7 +177,7 @@ function addChecksumsAndGpgSignature(configs, artifactFolder) { const sha1 = childProcess.execSync(`sha1sum "${path.join(modulePath, file)}"`); const sha1Match = /([a-z0-9]{40})/.exec(sha1.toString()); fs.writeFileSync(path.join(modulePath, file + ".sha1"), sha1Match[0]); - + // gpg sign. childProcess.execSync(`gpg --batch --pinentry-mode loopback --passphrase "${configs.gpgpass}" -ab "${path.join(modulePath, file)}"`) } From a01104960e77323db7a80f1cc7b39f8787855c2a Mon Sep 17 00:00:00 2001 From: Gayan Perera Date: Wed, 24 May 2023 07:30:28 +0200 Subject: [PATCH 04/72] Improve lambda method discovery Fixes: #477 (#478) * Improve lambda method discovery Fixes: #477 --- .../microsoft/java/debug/BindingUtils.java | 31 +++++-------------- .../java/debug/BreakpointLocationLocator.java | 2 +- .../java/debug/LambdaExpressionLocator.java | 2 +- .../internal/JdtSourceLookUpProvider.java | 18 ++++++++--- 4 files changed, 23 insertions(+), 30 deletions(-) diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/BindingUtils.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/BindingUtils.java index b696be049..085bf0d4c 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/BindingUtils.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/BindingUtils.java @@ -12,10 +12,12 @@ package com.microsoft.java.debug; import org.eclipse.jdt.core.dom.IMethodBinding; +import org.eclipse.jdt.internal.debug.core.breakpoints.LambdaLocationLocatorHelper; /** * Utility methods around working with JDT Bindings. */ +@SuppressWarnings("restriction") public final class BindingUtils { private BindingUtils() { @@ -48,31 +50,14 @@ public static String getMethodName(IMethodBinding binding, boolean fromKey) { } /** - * Returns the method signature of the method represented by the binding. Since - * this implementation use the {@link IMethodBinding#getKey()} to extract the - * signature from, the method name must be passed in. + * Returns the method signature of the method represented by the binding + * including the synthetic outer locals. * * @param binding the binding which the signature must be resolved for. - * @param name the name of the method. - * @return the signature or null if the signature could not be resolved from the - * key. + * @return the signature or null if the signature could not be resolved. */ - public static String toSignature(IMethodBinding binding, String name) { - // use key for now until JDT core provides a public API for this. - // "Ljava/util/Arrays;.asList([TT;)Ljava/util/List;" - // "([Ljava/lang/String;)V|Ljava/lang/InterruptedException;" - String signatureString = binding.getKey(); - if (signatureString != null) { - name = "." + name; - int index = signatureString.indexOf(name); - if (index > -1) { - int exceptionIndex = signatureString.indexOf("|", signatureString.lastIndexOf(")")); - if (exceptionIndex > -1) { - return signatureString.substring(index + name.length(), exceptionIndex); - } - return signatureString.substring(index + name.length()); - } - } - return null; + public static String toSignature(IMethodBinding binding) { + return LambdaLocationLocatorHelper.toMethodSignature(binding); } + } diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/BreakpointLocationLocator.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/BreakpointLocationLocator.java index 68f593aff..b14afde83 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/BreakpointLocationLocator.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/BreakpointLocationLocator.java @@ -46,7 +46,7 @@ public String getMethodSignature() { if (this.methodBinding == null) { return null; } - return BindingUtils.toSignature(this.methodBinding, getMethodName()); + return BindingUtils.toSignature(this.methodBinding); } /** diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/LambdaExpressionLocator.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/LambdaExpressionLocator.java index afffd9741..a5456809a 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/LambdaExpressionLocator.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/LambdaExpressionLocator.java @@ -71,7 +71,7 @@ public String getMethodSignature() { if (!this.found) { return null; } - return BindingUtils.toSignature(this.lambdaMethodBinding, getMethodName()); + return BindingUtils.toSignature(this.lambdaMethodBinding); } /** diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java index c4d4fe318..6d42572e4 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java @@ -29,10 +29,12 @@ import java.util.jar.Manifest; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.stream.Stream; import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.URIUtil; import org.eclipse.debug.core.sourcelookup.ISourceContainer; @@ -50,10 +52,10 @@ import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.ASTVisitor; import org.eclipse.jdt.core.dom.CompilationUnit; -import org.eclipse.jdt.core.dom.LambdaExpression; -import org.eclipse.jdt.core.manipulation.CoreASTProvider; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.LambdaExpression; +import org.eclipse.jdt.core.manipulation.CoreASTProvider; import org.eclipse.jdt.internal.core.JarPackageFragmentRoot; import org.eclipse.jdt.launching.IVMInstall; import org.eclipse.jdt.launching.JavaRuntime; @@ -276,7 +278,13 @@ private CompilationUnit asCompilationUnit(String uri) { * setEnvironment(String [], String [], String [], boolean) * and a unit name setUnitName(String). */ - parser.setEnvironment(new String[0], new String[0], null, true); + IFile resource = (IFile) JDTUtils.findResource(JDTUtils.toURI(uri), + ResourcesPlugin.getWorkspace().getRoot()::findFilesForLocationURI); + if (resource != null && JdtUtils.isJavaProject(resource.getProject())) { + parser.setProject(JavaCore.create(resource.getProject())); + } else { + parser.setEnvironment(new String[0], new String[0], null, true); + } parser.setUnitName(Paths.get(filePath).getFileName().toString()); /** * See the java doc for { @link ASTParser#setSource(char[]) }, @@ -492,7 +500,7 @@ public List findMethodInvocations(String uri, int line) { // Keep consistent with JDI since JDI uses binary class name invocation.declaringTypeName = binding.getDeclaringClass().getBinaryName(); } - invocation.methodGenericSignature = BindingUtils.toSignature(binding, BindingUtils.getMethodName(binding, true)); + invocation.methodGenericSignature = BindingUtils.toSignature(binding); invocation.methodSignature = Signature.getTypeErasure(invocation.methodGenericSignature); int startOffset = astNode.getStartPosition(); if (astNode instanceof org.eclipse.jdt.core.dom.MethodInvocation) { From d37cb100fb3b47c70479306c4d855060eafaabbd Mon Sep 17 00:00:00 2001 From: Gayan Perera Date: Fri, 26 May 2023 09:45:14 +0200 Subject: [PATCH 05/72] Improve ASTParser options when project is resolved. Fix #488 (#490) * Improve ASTParser options when project is resolved. Fix #488 Co-authored-by: Jinbo Wang --- .../internal/JdtSourceLookUpProvider.java | 54 ++++++++++--------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java index 6d42572e4..bd41f99ca 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java @@ -100,7 +100,8 @@ public void initialize(IDebugAdapterContext context, Map props) throw new IllegalArgumentException("argument is null"); } options.putAll(props); - // During initialization, trigger a background job to load the source containers to improve the perf. + // During initialization, trigger a background job to load the source containers + // to improve the perf. new Thread(() -> { getSourceContainers(); }).start(); @@ -142,15 +143,16 @@ public String[] getFullyQualifiedName(String uri, int[] lines, int[] columns) th return Stream.of(locations).map(location -> { if (location.className() != null && location.methodName() != null) { return location.className() - .concat("#").concat(location.methodName()) - .concat("#").concat(location.methodSignature()); + .concat("#").concat(location.methodName()) + .concat("#").concat(location.methodSignature()); } return location.className(); }).toArray(String[]::new); } @Override - public JavaBreakpointLocation[] getBreakpointLocations(String sourceUri, SourceBreakpoint[] sourceBreakpoints) throws DebugException { + public JavaBreakpointLocation[] getBreakpointLocations(String sourceUri, SourceBreakpoint[] sourceBreakpoints) + throws DebugException { if (sourceUri == null) { throw new IllegalArgumentException("sourceUri is null"); } @@ -161,8 +163,8 @@ public JavaBreakpointLocation[] getBreakpointLocations(String sourceUri, SourceB CompilationUnit astUnit = asCompilationUnit(sourceUri); JavaBreakpointLocation[] sourceLocations = Stream.of(sourceBreakpoints) - .map(sourceBreakpoint -> new JavaBreakpointLocation(sourceBreakpoint.line, sourceBreakpoint.column)) - .toArray(JavaBreakpointLocation[]::new); + .map(sourceBreakpoint -> new JavaBreakpointLocation(sourceBreakpoint.line, sourceBreakpoint.column)) + .toArray(JavaBreakpointLocation[]::new); if (astUnit != null) { Map resolvedLocations = new HashMap<>(); for (JavaBreakpointLocation sourceLocation : sourceLocations) { @@ -171,7 +173,7 @@ public JavaBreakpointLocation[] getBreakpointLocations(String sourceUri, SourceB if (sourceColumn > -1) { // if we have a column, try to find the lambda expression at that column LambdaExpressionLocator lambdaExpressionLocator = new LambdaExpressionLocator(astUnit, - sourceLine, sourceColumn); + sourceLine, sourceColumn); astUnit.accept(lambdaExpressionLocator); if (lambdaExpressionLocator.isFound()) { sourceLocation.setClassName(lambdaExpressionLocator.getFullyQualifiedTypeName()); @@ -232,7 +234,8 @@ public JavaBreakpointLocation[] getBreakpointLocations(String sourceUri, SourceB private BreakpointLocation[] getInlineBreakpointLocations(final CompilationUnit astUnit, int sourceLine) { List locations = new ArrayList<>(); - // The starting position of each line is the default breakpoint location for that line. + // The starting position of each line is the default breakpoint location for + // that line. locations.add(new BreakpointLocation(sourceLine, 0)); astUnit.accept(new ASTVisitor() { @Override @@ -284,18 +287,18 @@ private CompilationUnit asCompilationUnit(String uri) { parser.setProject(JavaCore.create(resource.getProject())); } else { parser.setEnvironment(new String[0], new String[0], null, true); + /** + * See the java doc for { @link ASTParser#setSource(char[]) }, + * the user need specify the compiler options explicitly. + */ + Map javaOptions = JavaCore.getOptions(); + javaOptions.put(JavaCore.COMPILER_SOURCE, this.latestJavaVersion); + javaOptions.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, this.latestJavaVersion); + javaOptions.put(JavaCore.COMPILER_COMPLIANCE, this.latestJavaVersion); + javaOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + parser.setCompilerOptions(javaOptions); } parser.setUnitName(Paths.get(filePath).getFileName().toString()); - /** - * See the java doc for { @link ASTParser#setSource(char[]) }, - * the user need specify the compiler options explicitly. - */ - Map javaOptions = JavaCore.getOptions(); - javaOptions.put(JavaCore.COMPILER_SOURCE, this.latestJavaVersion); - javaOptions.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, this.latestJavaVersion); - javaOptions.put(JavaCore.COMPILER_COMPLIANCE, this.latestJavaVersion); - javaOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); - parser.setCompilerOptions(javaOptions); astUnit = (CompilationUnit) parser.createAST(null); } else { // For non-file uri (e.g. jdt://contents/rt.jar/java.io/PrintStream.class), @@ -336,7 +339,8 @@ public String getJavaRuntimeVersion(String projectName) { return resolveSystemLibraryVersion(project, vmInstall); } catch (CoreException e) { - logger.log(Level.SEVERE, "Failed to get Java runtime version for project '" + projectName + "': " + e.getMessage(), e); + logger.log(Level.SEVERE, + "Failed to get Java runtime version for project '" + projectName + "': " + e.getMessage(), e); } } @@ -345,6 +349,7 @@ public String getJavaRuntimeVersion(String projectName) { /** * Get the project associated source containers. + * * @return the initialized source container list */ public synchronized ISourceContainer[] getSourceContainers() { @@ -373,7 +378,8 @@ private String getContents(IClassFile cf) { source = buffer.getContents(); } } catch (JavaModelException e) { - logger.log(Level.SEVERE, String.format("Failed to parse the source contents of the class file: %s", e.toString()), e); + logger.log(Level.SEVERE, + String.format("Failed to parse the source contents of the class file: %s", e.toString()), e); } if (source == null) { source = ""; @@ -388,7 +394,7 @@ private static String getFileURI(IClassFile classFile) { try { return new URI(JDT_SCHEME, "contents", PATH_SEPARATOR + jarName + PATH_SEPARATOR + packageName + PATH_SEPARATOR + classFile.getElementName(), classFile.getHandleIdentifier(), null) - .toASCIIString(); + .toASCIIString(); } catch (URISyntaxException e) { return null; } @@ -425,8 +431,7 @@ private static IClassFile resolveClassFile(String uriString) { private static String readFile(String filePath) { StringBuilder builder = new StringBuilder(); - try (BufferedReader bufferReader = - new BufferedReader(new InputStreamReader(new FileInputStream(filePath)))) { + try (BufferedReader bufferReader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath)))) { final int BUFFER_SIZE = 4096; char[] buffer = new char[BUFFER_SIZE]; while (true) { @@ -442,7 +447,8 @@ private static String readFile(String filePath) { return builder.toString(); } - private static String resolveSystemLibraryVersion(IJavaProject project, IVMInstall vmInstall) throws JavaModelException { + private static String resolveSystemLibraryVersion(IJavaProject project, IVMInstall vmInstall) + throws JavaModelException { LibraryLocation[] libraries = JavaRuntime.getLibraryLocations(vmInstall); if (libraries != null && libraries.length > 0) { IPackageFragmentRoot root = project.findPackageFragmentRoot(libraries[0].getSystemLibraryPath()); From 3e9adddd8c21a13b66114fb2b8f3bc711aa11ec0 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Tue, 30 May 2023 13:29:16 +0800 Subject: [PATCH 06/72] Bump version to 0.46.0 (#492) --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/.classpath | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 4 ++-- com.microsoft.java.debug.plugin/pom.xml | 4 ++-- com.microsoft.java.debug.repository/category.xml | 2 +- com.microsoft.java.debug.repository/pom.xml | 2 +- com.microsoft.java.debug.target/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index a347b1883..9faa391fb 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.45.0 + 0.46.0 com.microsoft.java.debug.core jar diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index 0fc9cfb6c..d3415ec62 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -11,6 +11,6 @@ - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index f04641553..e754ee286 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true -Bundle-Version: 0.45.0 +Bundle-Version: 0.46.0 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.11.0.jar, ., lib/rxjava-2.2.21.jar, lib/reactive-streams-1.0.4.jar, - lib/com.microsoft.java.debug.core-0.45.0.jar + lib/com.microsoft.java.debug.core-0.46.0.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index b8d0b7582..c69609528 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.45.0 + 0.46.0 com.microsoft.java.debug.plugin eclipse-plugin @@ -56,7 +56,7 @@ com.microsoft.java com.microsoft.java.debug.core - 0.45.0 + 0.46.0 diff --git a/com.microsoft.java.debug.repository/category.xml b/com.microsoft.java.debug.repository/category.xml index 38801a366..4efab9fba 100644 --- a/com.microsoft.java.debug.repository/category.xml +++ b/com.microsoft.java.debug.repository/category.xml @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.repository/pom.xml b/com.microsoft.java.debug.repository/pom.xml index 096a5ecc9..9ff9e2352 100644 --- a/com.microsoft.java.debug.repository/pom.xml +++ b/com.microsoft.java.debug.repository/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.45.0 + 0.46.0 com.microsoft.java.debug.repository eclipse-repository diff --git a/com.microsoft.java.debug.target/pom.xml b/com.microsoft.java.debug.target/pom.xml index c333a4d02..61bb2fca2 100644 --- a/com.microsoft.java.debug.target/pom.xml +++ b/com.microsoft.java.debug.target/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.45.0 + 0.46.0 com.microsoft.java.debug.tp ${base.name} :: Target Platform diff --git a/pom.xml b/pom.xml index 4eda39462..269077f6e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ${base.name} :: Parent The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug - 0.45.0 + 0.46.0 pom Java Debug Server for Visual Studio Code From 25dd38f7202f0841ec8dd0686112e8809ee79c19 Mon Sep 17 00:00:00 2001 From: "microsoft-github-policy-service[bot]" <77245923+microsoft-github-policy-service[bot]@users.noreply.github.com> Date: Mon, 5 Jun 2023 13:06:22 +0800 Subject: [PATCH 07/72] Microsoft mandatory file (#493) Co-authored-by: microsoft-github-policy-service[bot] <77245923+microsoft-github-policy-service[bot]@users.noreply.github.com> --- SECURITY.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 000000000..e138ec5d6 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,41 @@ + + +## Security + +Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). + +If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. + +## Reporting Security Issues + +**Please do not report security vulnerabilities through public GitHub issues.** + +Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). + +If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). + +You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). + +Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: + + * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) + * Full paths of source file(s) related to the manifestation of the issue + * The location of the affected source code (tag/branch/commit or direct URL) + * Any special configuration required to reproduce the issue + * Step-by-step instructions to reproduce the issue + * Proof-of-concept or exploit code (if possible) + * Impact of the issue, including how an attacker might exploit the issue + +This information will help us triage your report more quickly. + +If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. + +## Preferred Languages + +We prefer all communications to be in English. + +## Policy + +Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). + + From 6f5a9b386035e0663c343abc898b2c9e9c31b69d Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Mon, 26 Jun 2023 15:27:49 +0800 Subject: [PATCH 08/72] Debug support on the decompiled source code (#495) * Debug support on the decompiled source code --- .../java/debug/core/DebugSettings.java | 8 ++ .../debug/core/JavaBreakpointLocation.java | 14 ++- .../java/debug/core/adapter/AdapterUtils.java | 54 ++++++++++ .../core/adapter/ISourceLookUpProvider.java | 20 ++++ .../handler/SetBreakpointsRequestHandler.java | 18 +++- .../handler/StackTraceRequestHandler.java | 10 ++ .../internal/JdtSourceLookUpProvider.java | 100 +++++++++++++++++- .../com.microsoft.java.debug.tp.target | 2 +- 8 files changed, 219 insertions(+), 7 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java index eaafdd064..0a3e05ec8 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSettings.java @@ -44,6 +44,7 @@ public final class DebugSettings { public int limitOfVariablesPerJdwpRequest = 100; public int jdwpRequestTimeout = 3000; public AsyncMode asyncJDWP = AsyncMode.OFF; + public Switch debugSupportOnDecompiledSource = Switch.OFF; public static DebugSettings getCurrent() { return current; @@ -97,6 +98,13 @@ public static enum AsyncMode { OFF } + public static enum Switch { + @SerializedName("on") + ON, + @SerializedName("off") + OFF + } + public static interface IDebugSettingChangeListener { public void update(DebugSettings oldSettings, DebugSettings newSettings); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/JavaBreakpointLocation.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/JavaBreakpointLocation.java index 820e80c9b..3dbc1a24d 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/JavaBreakpointLocation.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/JavaBreakpointLocation.java @@ -17,7 +17,11 @@ public class JavaBreakpointLocation { /** - * The source line of the breakpoint or logpoint. + * The line number in the source file. + */ + private int lineNumberInSourceFile = Integer.MIN_VALUE; + /** + * The line number in the class file. */ private int lineNumber; /** @@ -110,4 +114,12 @@ public Types.BreakpointLocation[] availableBreakpointLocations() { public void setAvailableBreakpointLocations(Types.BreakpointLocation[] availableBreakpointLocations) { this.availableBreakpointLocations = availableBreakpointLocations; } + + public int lineNumberInSourceFile() { + return lineNumberInSourceFile == Integer.MIN_VALUE ? lineNumber : lineNumberInSourceFile; + } + + public void setLineNumberInSourceFile(int lineNumberInSourceFile) { + this.lineNumberInSourceFile = lineNumberInSourceFile; + } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/AdapterUtils.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/AdapterUtils.java index 9b972334d..c30aa8742 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/AdapterUtils.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/AdapterUtils.java @@ -310,4 +310,58 @@ public static String decodeURIComponent(String uri) { return uri; } } + + /** + * Find the mapped lines based on the given line number. + * + * The line mappings format is as follows: + * - [i]: key + * - [i+1]: value + */ + public static int[] binarySearchMappedLines(int[] lineMappings, int targetLine) { + if (lineMappings == null || lineMappings.length == 0 || lineMappings.length % 2 != 0) { + return null; + } + + final int MAX = lineMappings.length / 2 - 1; + int low = 0; + int high = MAX; + int found = -1; + while (low <= high) { + int mid = low + (high - low) / 2; + int actualMid = mid * 2; + if (lineMappings[actualMid] == targetLine) { + found = mid; + break; + } + + if (lineMappings[actualMid] < targetLine) { + low = mid + 1; + } else { + high = mid - 1; + } + } + + if (found == -1) { + return null; + } + + // Find the duplicates in the sorted array + int left = found; + while ((left - 1) >= 0 && lineMappings[(left - 1) * 2] == targetLine) { + left--; + } + + int right = found; + while ((right + 1) <= MAX && lineMappings[(right + 1) * 2] == targetLine) { + right++; + } + + int[] values = new int[right - left + 1]; + for (int i = 0; i < values.length; i++) { + values[i] = lineMappings[(left + i) * 2 + 1]; + } + + return values; + } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ISourceLookUpProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ISourceLookUpProvider.java index ead10e33c..5ffed6e0f 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ISourceLookUpProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ISourceLookUpProvider.java @@ -76,6 +76,26 @@ default String getJavaRuntimeVersion(String projectName) { */ List findMethodInvocations(String uri, int line); + /** + * Return the line mappings from the original line to the decompiled line. + * + * @param uri The uri + * @return the line mappings from the original line to the decompiled line. + */ + default int[] getOriginalLineMappings(String uri) { + return null; + } + + /** + * Return the line mappings from the decompiled line to the original line. + * + * @param uri The uri + * @return the line mappings from the decompiled line to the original line. + */ + default int[] getDecompiledLineMappings(String uri) { + return null; + } + public static class MethodInvocation { public String expression; public String methodName; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java index 7fe6c3fdd..a8774ad37 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java @@ -24,6 +24,8 @@ import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugException; +import com.microsoft.java.debug.core.DebugSettings; +import com.microsoft.java.debug.core.DebugSettings.Switch; import com.microsoft.java.debug.core.IBreakpoint; import com.microsoft.java.debug.core.IDebugSession; import com.microsoft.java.debug.core.IEvaluatableBreakpoint; @@ -296,7 +298,8 @@ public static boolean handleEvaluationResult(IDebugAdapterContext context, Threa private Types.Breakpoint convertDebuggerBreakpointToClient(IBreakpoint breakpoint, IDebugAdapterContext context) { int id = (int) breakpoint.getProperty("id"); boolean verified = breakpoint.getProperty("verified") != null && (boolean) breakpoint.getProperty("verified"); - int lineNumber = AdapterUtils.convertLineNumber(breakpoint.getLineNumber(), context.isDebuggerLinesStartAt1(), context.isClientLinesStartAt1()); + int lineNumber = AdapterUtils.convertLineNumber(breakpoint.sourceLocation().lineNumberInSourceFile(), + context.isDebuggerLinesStartAt1(), context.isClientLinesStartAt1()); return new Types.Breakpoint(id, verified, lineNumber, ""); } @@ -318,6 +321,19 @@ private IBreakpoint[] convertClientBreakpointsToDebugger(String sourceFile, Type } catch (NumberFormatException e) { hitCount = 0; // If hitCount is an illegal number, ignore hitCount condition. } + + if (DebugSettings.getCurrent().debugSupportOnDecompiledSource == Switch.ON) { + // Align the decompiled line with the original line. + int[] lineMappings = sourceProvider.getDecompiledLineMappings(sourceFile); + if (locations[i] != null && lineMappings != null) { + int lineNumberInSourceFile = locations[i].lineNumber(); + int[] originalLines = AdapterUtils.binarySearchMappedLines(lineMappings, lineNumberInSourceFile); + if (originalLines != null && originalLines.length > 0) { + locations[i].setLineNumberInSourceFile(lineNumberInSourceFile); + locations[i].setLineNumber(originalLines[0]); + } + } + } breakpoints[i] = context.getDebugSession().createBreakpoint(locations[i], hitCount, sourceBreakpoints[i].condition, sourceBreakpoints[i].logMessage); if (sourceProvider.supportsRealtimeBreakpointVerification() && StringUtils.isNotBlank(locations[i].className())) { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index fbfce49ef..601a29f56 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -25,8 +25,10 @@ import org.apache.commons.lang3.StringUtils; import com.microsoft.java.debug.core.AsyncJdwpUtils; +import com.microsoft.java.debug.core.DebugSettings; import com.microsoft.java.debug.core.DebugUtility; import com.microsoft.java.debug.core.IBreakpoint; +import com.microsoft.java.debug.core.DebugSettings.Switch; import com.microsoft.java.debug.core.adapter.AdapterUtils; import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; @@ -189,6 +191,14 @@ private Types.StackFrame convertDebuggerStackFrameToClient(StackFrameInfo jdiFra // display "Unknown Source" in the Call Stack View. clientSource = null; } + } else if (DebugSettings.getCurrent().debugSupportOnDecompiledSource == Switch.ON + && clientSource != null && clientSource.path != null) { + // Align the original line with the decompiled line. + int[] lineMappings = context.getProvider(ISourceLookUpProvider.class).getOriginalLineMappings(clientSource.path); + int[] renderLines = AdapterUtils.binarySearchMappedLines(lineMappings, clientLineNumber); + if (renderLines != null && renderLines.length > 0) { + clientLineNumber = renderLines[0]; + } } int clientColumnNumber = context.isClientColumnsStartAt1() ? 1 : 0; diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java index bd41f99ca..f0c8795cc 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java @@ -36,6 +36,7 @@ import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.URIUtil; import org.eclipse.debug.core.sourcelookup.ISourceContainer; import org.eclipse.jdt.core.IBuffer; @@ -60,14 +61,19 @@ import org.eclipse.jdt.launching.IVMInstall; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jdt.launching.LibraryLocation; +import org.eclipse.jdt.ls.core.internal.DecompilerResult; import org.eclipse.jdt.ls.core.internal.JDTUtils; +import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin; +import org.eclipse.jdt.ls.core.internal.managers.ContentProviderManager; import com.microsoft.java.debug.BindingUtils; import com.microsoft.java.debug.BreakpointLocationLocator; import com.microsoft.java.debug.LambdaExpressionLocator; import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugException; +import com.microsoft.java.debug.core.DebugSettings; import com.microsoft.java.debug.core.JavaBreakpointLocation; +import com.microsoft.java.debug.core.DebugSettings.Switch; import com.microsoft.java.debug.core.adapter.AdapterUtils; import com.microsoft.java.debug.core.adapter.Constants; import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; @@ -303,10 +309,42 @@ private CompilationUnit asCompilationUnit(String uri) { } else { // For non-file uri (e.g. jdt://contents/rt.jar/java.io/PrintStream.class), // leverage jdt to load the source contents. - ITypeRoot typeRoot = resolveClassFile(uri); - if (typeRoot != null) { - parser.setSource(typeRoot); - astUnit = (CompilationUnit) parser.createAST(null); + IClassFile typeRoot = resolveClassFile(uri); + try { + if (typeRoot != null && typeRoot.getSourceRange() != null) { + parser.setSource(typeRoot); + astUnit = (CompilationUnit) parser.createAST(null); + } else if (typeRoot != null && DebugSettings.getCurrent().debugSupportOnDecompiledSource == Switch.ON) { + ContentProviderManager contentProvider = JavaLanguageServerPlugin.getContentProviderManager(); + try { + String contents = contentProvider.getSource(typeRoot, new NullProgressMonitor()); + if (contents != null && !contents.isBlank()) { + IJavaProject javaProject = typeRoot.getJavaProject(); + if (javaProject != null) { + parser.setProject(javaProject); + } else { + parser.setEnvironment(new String[0], new String[0], null, true); + /** + * See the java doc for { @link ASTParser#setSource(char[]) }, + * the user need specify the compiler options explicitly. + */ + Map javaOptions = JavaCore.getOptions(); + javaOptions.put(JavaCore.COMPILER_SOURCE, this.latestJavaVersion); + javaOptions.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, this.latestJavaVersion); + javaOptions.put(JavaCore.COMPILER_COMPLIANCE, this.latestJavaVersion); + javaOptions.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED); + parser.setCompilerOptions(javaOptions); + } + parser.setUnitName(typeRoot.getElementName()); + parser.setSource(contents.toCharArray()); + astUnit = (CompilationUnit) parser.createAST(null); + } + } catch (Exception e) { + JavaLanguageServerPlugin.logException(e.getMessage(), e); + } + } + } catch (JavaModelException e) { + // ignore } } return astUnit; @@ -533,4 +571,58 @@ private boolean isSameURI(String uri1, String uri2) { return false; } } + + public int[] getOriginalLineMappings(String uri) { + IClassFile classFile = resolveClassFile(uri); + try { + if (classFile == null) { + return null; + } + + IPackageFragmentRoot packageRoot = (IPackageFragmentRoot) classFile.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT); + if (packageRoot != null && packageRoot.getSourceAttachmentPath() != null) { + return null; + } + + if (classFile.getSourceRange() == null) { + ContentProviderManager contentProvider = JavaLanguageServerPlugin.getContentProviderManager(); + try { + DecompilerResult result = contentProvider.getSourceResult(classFile, new NullProgressMonitor()); + if (result != null) { + return result.getOriginalLineMappings(); + } + } catch (NoSuchMethodError e) { + // ignore it if old language server version is installed. + } catch (Exception e) { + JavaLanguageServerPlugin.logException(e.getMessage(), e); + } + } + } catch (JavaModelException e) { + // ignore + } + return null; + } + + public int[] getDecompiledLineMappings(String uri) { + IClassFile classFile = resolveClassFile(uri); + try { + if (classFile != null && classFile.getSourceRange() == null) { + ContentProviderManager contentProvider = JavaLanguageServerPlugin.getContentProviderManager(); + try { + DecompilerResult result = contentProvider.getSourceResult(classFile, new NullProgressMonitor()); + if (result != null) { + return result.getDecompiledLineMappings(); + } + } catch (NoSuchMethodError e) { + // ignore it if old Java language server version is installed. + } catch (Exception e) { + JavaLanguageServerPlugin.logException(e.getMessage(), e); + } + } + } catch (JavaModelException e) { + // ignore + } + + return null; + } } diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index 187803840..fbc981533 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -31,7 +31,7 @@ - + From b6564781f1b212036d5fceed4e9b757d40cc0ce4 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Fri, 30 Jun 2023 09:57:33 +0800 Subject: [PATCH 09/72] Track the perf of stackTrace dap request (#496) --- .../handler/StackTraceRequestHandler.java | 15 ++++++++++++ .../java/debug/core/protocol/Events.java | 24 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index 601a29f56..6b44d52f5 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -24,6 +24,7 @@ import org.apache.commons.lang3.StringUtils; +import com.google.gson.JsonObject; import com.microsoft.java.debug.core.AsyncJdwpUtils; import com.microsoft.java.debug.core.DebugSettings; import com.microsoft.java.debug.core.DebugUtility; @@ -41,6 +42,7 @@ import com.microsoft.java.debug.core.protocol.Requests.StackTraceArguments; import com.microsoft.java.debug.core.protocol.Responses; import com.microsoft.java.debug.core.protocol.Types; +import com.microsoft.java.debug.core.protocol.Events.TelemetryEvent; import com.sun.jdi.AbsentInformationException; import com.sun.jdi.IncompatibleThreadStateException; import com.sun.jdi.LocalVariable; @@ -54,6 +56,7 @@ import com.sun.jdi.request.BreakpointRequest; public class StackTraceRequestHandler implements IDebugRequestHandler { + private ThreadLocal isDecompilerInvoked = new ThreadLocal<>(); @Override public List getTargetCommands() { @@ -62,6 +65,8 @@ public List getTargetCommands() { @Override public CompletableFuture handle(Command command, Arguments arguments, Response response, IDebugAdapterContext context) { + final long startAt = System.currentTimeMillis(); + isDecompilerInvoked.set(false); StackTraceArguments stacktraceArgs = (StackTraceArguments) arguments; List result = new ArrayList<>(); if (stacktraceArgs.startFrame < 0 || stacktraceArgs.levels < 0) { @@ -108,6 +113,15 @@ public CompletableFuture handle(Command command, Arguments arguments, } } response.body = new Responses.StackTraceResponseBody(result, totalFrames); + long duration = System.currentTimeMillis() - startAt; + JsonObject properties = new JsonObject(); + properties.addProperty("command", "stackTrace"); + properties.addProperty("duration", duration); + properties.addProperty("decompileSupport", DebugSettings.getCurrent().debugSupportOnDecompiledSource.toString()); + if (isDecompilerInvoked.get() != null) { + properties.addProperty("isDecompilerInvoked", Boolean.toString(isDecompilerInvoked.get())); + } + context.getProtocolServer().sendEvent(new TelemetryEvent("dap", properties)); return CompletableFuture.completedFuture(response); } @@ -198,6 +212,7 @@ private Types.StackFrame convertDebuggerStackFrameToClient(StackFrameInfo jdiFra int[] renderLines = AdapterUtils.binarySearchMappedLines(lineMappings, clientLineNumber); if (renderLines != null && renderLines.length > 0) { clientLineNumber = renderLines[0]; + isDecompilerInvoked.set(true); } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Events.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Events.java index 681ec543d..1973444b6 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Events.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Events.java @@ -246,6 +246,30 @@ public UserNotificationEvent(NotificationType notifyType, String message) { } } + public static class TelemetryEvent extends DebugEvent { + /** + * The telemetry event name. + */ + public String name; + + /** + * The properties is an object as below. + * { + * [key: string]: string | number; + * } + */ + public Object properties; + + /** + * Constructor. + */ + public TelemetryEvent(String name, Object data) { + super("telemetry"); + this.name = name; + this.properties = data; + } + } + public static enum InvalidatedAreas { @SerializedName("all") ALL, From 7bdf2effd7be8f54745e04ea8334e337ed86b75b Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Fri, 30 Jun 2023 10:44:35 +0800 Subject: [PATCH 10/72] Bump version to 0.47.0 (#497) --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/.classpath | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 4 ++-- com.microsoft.java.debug.plugin/pom.xml | 4 ++-- com.microsoft.java.debug.repository/category.xml | 2 +- com.microsoft.java.debug.repository/pom.xml | 2 +- com.microsoft.java.debug.target/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 9faa391fb..3b1d57547 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.46.0 + 0.47.0 com.microsoft.java.debug.core jar diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index d3415ec62..5c303928d 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -11,6 +11,6 @@ - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index e754ee286..0965d8ed5 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true -Bundle-Version: 0.46.0 +Bundle-Version: 0.47.0 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.11.0.jar, ., lib/rxjava-2.2.21.jar, lib/reactive-streams-1.0.4.jar, - lib/com.microsoft.java.debug.core-0.46.0.jar + lib/com.microsoft.java.debug.core-0.47.0.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index c69609528..c41c9de3b 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.46.0 + 0.47.0 com.microsoft.java.debug.plugin eclipse-plugin @@ -56,7 +56,7 @@ com.microsoft.java com.microsoft.java.debug.core - 0.46.0 + 0.47.0 diff --git a/com.microsoft.java.debug.repository/category.xml b/com.microsoft.java.debug.repository/category.xml index 4efab9fba..20eac94c8 100644 --- a/com.microsoft.java.debug.repository/category.xml +++ b/com.microsoft.java.debug.repository/category.xml @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.repository/pom.xml b/com.microsoft.java.debug.repository/pom.xml index 9ff9e2352..665b94a6a 100644 --- a/com.microsoft.java.debug.repository/pom.xml +++ b/com.microsoft.java.debug.repository/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.46.0 + 0.47.0 com.microsoft.java.debug.repository eclipse-repository diff --git a/com.microsoft.java.debug.target/pom.xml b/com.microsoft.java.debug.target/pom.xml index 61bb2fca2..6e22d46ab 100644 --- a/com.microsoft.java.debug.target/pom.xml +++ b/com.microsoft.java.debug.target/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.46.0 + 0.47.0 com.microsoft.java.debug.tp ${base.name} :: Target Platform diff --git a/pom.xml b/pom.xml index 269077f6e..c296ce2c1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ${base.name} :: Parent The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug - 0.46.0 + 0.47.0 pom Java Debug Server for Visual Studio Code From f9c02cffebf3f7b62ca5f980fa842033f3d53049 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Mon, 24 Jul 2023 13:57:20 +0800 Subject: [PATCH 11/72] Custom request 'refreshFrames' to refresh the thread's frames (#501) * Custom request 'refreshFrames' to refresh the thread's frames --- .../java/debug/core/adapter/DebugAdapter.java | 2 + .../java/debug/core/adapter/ThreadCache.java | 46 ++++++ .../ConfigurationDoneRequestHandler.java | 3 +- .../adapter/handler/RefreshFramesHandler.java | 136 ++++++++++++++++++ .../adapter/handler/RestartFrameHandler.java | 1 + .../handler/SetBreakpointsRequestHandler.java | 4 +- .../SetDataBreakpointsRequestHandler.java | 4 +- .../SetFunctionBreakpointsRequestHandler.java | 4 +- .../handler/StackTraceRequestHandler.java | 19 ++- .../adapter/handler/StepRequestHandler.java | 2 +- .../handler/ThreadsRequestHandler.java | 7 + .../java/debug/core/protocol/Events.java | 5 + .../java/debug/core/protocol/Requests.java | 10 ++ 13 files changed, 233 insertions(+), 10 deletions(-) create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/RefreshFramesHandler.java diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java index b853e0469..10c0df902 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java @@ -34,6 +34,7 @@ import com.microsoft.java.debug.core.adapter.handler.InlineValuesRequestHandler; import com.microsoft.java.debug.core.adapter.handler.LaunchRequestHandler; import com.microsoft.java.debug.core.adapter.handler.ProcessIdHandler; +import com.microsoft.java.debug.core.adapter.handler.RefreshFramesHandler; import com.microsoft.java.debug.core.adapter.handler.RefreshVariablesHandler; import com.microsoft.java.debug.core.adapter.handler.RestartFrameHandler; import com.microsoft.java.debug.core.adapter.handler.ScopesRequestHandler; @@ -133,6 +134,7 @@ private void initialize() { registerHandlerForDebug(new SetFunctionBreakpointsRequestHandler()); registerHandlerForDebug(new BreakpointLocationsRequestHander()); registerHandlerForDebug(new StepInTargetsRequestHandler()); + registerHandlerForDebug(new RefreshFramesHandler()); // NO_DEBUG mode only registerHandlerForNoDebug(new DisconnectRequestWithoutDebuggingHandler()); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ThreadCache.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ThreadCache.java index ce1c17282..57d39154e 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ThreadCache.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ThreadCache.java @@ -13,6 +13,7 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; @@ -32,6 +33,8 @@ protected boolean removeEldestEntry(java.util.Map.Entry eldest) { } }); private Map eventThreads = new ConcurrentHashMap<>(); + private Map> decompiledClassesByThread = new HashMap<>(); + private Map threadStoppedReasons = new HashMap<>(); public synchronized void resetThreads(List threads) { allThreads.clear(); @@ -80,6 +83,13 @@ public void addEventThread(ThreadReference thread) { eventThreads.put(thread.uniqueID(), thread); } + public void addEventThread(ThreadReference thread, String reason) { + eventThreads.put(thread.uniqueID(), thread); + if (reason != null) { + threadStoppedReasons.put(thread.uniqueID(), reason); + } + } + public void removeEventThread(long threadId) { eventThreads.remove(threadId); } @@ -113,4 +123,40 @@ public List visibleThreads(IDebugAdapterContext context) { return visibleThreads; } + + public Set getDecompiledClassesByThread(long threadId) { + return decompiledClassesByThread.get(threadId); + } + + public void setDecompiledClassesByThread(long threadId, Set decompiledClasses) { + if (decompiledClasses == null || decompiledClasses.isEmpty()) { + decompiledClassesByThread.remove(threadId); + return; + } + + decompiledClassesByThread.put(threadId, decompiledClasses); + } + + public String getThreadStoppedReason(long threadId) { + return threadStoppedReasons.get(threadId); + } + + public void setThreadStoppedReason(long threadId, String reason) { + if (reason == null) { + threadStoppedReasons.remove(threadId); + return; + } + + threadStoppedReasons.put(threadId, reason); + } + + public void clearThreadStoppedState(long threadId) { + threadStoppedReasons.remove(threadId); + decompiledClassesByThread.remove(threadId); + } + + public void clearAllThreadStoppedState() { + threadStoppedReasons.clear(); + decompiledClassesByThread.clear(); + } } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java index 6805073dc..1c543bce4 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ConfigurationDoneRequestHandler.java @@ -76,6 +76,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, if (context.isVmStopOnEntry()) { DebugUtility.stopOnEntry(debugSession, context.getMainClass()).thenAccept(threadId -> { context.getProtocolServer().sendEvent(new Events.StoppedEvent("entry", threadId)); + context.getThreadCache().setThreadStoppedReason(threadId, "entry"); }); } } else if (event instanceof VMDeathEvent) { @@ -117,7 +118,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, JdiExceptionReference jdiException = new JdiExceptionReference(((ExceptionEvent) event).exception(), ((ExceptionEvent) event).catchLocation() == null); context.getExceptionManager().setException(thread.uniqueID(), jdiException); - context.getThreadCache().addEventThread(thread); + context.getThreadCache().addEventThread(thread, "exception"); context.getProtocolServer().sendEvent(new Events.StoppedEvent("exception", thread.uniqueID())); debugEvent.shouldResume = false; } else { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/RefreshFramesHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/RefreshFramesHandler.java new file mode 100644 index 000000000..b91daaf80 --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/RefreshFramesHandler.java @@ -0,0 +1,136 @@ +/******************************************************************************* +* Copyright (c) 2023 Microsoft Corporation and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Microsoft Corporation - initial API and implementation +*******************************************************************************/ + +package com.microsoft.java.debug.core.adapter.handler; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CompletableFuture; + +import com.microsoft.java.debug.core.AsyncJdwpUtils; +import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; +import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; +import com.microsoft.java.debug.core.protocol.Events.StoppedEvent; +import com.microsoft.java.debug.core.protocol.Messages.Response; +import com.microsoft.java.debug.core.protocol.Requests.Arguments; +import com.microsoft.java.debug.core.protocol.Requests.Command; +import com.microsoft.java.debug.core.protocol.Requests.RefreshFramesArguments; +import com.sun.jdi.ObjectCollectedException; +import com.sun.jdi.ThreadReference; + +public class RefreshFramesHandler implements IDebugRequestHandler { + + @Override + public List getTargetCommands() { + return Arrays.asList(Command.REFRESHFRAMES); + } + + @Override + public CompletableFuture handle(Command command, Arguments arguments, Response response, + IDebugAdapterContext context) { + RefreshFramesArguments refreshArgs = (RefreshFramesArguments) arguments; + String[] affectedRootPaths = refreshArgs == null ? null : refreshArgs.affectedRootPaths; + List pausedThreads = getPausedThreads(context); + for (long threadId : pausedThreads) { + if (affectedRootPaths == null || affectedRootPaths.length == 0) { + refreshFrames(threadId, context); + continue; + } + + Set decompiledClasses = context.getThreadCache().getDecompiledClassesByThread(threadId); + if (decompiledClasses == null || decompiledClasses.isEmpty()) { + continue; + } + + if (anyInAffectedRootPaths(decompiledClasses, affectedRootPaths)) { + refreshFrames(threadId, context); + } + } + + return CompletableFuture.completedFuture(response); + } + + List getPausedThreads(IDebugAdapterContext context) { + List results = new ArrayList<>(); + List> futures = new ArrayList<>(); + List threads = context.getThreadCache().visibleThreads(context); + for (ThreadReference thread : threads) { + if (context.asyncJDWP()) { + futures.add(AsyncJdwpUtils.supplyAsync(() -> { + try { + if (thread.isSuspended()) { + return thread.uniqueID(); + } + } catch (ObjectCollectedException ex) { + // Ignore it if the thread is garbage collected. + } + + return -1L; + })); + } else { + try { + if (thread.isSuspended()) { + results.add(thread.uniqueID()); + } + } catch (ObjectCollectedException ex) { + // Ignore it if the thread is garbage collected. + } + } + } + + List awaitedResutls = AsyncJdwpUtils.await(futures); + for (Long threadId : awaitedResutls) { + if (threadId > 0) { + results.add(threadId); + } + } + + return results; + } + + /** + * See https://github.com/microsoft/vscode/issues/188606, + * VS Code doesn't provide a simple way to refetch the stack frames. + * We're going to resend a thread stopped event to trick the client + * into refetching the thread stack frames. + */ + void refreshFrames(long threadId, IDebugAdapterContext context) { + StoppedEvent stoppedEvent = new StoppedEvent(context.getThreadCache().getThreadStoppedReason(threadId), threadId); + stoppedEvent.preserveFocusHint = true; + context.getProtocolServer().sendEvent(stoppedEvent); + } + + boolean anyInAffectedRootPaths(Collection classes, String[] affectedRootPaths) { + if (affectedRootPaths == null || affectedRootPaths.length == 0) { + return true; + } + + for (String classUri : classes) { + // decompiled class uri is like 'jdt://contents/rt.jar/java.io/PrintStream.class?=1.helloworld/%5C/usr%5C/lib%5C/jvm%5C/ + // java-8-oracle%5C/jre%5C/lib%5C/rt.jar%3Cjava.io(PrintStream.class'. + if (classUri.startsWith("jdt://contents/")) { + String jarName = classUri.substring("jdt://contents/".length()); + int sep = jarName.indexOf("/"); + jarName = sep >= 0 ? jarName.substring(0, sep) : jarName; + for (String affectedRootPath : affectedRootPaths) { + if (affectedRootPath.endsWith("/" + jarName) || affectedRootPath.endsWith("\\" + jarName)) { + return true; + } + } + } + } + + return false; + } +} diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/RestartFrameHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/RestartFrameHandler.java index 2023209f4..164909656 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/RestartFrameHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/RestartFrameHandler.java @@ -122,6 +122,7 @@ private void stepInto(IDebugAdapterContext context, ThreadReference thread) { // Have to send two events to keep the UI sync with the step in operations: context.getProtocolServer().sendEvent(new Events.ContinuedEvent(thread.uniqueID())); context.getProtocolServer().sendEvent(new Events.StoppedEvent("restartframe", thread.uniqueID())); + context.getThreadCache().setThreadStoppedReason(thread.uniqueID(), "restartframe"); }); request.enable(); thread.resume(); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java index a8774ad37..09dafd1b0 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java @@ -211,14 +211,14 @@ private void registerBreakpointHandler(IDebugAdapterContext context) { if (resume) { debugEvent.eventSet.resume(); } else { - context.getThreadCache().addEventThread(bpThread); + context.getThreadCache().addEventThread(bpThread, breakpointName); context.getProtocolServer().sendEvent(new Events.StoppedEvent( breakpointName, bpThread.uniqueID())); } }); }); } else { - context.getThreadCache().addEventThread(bpThread); + context.getThreadCache().addEventThread(bpThread, breakpointName); context.getProtocolServer().sendEvent(new Events.StoppedEvent( breakpointName, bpThread.uniqueID())); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetDataBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetDataBreakpointsRequestHandler.java index 6d3e8c0b1..373b1c31b 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetDataBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetDataBreakpointsRequestHandler.java @@ -151,13 +151,13 @@ private void registerWatchpointHandler(IDebugAdapterContext context) { if (resume) { debugEvent.eventSet.resume(); } else { - context.getThreadCache().addEventThread(bpThread); + context.getThreadCache().addEventThread(bpThread, "data breakpoint"); context.getProtocolServer().sendEvent(new Events.StoppedEvent("data breakpoint", bpThread.uniqueID())); } }); }); } else { - context.getThreadCache().addEventThread(bpThread); + context.getThreadCache().addEventThread(bpThread, "data breakpoint"); context.getProtocolServer().sendEvent(new Events.StoppedEvent("data breakpoint", bpThread.uniqueID())); } debugEvent.shouldResume = false; diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetFunctionBreakpointsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetFunctionBreakpointsRequestHandler.java index 59a948d37..96a0e395b 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetFunctionBreakpointsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetFunctionBreakpointsRequestHandler.java @@ -165,7 +165,7 @@ private void registerMethodBreakpointHandler(IDebugAdapterContext context) { if (resume) { debugEvent.eventSet.resume(); } else { - context.getThreadCache().addEventThread(bpThread); + context.getThreadCache().addEventThread(bpThread, "function breakpoint"); context.getProtocolServer().sendEvent(new Events.StoppedEvent( "function breakpoint", bpThread.uniqueID())); } @@ -173,7 +173,7 @@ private void registerMethodBreakpointHandler(IDebugAdapterContext context) { }); } else { - context.getThreadCache().addEventThread(bpThread); + context.getThreadCache().addEventThread(bpThread, "function breakpoint"); context.getProtocolServer() .sendEvent(new Events.StoppedEvent("function breakpoint", bpThread.uniqueID())); } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index 6b44d52f5..0ba3b2004 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -15,8 +15,10 @@ import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; +import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; +import java.util.Set; import java.util.concurrent.CancellationException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; @@ -73,16 +75,23 @@ public CompletableFuture handle(Command command, Arguments arguments, response.body = new Responses.StackTraceResponseBody(result, 0); return CompletableFuture.completedFuture(response); } - ThreadReference thread = context.getThreadCache().getThread(stacktraceArgs.threadId); + long threadId = stacktraceArgs.threadId; + ThreadReference thread = context.getThreadCache().getThread(threadId); if (thread == null) { - thread = DebugUtility.getThread(context.getDebugSession(), stacktraceArgs.threadId); + thread = DebugUtility.getThread(context.getDebugSession(), threadId); } int totalFrames = 0; if (thread != null) { + Set decompiledClasses = new LinkedHashSet<>(); try { // Thread state has changed and then invalidate the stack frame cache. if (stacktraceArgs.startFrame == 0) { context.getStackFrameManager().clearStackFrames(thread); + } else { + Set existing = context.getThreadCache().getDecompiledClassesByThread(threadId); + if (existing != null) { + decompiledClasses.addAll(existing); + } } totalFrames = thread.frameCount(); @@ -102,6 +111,10 @@ public CompletableFuture handle(Command command, Arguments arguments, Types.StackFrame lspFrame = convertDebuggerStackFrameToClient(jdiFrame, frameId, i == 0, context); result.add(lspFrame); frameReference.setSource(lspFrame.source); + int jdiLineNumber = AdapterUtils.convertLineNumber(jdiFrame.lineNumber, context.isDebuggerLinesStartAt1(), context.isClientLinesStartAt1()); + if (jdiLineNumber != lspFrame.line) { + decompiledClasses.add(lspFrame.source.path); + } } } catch (IncompatibleThreadStateException | IndexOutOfBoundsException | URISyntaxException | AbsentInformationException | ObjectCollectedException @@ -110,6 +123,8 @@ public CompletableFuture handle(Command command, Arguments arguments, // 1. the vscode has wrong parameter/wrong uri // 2. the thread actually terminates // TODO: should record a error log here. + } finally { + context.getThreadCache().setDecompiledClassesByThread(threadId, decompiledClasses); } } response.body = new Responses.StackTraceResponseBody(result, totalFrames); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index bd324a7fa..71f28355a 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -308,7 +308,7 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, if (threadState.eventSubscription != null) { threadState.eventSubscription.dispose(); } - context.getThreadCache().addEventThread(thread); + context.getThreadCache().addEventThread(thread, "step"); context.getProtocolServer().sendEvent(new Events.StoppedEvent("step", thread.uniqueID())); debugEvent.shouldResume = false; } else if (event instanceof MethodExitEvent) { diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ThreadsRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ThreadsRequestHandler.java index fceac73a5..6573f11da 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ThreadsRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/ThreadsRequestHandler.java @@ -138,6 +138,7 @@ private CompletableFuture pause(Requests.PauseArguments arguments, Res context.getStepResultManager().removeAllMethodResults(); context.getDebugSession().suspend(); context.getProtocolServer().sendEvent(new Events.StoppedEvent("pause", arguments.threadId, true)); + context.getThreadCache().setThreadStoppedReason(arguments.threadId, "pause"); } return CompletableFuture.completedFuture(response); } @@ -158,12 +159,14 @@ private CompletableFuture resume(Requests.ContinueArguments arguments, context.getStepResultManager().removeMethodResult(arguments.threadId); context.getExceptionManager().removeException(arguments.threadId); allThreadsContinued = false; + context.getThreadCache().clearThreadStoppedState(arguments.threadId); DebugUtility.resumeThread(thread); context.getStackFrameManager().clearStackFrames(thread); checkThreadRunningAndRecycleIds(thread, context); } else { context.getStepResultManager().removeAllMethodResults(); context.getExceptionManager().removeAllExceptions(); + context.getThreadCache().clearAllThreadStoppedState(); resumeVM(context); context.getStackFrameManager().clearStackFrames(); context.getRecyclableIdPool().removeAllObjects(); @@ -175,6 +178,7 @@ private CompletableFuture resume(Requests.ContinueArguments arguments, private CompletableFuture resumeAll(Requests.ThreadOperationArguments arguments, Response response, IDebugAdapterContext context) { context.getStepResultManager().removeAllMethodResults(); context.getExceptionManager().removeAllExceptions(); + context.getThreadCache().clearAllThreadStoppedState(); resumeVM(context); context.getProtocolServer().sendEvent(new Events.ContinuedEvent(arguments.threadId, true)); context.getStackFrameManager().clearStackFrames(); @@ -190,6 +194,7 @@ private CompletableFuture resumeOthers(Requests.ThreadOperationArgumen continue; } + context.getThreadCache().clearThreadStoppedState(thread.uniqueID()); if (context.asyncJDWP()) { futures.add(AsyncJdwpUtils.runAsync(() -> resumeThread(thread, context))); } else { @@ -203,6 +208,7 @@ private CompletableFuture resumeOthers(Requests.ThreadOperationArgumen private CompletableFuture pauseAll(Requests.ThreadOperationArguments arguments, Response response, IDebugAdapterContext context) { context.getDebugSession().suspend(); context.getProtocolServer().sendEvent(new Events.StoppedEvent("pause", arguments.threadId, true)); + context.getThreadCache().setThreadStoppedReason(arguments.threadId, "pause"); return CompletableFuture.completedFuture(response); } @@ -300,6 +306,7 @@ private void pauseThread(ThreadReference thread, IDebugAdapterContext context) { context.getStepResultManager().removeMethodResult(threadId); thread.suspend(); context.getProtocolServer().sendEvent(new Events.StoppedEvent("pause", threadId)); + context.getThreadCache().setThreadStoppedReason(threadId, "pause"); } } catch (ObjectCollectedException ex) { // the thread is garbage collected. diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Events.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Events.java index 1973444b6..e692e9b8d 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Events.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Events.java @@ -38,6 +38,11 @@ public static class StoppedEvent extends DebugEvent { public String description; public String text; public boolean allThreadsStopped; + /** + * A value of true hints to the client that this event should not change the + * focus. + */ + public Boolean preserveFocusHint; /** * Constructor. diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Requests.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Requests.java index 09de7bfd9..1129d230e 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Requests.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/protocol/Requests.java @@ -426,6 +426,15 @@ public static class BreakpointLocationsArguments extends Arguments { public int endColumn; } + public static class RefreshFramesArguments extends Arguments { + /** + * If provided, refresh the stack frames of the paused threads that previously + * requested decompiled sources for classes in the affected root paths. + * Otherwise, refresh all paused threads. + */ + public String[] affectedRootPaths; + } + public static enum Command { INITIALIZE("initialize", InitializeArguments.class), LAUNCH("launch", LaunchArguments.class), @@ -464,6 +473,7 @@ public static enum Command { REFRESHVARIABLES("refreshVariables", RefreshVariablesArguments.class), PROCESSID("processId", Arguments.class), BREAKPOINTLOCATIONS("breakpointLocations", BreakpointLocationsArguments.class), + REFRESHFRAMES("refreshFrames", RefreshFramesArguments.class), UNSUPPORTED("", Arguments.class); private String command; From 1d76af515d6926db737f89438c056c2d0d2150df Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Mon, 31 Jul 2023 12:13:50 +0800 Subject: [PATCH 12/72] Bump version to 0.48.0 (#502) --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/.classpath | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 4 ++-- com.microsoft.java.debug.plugin/pom.xml | 4 ++-- com.microsoft.java.debug.repository/category.xml | 2 +- com.microsoft.java.debug.repository/pom.xml | 2 +- com.microsoft.java.debug.target/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 3b1d57547..8ebf3fb5f 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.47.0 + 0.48.0 com.microsoft.java.debug.core jar diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index 5c303928d..2f7e62dc3 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -11,6 +11,6 @@ - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 0965d8ed5..520d7d0da 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true -Bundle-Version: 0.47.0 +Bundle-Version: 0.48.0 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.11.0.jar, ., lib/rxjava-2.2.21.jar, lib/reactive-streams-1.0.4.jar, - lib/com.microsoft.java.debug.core-0.47.0.jar + lib/com.microsoft.java.debug.core-0.48.0.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index c41c9de3b..e50a7f992 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.47.0 + 0.48.0 com.microsoft.java.debug.plugin eclipse-plugin @@ -56,7 +56,7 @@ com.microsoft.java com.microsoft.java.debug.core - 0.47.0 + 0.48.0 diff --git a/com.microsoft.java.debug.repository/category.xml b/com.microsoft.java.debug.repository/category.xml index 20eac94c8..8cf6b4f60 100644 --- a/com.microsoft.java.debug.repository/category.xml +++ b/com.microsoft.java.debug.repository/category.xml @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.repository/pom.xml b/com.microsoft.java.debug.repository/pom.xml index 665b94a6a..27132434c 100644 --- a/com.microsoft.java.debug.repository/pom.xml +++ b/com.microsoft.java.debug.repository/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.47.0 + 0.48.0 com.microsoft.java.debug.repository eclipse-repository diff --git a/com.microsoft.java.debug.target/pom.xml b/com.microsoft.java.debug.target/pom.xml index 6e22d46ab..c7fcc1716 100644 --- a/com.microsoft.java.debug.target/pom.xml +++ b/com.microsoft.java.debug.target/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.47.0 + 0.48.0 com.microsoft.java.debug.tp ${base.name} :: Target Platform diff --git a/pom.xml b/pom.xml index c296ce2c1..55e421c19 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ${base.name} :: Parent The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug - 0.47.0 + 0.48.0 pom Java Debug Server for Visual Studio Code From 5174aa3744281ad05531c1c1984631e2ff1c68de Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Fri, 4 Aug 2023 16:12:49 +0800 Subject: [PATCH 13/72] Only build main project for build server project (#503) * Only build main project for build server project * Add a dedicated error code for build server --------- Signed-off-by: Sheng Chen --- .../java/debug/plugin/internal/Compile.java | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 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 415456ce5..d38227785 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 @@ -18,9 +18,11 @@ import java.util.logging.Logger; import org.apache.commons.lang3.StringUtils; +import org.eclipse.core.resources.IBuildConfiguration; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceStatus; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.resources.ResourcesPlugin; @@ -40,7 +42,42 @@ public class Compile { private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); - public static BuildWorkspaceStatus compile(CompileParams params, IProgressMonitor monitor) { + 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) { + try { + // Q: is infer project by main class name necessary? perf impact? + List 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); + } + } + + if (isBspProject(mainProject)) { + // Just need to trigger a build for the target project, the Gradle build server will + // handle the build dependencies for us. + try { + ResourcesPlugin.getWorkspace().build( + new IBuildConfiguration[]{mainProject.getActiveBuildConfig()}, + IncrementalProjectBuilder.INCREMENTAL_BUILD, + false /*buildReference*/, + monitor + ); + } catch (CoreException e) { + if (e.getStatus().getCode() == IResourceStatus.BUILD_FAILED) { + return GRADLE_BS_COMPILATION_ERROR; + } else { + return BuildWorkspaceStatus.FAILED; + } + } + return BuildWorkspaceStatus.SUCCEED; + } + try { if (monitor.isCanceled()) { return BuildWorkspaceStatus.CANCELLED; @@ -55,7 +92,6 @@ public static BuildWorkspaceStatus compile(CompileParams params, IProgressMonito } logger.info("Time cost for ECJ: " + (System.currentTimeMillis() - compileAt) + "ms"); - IProject mainProject = params == null ? null : ProjectUtils.getProject(params.getProjectName()); IResource currentResource = mainProject; if (isUnmanagedFolder(mainProject) && StringUtils.isNotBlank(params.getMainClass())) { IType mainType = ProjectUtils.getJavaProject(mainProject).findType(params.getMainClass()); @@ -117,6 +153,11 @@ 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); } From 0e03327569c18a83d0c56f63bbb80ba404bb20b3 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Tue, 15 Aug 2023 12:46:31 +0800 Subject: [PATCH 14/72] Code completion: Use fully qualified name as needed in DEBUG CONSOLE (#504) --- .../internal/CompletionProposalRequestor.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java index be7932992..41b4da929 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java @@ -45,6 +45,7 @@ import org.eclipse.jdt.ls.core.internal.handlers.CompletionResponses; import org.eclipse.lsp4j.CompletionItem; import org.eclipse.lsp4j.CompletionItemKind; +import org.eclipse.lsp4j.CompletionItemLabelDetails; import com.google.common.collect.ImmutableSet; import com.microsoft.java.debug.core.Configuration; @@ -159,6 +160,8 @@ public CompletionItem toCompletionItem(CompletionProposal proposal, int index) { data.put(CompletionResolveHandler.DATA_FIELD_PROPOSAL_ID, String.valueOf(index)); $.setData(data); this.descriptionProvider.updateDescription(proposal, $); + // Use fully qualified name as needed. + $.setInsertText(String.valueOf(proposal.getCompletion())); adjustCompleteItem($); $.setSortText(SortTextHelper.computeSortText(proposal)); return $; @@ -166,6 +169,17 @@ public CompletionItem toCompletionItem(CompletionProposal proposal, int index) { private void adjustCompleteItem(CompletionItem item) { if (item.getKind() == CompletionItemKind.Function) { + // Merge the label details into the label property + // because the completion provider in DEBUG CONSOLE + // doesn't support the label details. + CompletionItemLabelDetails labelDetails = item.getLabelDetails(); + if (labelDetails != null && StringUtils.isNotBlank(labelDetails.getDetail())) { + item.setLabel(item.getLabel() + labelDetails.getDetail()); + } + if (labelDetails != null && StringUtils.isNotBlank(labelDetails.getDescription())) { + item.setLabel(item.getLabel() + " : " + labelDetails.getDescription()); + } + String text = item.getInsertText(); if (StringUtils.isNotBlank(text) && !text.endsWith(")")) { item.setInsertText(text + "()"); From f8b6db6eea40a6faab6be9c8ec8a8844584533ac Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Thu, 17 Aug 2023 14:35:42 +0800 Subject: [PATCH 15/72] Display the package name in the label property when suggesting types in DEBUG CONSOLE (#505) --- .../internal/CompletionProposalRequestor.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java index 41b4da929..1df752f24 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java @@ -28,6 +28,7 @@ import org.eclipse.jdt.core.CompletionContext; import org.eclipse.jdt.core.CompletionProposal; import org.eclipse.jdt.core.CompletionRequestor; +import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaElement; @@ -154,7 +155,7 @@ public List getCompletionItems() { */ public CompletionItem toCompletionItem(CompletionProposal proposal, int index) { final CompletionItem $ = new CompletionItem(); - $.setKind(mapKind(proposal.getKind())); + $.setKind(mapKind(proposal.getKind(), proposal.getFlags())); Map data = new HashMap<>(); data.put(CompletionResolveHandler.DATA_FIELD_REQUEST_ID, String.valueOf(response.getId())); data.put(CompletionResolveHandler.DATA_FIELD_PROPOSAL_ID, String.valueOf(index)); @@ -168,7 +169,15 @@ public CompletionItem toCompletionItem(CompletionProposal proposal, int index) { } private void adjustCompleteItem(CompletionItem item) { - if (item.getKind() == CompletionItemKind.Function) { + CompletionItemKind itemKind = item.getKind(); + if (itemKind == CompletionItemKind.Class || itemKind == CompletionItemKind.Interface + || itemKind == CompletionItemKind.Enum) { + // Display the package name in the label property. + CompletionItemLabelDetails labelDetails = item.getLabelDetails(); + if (labelDetails != null && StringUtils.isNotBlank(labelDetails.getDescription())) { + item.setLabel(item.getLabel() + " - " + labelDetails.getDescription()); + } + } else if (itemKind == CompletionItemKind.Function) { // Merge the label details into the label property // because the completion provider in DEBUG CONSOLE // doesn't support the label details. @@ -195,7 +204,7 @@ public void acceptContext(CompletionContext context) { this.descriptionProvider = new CompletionProposalDescriptionProvider(context); } - private CompletionItemKind mapKind(final int kind) { + private CompletionItemKind mapKind(final int kind, final int flags) { // When a new CompletionItemKind is added, don't forget to update // SUPPORTED_KINDS switch (kind) { @@ -204,6 +213,11 @@ private CompletionItemKind mapKind(final int kind) { return CompletionItemKind.Constructor; case CompletionProposal.ANONYMOUS_CLASS_DECLARATION: case CompletionProposal.TYPE_REF: + if (Flags.isInterface(flags)) { + return CompletionItemKind.Interface; + } else if (Flags.isEnum(flags)) { + return CompletionItemKind.Enum; + } return CompletionItemKind.Class; case CompletionProposal.FIELD_IMPORT: case CompletionProposal.METHOD_IMPORT: @@ -213,6 +227,9 @@ private CompletionItemKind mapKind(final int kind) { return CompletionItemKind.Module; case CompletionProposal.FIELD_REF: case CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER: + if (Flags.isStatic(flags) && Flags.isFinal(flags)) { + return CompletionItemKind.Constant; + } return CompletionItemKind.Field; case CompletionProposal.KEYWORD: return CompletionItemKind.Keyword; From c0e8f92f54defe9af77c6d091bb96a57ff114ac1 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Mon, 28 Aug 2023 11:33:14 +0800 Subject: [PATCH 16/72] bump version to 0.49.0 (#506) --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/.classpath | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 4 ++-- com.microsoft.java.debug.plugin/pom.xml | 4 ++-- com.microsoft.java.debug.repository/category.xml | 2 +- com.microsoft.java.debug.repository/pom.xml | 2 +- com.microsoft.java.debug.target/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 8ebf3fb5f..5412d44a4 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.48.0 + 0.49.0 com.microsoft.java.debug.core jar diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index 2f7e62dc3..c2b013548 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -11,6 +11,6 @@ - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 520d7d0da..cdc8e2f81 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true -Bundle-Version: 0.48.0 +Bundle-Version: 0.49.0 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.11.0.jar, ., lib/rxjava-2.2.21.jar, lib/reactive-streams-1.0.4.jar, - lib/com.microsoft.java.debug.core-0.48.0.jar + lib/com.microsoft.java.debug.core-0.49.0.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index e50a7f992..7fd392bbe 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.48.0 + 0.49.0 com.microsoft.java.debug.plugin eclipse-plugin @@ -56,7 +56,7 @@ com.microsoft.java com.microsoft.java.debug.core - 0.48.0 + 0.49.0 diff --git a/com.microsoft.java.debug.repository/category.xml b/com.microsoft.java.debug.repository/category.xml index 8cf6b4f60..dc3efd066 100644 --- a/com.microsoft.java.debug.repository/category.xml +++ b/com.microsoft.java.debug.repository/category.xml @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.repository/pom.xml b/com.microsoft.java.debug.repository/pom.xml index 27132434c..0adda64ab 100644 --- a/com.microsoft.java.debug.repository/pom.xml +++ b/com.microsoft.java.debug.repository/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.48.0 + 0.49.0 com.microsoft.java.debug.repository eclipse-repository diff --git a/com.microsoft.java.debug.target/pom.xml b/com.microsoft.java.debug.target/pom.xml index c7fcc1716..cfae4adb8 100644 --- a/com.microsoft.java.debug.target/pom.xml +++ b/com.microsoft.java.debug.target/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.48.0 + 0.49.0 com.microsoft.java.debug.tp ${base.name} :: Target Platform diff --git a/pom.xml b/pom.xml index 55e421c19..c71560b64 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ${base.name} :: Parent The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug - 0.48.0 + 0.49.0 pom Java Debug Server for Visual Studio Code From 8905c4a7367991a492ba280d8ba616f73fdea557 Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Tue, 19 Sep 2023 00:51:18 -0700 Subject: [PATCH 17/72] Special handling build only when it's build server project and not buildship project (#511) Signed-off-by: Sheng Chen --- .../java/com/microsoft/java/debug/plugin/internal/Compile.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/Compile.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/Compile.java index d38227785..9cb6fbbfa 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)) { + if (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 { From 4f42baa62997c29507f930e009f28d4453f59596 Mon Sep 17 00:00:00 2001 From: Vladimir Makaev Date: Tue, 26 Sep 2023 09:50:31 +0100 Subject: [PATCH 18/72] Add extensibility points to DebugAdapter and ProtocolServer (#509) Co-authored-by: Vladimir Makayev Co-authored-by: Jinbo Wang --- .../java/debug/core/adapter/DebugAdapter.java | 9 +++++---- .../core/adapter/IDebugAdapterFactory.java | 19 +++++++++++++++++++ .../debug/core/adapter/ProtocolServer.java | 14 ++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapterFactory.java diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java index 10c0df902..8f595151f 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapter.java @@ -102,7 +102,7 @@ public CompletableFuture dispatchRequest(Messages.Request req } } - private void initialize() { + protected void initialize() { // Register request handlers. // When there are multiple handlers registered for the same request, follow the rule "first register, first execute". registerHandler(new InitializeRequestHandler()); @@ -141,15 +141,15 @@ private void initialize() { registerHandlerForNoDebug(new ProcessIdHandler()); } - private void registerHandlerForDebug(IDebugRequestHandler handler) { + protected void registerHandlerForDebug(IDebugRequestHandler handler) { registerHandler(requestHandlersForDebug, handler); } - private void registerHandlerForNoDebug(IDebugRequestHandler handler) { + protected void registerHandlerForNoDebug(IDebugRequestHandler handler) { registerHandler(requestHandlersForNoDebug, handler); } - private void registerHandler(IDebugRequestHandler handler) { + protected void registerHandler(IDebugRequestHandler handler) { registerHandler(requestHandlersForDebug, handler); registerHandler(requestHandlersForNoDebug, handler); } @@ -165,4 +165,5 @@ private void registerHandler(Map> requestHan handlerList.add(handler); } } + } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapterFactory.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapterFactory.java new file mode 100644 index 000000000..d392d3b48 --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapterFactory.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2023 Microsoft Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Microsoft Corporation - initial API and implementation +*******************************************************************************/ + +package com.microsoft.java.debug.core.adapter; + +import com.microsoft.java.debug.core.protocol.IProtocolServer; + +@FunctionalInterface +public interface IDebugAdapterFactory { + public IDebugAdapter create(IProtocolServer server); +} diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java index 0526293b9..9e503e0af 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ProtocolServer.java @@ -52,6 +52,20 @@ public ProtocolServer(InputStream input, OutputStream output, IProviderContext c debugAdapter = new DebugAdapter(this, context); } + /** + * Constructs a protocol server instance based on the given input stream and output stream. + * @param input + * the input stream + * @param output + * the output stream + * @param debugAdapterFactory + * factory to create debug adapter that implements DAP communication + */ + public ProtocolServer(InputStream input, OutputStream output, IDebugAdapterFactory debugAdapterFactory) { + super(input, output); + debugAdapter = debugAdapterFactory.create(this); + } + /** * A while-loop to parse input data and send output data constantly. */ From 488a56ef9fe4c8766b47af6443986936283e1b7f Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Wed, 1 Nov 2023 14:02:42 +0800 Subject: [PATCH 19/72] Bump version to 0.50.0 (#516) --- .mvn/wrapper/maven-wrapper.properties | 2 +- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/.classpath | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 4 ++-- com.microsoft.java.debug.plugin/pom.xml | 4 ++-- com.microsoft.java.debug.repository/category.xml | 2 +- com.microsoft.java.debug.repository/pom.xml | 2 +- .../com.microsoft.java.debug.tp.target | 4 ++-- com.microsoft.java.debug.target/pom.xml | 2 +- pom.xml | 4 ++-- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 56bb0164e..9e0264d04 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1 +1 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip \ No newline at end of file +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.3/apache-maven-3.9.3-bin.zip \ No newline at end of file diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 5412d44a4..635993d56 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.49.0 + 0.50.0 com.microsoft.java.debug.core jar diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index c2b013548..ca5f41e6f 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -11,6 +11,6 @@ - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index cdc8e2f81..84a0ab36f 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true -Bundle-Version: 0.49.0 +Bundle-Version: 0.50.0 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.11.0.jar, ., lib/rxjava-2.2.21.jar, lib/reactive-streams-1.0.4.jar, - lib/com.microsoft.java.debug.core-0.49.0.jar + lib/com.microsoft.java.debug.core-0.50.0.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index 7fd392bbe..b895ffd28 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.49.0 + 0.50.0 com.microsoft.java.debug.plugin eclipse-plugin @@ -56,7 +56,7 @@ com.microsoft.java com.microsoft.java.debug.core - 0.49.0 + 0.50.0 diff --git a/com.microsoft.java.debug.repository/category.xml b/com.microsoft.java.debug.repository/category.xml index dc3efd066..639d50082 100644 --- a/com.microsoft.java.debug.repository/category.xml +++ b/com.microsoft.java.debug.repository/category.xml @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.repository/pom.xml b/com.microsoft.java.debug.repository/pom.xml index 0adda64ab..4f05eb331 100644 --- a/com.microsoft.java.debug.repository/pom.xml +++ b/com.microsoft.java.debug.repository/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.49.0 + 0.50.0 com.microsoft.java.debug.repository eclipse-repository diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index fbc981533..1c10398c4 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -16,11 +16,11 @@ - + - + diff --git a/com.microsoft.java.debug.target/pom.xml b/com.microsoft.java.debug.target/pom.xml index cfae4adb8..80395f6dd 100644 --- a/com.microsoft.java.debug.target/pom.xml +++ b/com.microsoft.java.debug.target/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.49.0 + 0.50.0 com.microsoft.java.debug.tp ${base.name} :: Target Platform diff --git a/pom.xml b/pom.xml index c71560b64..d562f82b5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,12 +6,12 @@ ${base.name} :: Parent The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug - 0.49.0 + 0.50.0 pom Java Debug Server for Visual Studio Code UTF-8 - 2.7.3 + 4.0.3 ${basedir} From b0c70e3ddbf8cca9dc697f02f84914d7792b5982 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Tue, 21 Nov 2023 18:01:28 +0800 Subject: [PATCH 20/72] Update target platform dependencies to fix build errors (#518) --- .../com.microsoft.java.debug.tp.target | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index 1c10398c4..ef0a5284e 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -16,11 +16,8 @@ - - - - + From 39046b7ab8b1acc47894745f517fcd5fe010cf64 Mon Sep 17 00:00:00 2001 From: John Olson <69521422+olsonjohn@users.noreply.github.com> Date: Sun, 10 Dec 2023 20:21:59 -0600 Subject: [PATCH 21/72] updated dependency location (#528) --- .../com.microsoft.java.debug.tp.target | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index ef0a5284e..2e7920ed7 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -17,7 +17,7 @@ - + @@ -32,4 +32,4 @@ - \ No newline at end of file + From 27f72fbdf79097794d8a546a1206e620ecdde863 Mon Sep 17 00:00:00 2001 From: Gayan Perera Date: Tue, 12 Dec 2023 03:24:24 +0100 Subject: [PATCH 22/72] Fix generic return type lambda breakpoint issue. Fix #1359 (#499) * Fix generic return type lambda breakpoint issue. Fix #1359 The fix tries to compare the runtime lambda method signature with none generic version of the method signature found from AST traversal as a additional comparison to what is there. --- .../microsoft/java/debug/core/Breakpoint.java | 25 ++++++++++++++++++- .../java/debug/core/BreakpointTest.java | 17 +++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 com.microsoft.java.debug.core/src/test/java/com/microsoft/java/debug/core/BreakpointTest.java diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/Breakpoint.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/Breakpoint.java index dfdbad4bb..82859b268 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/Breakpoint.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/Breakpoint.java @@ -325,7 +325,8 @@ private Location findMethodLocaiton(ReferenceType refType, String methodName, St for (Method method : methods) { if (!method.isAbstract() && !method.isNative() && methodName.equals(method.name()) - && (methodSiguature.equals(method.genericSignature()) || methodSiguature.equals(method.signature()))) { + && (methodSiguature.equals(method.genericSignature()) || methodSiguature.equals(method.signature()) + || toNoneGeneric(methodSiguature).equals(method.signature()))) { location = method.location(); break; } @@ -334,6 +335,28 @@ private Location findMethodLocaiton(ReferenceType refType, String methodName, St return location; } + static String toNoneGeneric(String genericSig) { + StringBuilder builder = new StringBuilder(); + boolean append = true; + int depth = 0; + char[] chars = genericSig.toCharArray(); + for (int i = 0; i < chars.length; i++) { + char c = chars[i]; + if (c == '<') { + depth++; + append = (depth == 0); + } + if (append) { + builder.append(c); + } + if (c == '>') { + depth--; + append = (depth == 0); + } + } + return builder.toString(); + } + private List findLocaitonsOfLine(Method method, int lineNumber) { try { return method.locationsOfLine(lineNumber); diff --git a/com.microsoft.java.debug.core/src/test/java/com/microsoft/java/debug/core/BreakpointTest.java b/com.microsoft.java.debug.core/src/test/java/com/microsoft/java/debug/core/BreakpointTest.java new file mode 100644 index 000000000..5cc6fa3d7 --- /dev/null +++ b/com.microsoft.java.debug.core/src/test/java/com/microsoft/java/debug/core/BreakpointTest.java @@ -0,0 +1,17 @@ +package com.microsoft.java.debug.core; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class BreakpointTest { + @Test + public void testToNoneGeneric() { + assertEquals("Ljava.util.List;", Breakpoint.toNoneGeneric("Ljava.util.List;")); + assertEquals("(Ljava/util/Map;)Ljava/util/Map;", Breakpoint.toNoneGeneric( + "(Ljava/util/Map;>;)Ljava/util/Map;>;")); + assertEquals("(Ljava/util/Map;)Ljava/util/Map;", + Breakpoint.toNoneGeneric( + "(Ljava/util/Map;Ljava/util/List;>;)Ljava/util/Map;Ljava/util/List;>;")); + } +} From 9bdd9977860e5912a39b8efbaf62b9ee5577ec98 Mon Sep 17 00:00:00 2001 From: Gayan Perera Date: Wed, 13 Dec 2023 02:54:30 +0100 Subject: [PATCH 23/72] Improve inline breakpoint discovery when expression is multiline. Fix #521 (#522) * Improve inline breakpoint discovery when expression is multiline. Fix #521 --- .../microsoft/java/debug/BreakpointLocationLocator.java | 4 ++-- .../debug/plugin/internal/JdtSourceLookUpProvider.java | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/BreakpointLocationLocator.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/BreakpointLocationLocator.java index b14afde83..97581242e 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/BreakpointLocationLocator.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/BreakpointLocationLocator.java @@ -22,8 +22,8 @@ public class BreakpointLocationLocator public BreakpointLocationLocator(CompilationUnit compilationUnit, int lineNumber, boolean bindingsResolved, - boolean bestMatch) { - super(compilationUnit, lineNumber, bindingsResolved, bestMatch); + boolean bestMatch, int offset, int end) { + super(compilationUnit, lineNumber, bindingsResolved, bestMatch, offset, end); } @Override diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java index f0c8795cc..1ebf4c7c3 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java @@ -72,8 +72,8 @@ import com.microsoft.java.debug.core.Configuration; import com.microsoft.java.debug.core.DebugException; import com.microsoft.java.debug.core.DebugSettings; -import com.microsoft.java.debug.core.JavaBreakpointLocation; import com.microsoft.java.debug.core.DebugSettings.Switch; +import com.microsoft.java.debug.core.JavaBreakpointLocation; import com.microsoft.java.debug.core.adapter.AdapterUtils; import com.microsoft.java.debug.core.adapter.Constants; import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; @@ -210,8 +210,11 @@ public JavaBreakpointLocation[] getBreakpointLocations(String sourceUri, SourceB // mark it as "unverified". // In future, we could consider supporting to update the breakpoint to a valid // location. + + // passing the offset to the constructor, it can recognize the multiline lambda + // expression well BreakpointLocationLocator locator = new BreakpointLocationLocator(astUnit, - sourceLine, true, true); + sourceLine, true, true, astUnit.getPosition(sourceLine, 0), 0); astUnit.accept(locator); // When the final valid line location is same as the original line, that // represents it's a valid breakpoint. From f8da9e2e2f55a2cefaf658ae24154c784eaa113e Mon Sep 17 00:00:00 2001 From: Vladimir Makaev Date: Mon, 8 Jan 2024 03:22:46 +0000 Subject: [PATCH 24/72] Allow ISourceLookUpProvider specify whether file is Local or Remote (#515) --- .../core/adapter/DebugAdapterContext.java | 4 +-- .../core/adapter/IDebugAdapterContext.java | 2 +- .../core/adapter/ISourceLookUpProvider.java | 28 ++++++++++----- .../java/debug/core/adapter/Source.java | 30 ++++++++++++++++ .../java/debug/core/adapter/SourceType.java | 16 +++++++++ .../handler/StackTraceRequestHandler.java | 35 +++++++++++++------ 6 files changed, 93 insertions(+), 22 deletions(-) create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/Source.java create mode 100644 com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/SourceType.java diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapterContext.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapterContext.java index f8ac01c3e..bbf215c67 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapterContext.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/DebugAdapterContext.java @@ -32,7 +32,7 @@ public class DebugAdapterContext implements IDebugAdapterContext { private static final int MAX_CACHE_ITEMS = 10000; private final StepFilters defaultFilters = new StepFilters(); - private Map sourceMappingCache = Collections.synchronizedMap(new LRUCache<>(MAX_CACHE_ITEMS)); + private Map sourceMappingCache = Collections.synchronizedMap(new LRUCache<>(MAX_CACHE_ITEMS)); private IProviderContext providerContext; private IProtocolServer server; @@ -212,7 +212,7 @@ public void setVariableFormatter(IVariableFormatter variableFormatter) { } @Override - public Map getSourceLookupCache() { + public Map getSourceLookupCache() { return sourceMappingCache; } diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapterContext.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapterContext.java index 9a38e8598..e65270eef 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapterContext.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/IDebugAdapterContext.java @@ -85,7 +85,7 @@ public interface IDebugAdapterContext { void setVariableFormatter(IVariableFormatter variableFormatter); - Map getSourceLookupCache(); + Map getSourceLookupCache(); void setDebuggeeEncoding(Charset encoding); diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ISourceLookUpProvider.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ISourceLookUpProvider.java index 5ffed6e0f..f33742852 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ISourceLookUpProvider.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/ISourceLookUpProvider.java @@ -8,7 +8,6 @@ * Contributors: * Microsoft Corporation - initial API and implementation *******************************************************************************/ - package com.microsoft.java.debug.core.adapter; import java.util.List; @@ -42,18 +41,31 @@ public interface ISourceLookUpProvider extends IProvider { JavaBreakpointLocation[] getBreakpointLocations(String sourceUri, SourceBreakpoint[] sourceBreakpoints) throws DebugException; /** - * Given a fully qualified class name and source file path, search the associated disk source file. - * - * @param fullyQualifiedName - * the fully qualified class name (e.g. com.microsoft.java.debug.core.adapter.ISourceLookUpProvider). - * @param sourcePath - * the qualified source file path (e.g. com\microsoft\java\debug\core\adapter\ISourceLookupProvider.java). - * @return the associated source file uri. + * Deprecated, please use {@link #getSource(String, String)} instead. */ + @Deprecated String getSourceFileURI(String fullyQualifiedName, String sourcePath); String getSourceContents(String uri); + /** + * Retrieves a {@link Source} object representing the source code associated with the given fully qualified class name and source file path. + * The implementation of this interface can determine a source is "local" or "remote". + * In case of "remote" a follow up "source" request will be issued by the client + * + * @param fullyQualifiedName + * the fully qualified class name, + * e.g., "com.microsoft.java.debug.core.adapter.ISourceLookUpProvider". + * @param sourcePath + * the qualified source file path, + * e.g., "com/microsoft/java/debug/core/adapter/ISourceLookupProvider.java". + * @return A {@link Source} object encapsulating the source file URI obtained from + * {@link #getSourceFileURI(String, String)} and the source type as {@link SourceType#LOCAL}. + */ + default Source getSource(String fullyQualifiedName, String sourcePath) { + return new Source(getSourceFileURI(fullyQualifiedName, sourcePath), SourceType.LOCAL); + } + /** * Returns the Java runtime that the specified project's build path used. * @param projectName diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/Source.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/Source.java new file mode 100644 index 000000000..d00b4cb4c --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/Source.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2017 Microsoft Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Microsoft Corporation - initial API and implementation + *******************************************************************************/ + +package com.microsoft.java.debug.core.adapter; + +public class Source { + public final String uri; + public final SourceType type; + + public Source(String uri, SourceType type) { + this.uri = uri; + this.type = type; + } + + public String getUri() { + return this.uri; + } + + public SourceType getType() { + return this.type; + } +} diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/SourceType.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/SourceType.java new file mode 100644 index 000000000..724bf3bda --- /dev/null +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/SourceType.java @@ -0,0 +1,16 @@ +/******************************************************************************* + * Copyright (c) 2017 Microsoft Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Microsoft Corporation - initial API and implementation + *******************************************************************************/ +package com.microsoft.java.debug.core.adapter; + +public enum SourceType { + REMOTE, + LOCAL +} diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index 0ba3b2004..49f304771 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -36,6 +36,8 @@ import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; import com.microsoft.java.debug.core.adapter.ISourceLookUpProvider; +import com.microsoft.java.debug.core.adapter.Source; +import com.microsoft.java.debug.core.adapter.SourceType; import com.microsoft.java.debug.core.adapter.formatter.SimpleTypeFormatter; import com.microsoft.java.debug.core.adapter.variables.StackFrameReference; import com.microsoft.java.debug.core.protocol.Messages.Response; @@ -141,7 +143,7 @@ public CompletableFuture handle(Command command, Arguments arguments, } private static List resolveStackFrameInfos(StackFrame[] frames, boolean async) - throws AbsentInformationException, IncompatibleThreadStateException { + throws AbsentInformationException, IncompatibleThreadStateException { List jdiFrames = new ArrayList<>(); List> futures = new ArrayList<>(); for (StackFrame frame : frames) { @@ -221,7 +223,7 @@ private Types.StackFrame convertDebuggerStackFrameToClient(StackFrameInfo jdiFra clientSource = null; } } else if (DebugSettings.getCurrent().debugSupportOnDecompiledSource == Switch.ON - && clientSource != null && clientSource.path != null) { + && clientSource != null && clientSource.path != null) { // Align the original line with the decompiled line. int[] lineMappings = context.getProvider(ISourceLookUpProvider.class).getOriginalLineMappings(clientSource.path); int[] renderLines = AdapterUtils.binarySearchMappedLines(lineMappings, clientLineNumber); @@ -244,7 +246,7 @@ private Types.StackFrame convertDebuggerStackFrameToClient(StackFrameInfo jdiFra }); if (match) { clientColumnNumber = AdapterUtils.convertColumnNumber(breakpoint.getColumnNumber(), - context.isDebuggerColumnsStartAt1(), context.isClientColumnsStartAt1()); + context.isDebuggerColumnsStartAt1(), context.isClientColumnsStartAt1()); } } } @@ -256,33 +258,44 @@ private Types.StackFrame convertDebuggerStackFrameToClient(StackFrameInfo jdiFra /** * Find the source mapping for the specified source file name. */ - public static Types.Source convertDebuggerSourceToClient(String fullyQualifiedName, String sourceName, String relativeSourcePath, + public static Types.Source convertDebuggerSourceToClient(String fullyQualifiedName, String sourceName, + String relativeSourcePath, IDebugAdapterContext context) throws URISyntaxException { + // use a lru cache for better performance - String uri = context.getSourceLookupCache().computeIfAbsent(fullyQualifiedName, key -> { - String fromProvider = context.getProvider(ISourceLookUpProvider.class).getSourceFileURI(key, relativeSourcePath); - // avoid return null which will cause the compute function executed again - return StringUtils.isBlank(fromProvider) ? "" : fromProvider; + Source source = context.getSourceLookupCache().computeIfAbsent(fullyQualifiedName, key -> { + Source result = context.getProvider(ISourceLookUpProvider.class).getSource(key, relativeSourcePath); + if (result == null) { + return new Source("", SourceType.LOCAL); + } + return result; }); + Integer sourceReference = 0; + String uri = source.getUri(); + + if (source.getType().equals(SourceType.REMOTE)) { + sourceReference = context.createSourceReference(source.getUri()); + } + if (!StringUtils.isBlank(uri)) { // The Source.path could be a file system path or uri string. if (uri.startsWith("file:")) { String clientPath = AdapterUtils.convertPath(uri, context.isDebuggerPathsAreUri(), context.isClientPathsAreUri()); - return new Types.Source(sourceName, clientPath, 0); + return new Types.Source(sourceName, clientPath, sourceReference); } else { // If the debugger returns uri in the Source.path for the StackTrace response, VSCode client will try to find a TextDocumentContentProvider // to render the contents. // Language Support for Java by Red Hat extension has already registered a jdt TextDocumentContentProvider to parse the jdt-based uri. // The jdt uri looks like 'jdt://contents/rt.jar/java.io/PrintStream.class?=1.helloworld/%5C/usr%5C/lib%5C/jvm%5C/java-8-oracle%5C/jre%5C/ // lib%5C/rt.jar%3Cjava.io(PrintStream.class'. - return new Types.Source(sourceName, uri, 0); + return new Types.Source(sourceName, uri, sourceReference); } } else { // If the source lookup engine cannot find the source file, then lookup it in the source directories specified by user. String absoluteSourcepath = AdapterUtils.sourceLookup(context.getSourcePaths(), relativeSourcePath); if (absoluteSourcepath != null) { - return new Types.Source(sourceName, absoluteSourcepath, 0); + return new Types.Source(sourceName, absoluteSourcepath, sourceReference); } else { return null; } From b578b50078cef9ce7b37710966bd2c2496c1c00d Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Thu, 18 Jan 2024 15:39:43 +0800 Subject: [PATCH 25/72] Migrate to 1es pipelines (#532) --- .azure-pipelines/signjars-nightly.yml | 146 ++++++++++++++++ .azure-pipelines/signjars-rc.yml | 236 ++++++++++++++++++++++++++ 2 files changed, 382 insertions(+) create mode 100644 .azure-pipelines/signjars-nightly.yml create mode 100644 .azure-pipelines/signjars-rc.yml diff --git a/.azure-pipelines/signjars-nightly.yml b/.azure-pipelines/signjars-nightly.yml new file mode 100644 index 000000000..bdaeea871 --- /dev/null +++ b/.azure-pipelines/signjars-nightly.yml @@ -0,0 +1,146 @@ +name: $(Date:yyyyMMdd).$(Rev:r) +variables: + - name: Codeql.Enabled + value: true +schedules: + - cron: 0 5 * * 1,2,3,4,5 + branches: + include: + - refs/heads/main +resources: + repositories: + - repository: self + type: git + ref: refs/heads/main + - repository: 1esPipelines + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release +trigger: none +extends: + template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines + parameters: + pool: + os: linux + name: 1ES_JavaTooling_Pool + image: 1ES_JavaTooling_Ubuntu-2004 + sdl: + sourceAnalysisPool: + name: 1ES_JavaTooling_Pool + image: 1ES_JavaTooling_Windows_2022 + os: windows + customBuildTags: + - MigrationTooling-mseng-VSJava-13474-Tool + stages: + - stage: Build + jobs: + - job: Job_1 + displayName: Sign-Jars-Nightly + templateContext: + outputs: + - output: pipelineArtifact + artifactName: plugin + targetPath: $(Build.ArtifactStagingDirectory) + displayName: "Publish Artifact: plugin" + steps: + - checkout: self + fetchTags: true + - task: JavaToolInstaller@0 + displayName: Use Java 17 + inputs: + versionSpec: "17" + jdkArchitectureOption: x64 + jdkSourceOption: PreInstalled + - task: CmdLine@2 + displayName: Parse the release version from pom.xml + inputs: + script: |- + #!/bin/bash + + sudo apt-get install xmlstarlet + xmlstarlet --version + RELEASE_VERSION=$(xmlstarlet sel -t -v "/_:project/_:version" pom.xml) + echo $RELEASE_VERSION + echo "##vso[task.setvariable variable=RELEASE_VERSION]$RELEASE_VERSION" + - task: CmdLine@2 + displayName: Build core.jar + inputs: + script: | + ./mvnw clean install -f com.microsoft.java.debug.core/pom.xml -Dmaven.repo.local=./.repository + + mkdir -p jars + mv .repository/com/microsoft/java/com.microsoft.java.debug.core/$RELEASE_VERSION/com.microsoft.java.debug.core*.jar jars/ + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 + displayName: Sign core.jar + inputs: + ConnectedServiceName: vscjavaci_codesign + FolderPath: jars + Pattern: com.microsoft.java.debug.core*.jar + signConfigType: inlineSignParams + inlineOperation: |- + [ + { + "KeyCode" : "CP-447347-Java", + "OperationCode" : "JavaSign", + "Parameters" : { + "SigAlg" : "SHA256withRSA", + "Timestamp" : "-tsa http://sha256timestamp.ws.digicert.com/sha256/timestamp" + }, + "ToolName" : "sign", + "ToolVersion" : "1.0" + }, + { + "KeyCode" : "CP-447347-Java", + "OperationCode" : "JavaVerify", + "Parameters" : {}, + "ToolName" : "sign", + "ToolVersion" : "1.0" + } + ] + - task: CmdLine@2 + displayName: install signed core.jar + inputs: + script: cp jars/com.microsoft.java.debug.core*.jar .repository/com/microsoft/java/com.microsoft.java.debug.core/$RELEASE_VERSION/ + - task: CmdLine@2 + displayName: Build plugin.jar + inputs: + script: |- + ./mvnw clean install -f com.microsoft.java.debug.target/pom.xml -Dmaven.repo.local=./.repository + ./mvnw clean install -f com.microsoft.java.debug.plugin/pom.xml -Dmaven.repo.local=./.repository + + mkdir -p jars + mv .repository/com/microsoft/java/com.microsoft.java.debug.plugin/$RELEASE_VERSION/com.microsoft.java.debug.plugin*.jar jars/ + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 + displayName: Sign plugin.jar + inputs: + ConnectedServiceName: vscjavaci_codesign + FolderPath: jars + Pattern: com.microsoft.java.debug.plugin*.jar + signConfigType: inlineSignParams + inlineOperation: |- + [ + { + "KeyCode" : "CP-447347-Java", + "OperationCode" : "JavaSign", + "Parameters" : { + "SigAlg" : "SHA256withRSA", + "Timestamp" : "-tsa http://sha256timestamp.ws.digicert.com/sha256/timestamp" + }, + "ToolName" : "sign", + "ToolVersion" : "1.0" + }, + { + "KeyCode" : "CP-447347-Java", + "OperationCode" : "JavaVerify", + "Parameters" : {}, + "ToolName" : "sign", + "ToolVersion" : "1.0" + } + ] + - task: CopyFiles@2 + displayName: "Copy plugin.jar to: $(Build.ArtifactStagingDirectory)" + inputs: + Contents: |+ + jars/com.microsoft.java.debug.plugin*.jar + + TargetFolder: $(Build.ArtifactStagingDirectory) diff --git a/.azure-pipelines/signjars-rc.yml b/.azure-pipelines/signjars-rc.yml new file mode 100644 index 000000000..4e51eff7f --- /dev/null +++ b/.azure-pipelines/signjars-rc.yml @@ -0,0 +1,236 @@ +name: $(Date:yyyyMMdd).$(Rev:r) +variables: + - name: Codeql.Enabled + value: true +resources: + repositories: + - repository: self + type: git + ref: refs/heads/main + - repository: 1esPipelines + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release +trigger: none +extends: + template: v1/1ES.Official.PipelineTemplate.yml@1esPipelines + parameters: + pool: + os: linux + name: 1ES_JavaTooling_Pool + image: 1ES_JavaTooling_Ubuntu-2004 + sdl: + sourceAnalysisPool: + name: 1ES_JavaTooling_Pool + image: 1ES_JavaTooling_Windows_2022 + os: windows + customBuildTags: + - MigrationTooling-mseng-VSJava-9151-Tool + stages: + - stage: Build + jobs: + - job: Job_1 + displayName: Sign-Jars-RC + templateContext: + outputs: + - output: pipelineArtifact + artifactName: m2 + targetPath: $(Build.ArtifactStagingDirectory)/m2 + displayName: "Publish Artifact: m2" + - output: pipelineArtifact + artifactName: p2 + targetPath: $(Build.ArtifactStagingDirectory)/p2 + displayName: "Publish Artifact: p2" + steps: + - checkout: self + fetchTags: true + - task: JavaToolInstaller@0 + displayName: Use Java 17 + inputs: + versionSpec: "17" + jdkArchitectureOption: x64 + jdkSourceOption: PreInstalled + - task: CmdLine@2 + displayName: Parse the release version from pom.xml + inputs: + script: |- + #!/bin/bash + + sudo apt-get install xmlstarlet + xmlstarlet --version + RELEASE_VERSION=$(xmlstarlet sel -t -v "/_:project/_:version" pom.xml) + echo $RELEASE_VERSION + echo "##vso[task.setvariable variable=RELEASE_VERSION]$RELEASE_VERSION" + - task: CmdLine@2 + displayName: Build core.jar + inputs: + script: | + ./mvnw -N clean install -Dmaven.repo.local=./.repository + + ./mvnw clean install -f com.microsoft.java.debug.core/pom.xml -Dmaven.repo.local=./.repository + + mkdir -p jars + mv .repository/com/microsoft/java/com.microsoft.java.debug.core/$RELEASE_VERSION/com.microsoft.java.debug.core*.jar jars/ + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 + displayName: Sign core.jar + inputs: + ConnectedServiceName: vscjavaci_codesign + FolderPath: jars + Pattern: com.microsoft.java.debug.core*.jar + signConfigType: inlineSignParams + inlineOperation: |- + [ + { + "KeyCode" : "CP-447347-Java", + "OperationCode" : "JavaSign", + "Parameters" : { + "SigAlg" : "SHA256withRSA", + "Timestamp" : "-tsa http://sha256timestamp.ws.digicert.com/sha256/timestamp" + }, + "ToolName" : "sign", + "ToolVersion" : "1.0" + }, + { + "KeyCode" : "CP-447347-Java", + "OperationCode" : "JavaVerify", + "Parameters" : {}, + "ToolName" : "sign", + "ToolVersion" : "1.0" + } + ] + - task: CmdLine@2 + displayName: install signed core.jar + inputs: + script: cp jars/com.microsoft.java.debug.core*.jar .repository/com/microsoft/java/com.microsoft.java.debug.core/$RELEASE_VERSION/ + - task: CmdLine@2 + displayName: Build plugin.jar + inputs: + script: |- + ./mvnw clean install -f com.microsoft.java.debug.target/pom.xml -Dmaven.repo.local=./.repository + ./mvnw clean install -f com.microsoft.java.debug.plugin/pom.xml -Dmaven.repo.local=./.repository + + mkdir -p jars + mv .repository/com/microsoft/java/com.microsoft.java.debug.plugin/$RELEASE_VERSION/com.microsoft.java.debug.plugin*.jar jars/ + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 + displayName: Sign plugin.jar + inputs: + ConnectedServiceName: vscjavaci_codesign + FolderPath: jars + Pattern: com.microsoft.java.debug.plugin*.jar + signConfigType: inlineSignParams + inlineOperation: |- + [ + { + "KeyCode" : "CP-447347-Java", + "OperationCode" : "JavaSign", + "Parameters" : { + "SigAlg" : "SHA256withRSA", + "Timestamp" : "-tsa http://sha256timestamp.ws.digicert.com/sha256/timestamp" + }, + "ToolName" : "sign", + "ToolVersion" : "1.0" + }, + { + "KeyCode" : "CP-447347-Java", + "OperationCode" : "JavaVerify", + "Parameters" : {}, + "ToolName" : "sign", + "ToolVersion" : "1.0" + } + ] + - task: CmdLine@2 + displayName: install signed plugin.jar + inputs: + script: cp jars/com.microsoft.java.debug.plugin*.jar .repository/com/microsoft/java/com.microsoft.java.debug.plugin/$RELEASE_VERSION/ + - task: CmdLine@2 + displayName: Build p2 artifacts + inputs: + script: |- + # 3. Build the p2 artifacts. + ./mvnw clean package -f com.microsoft.java.debug.repository/pom.xml -Dmaven.repo.local=./.repository + + mkdir -p p2/target + cp -r com.microsoft.java.debug.repository/target/repository p2/target/ + cp com.microsoft.java.debug.repository/pushToBintray.sh p2/ + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 + displayName: Sign p2 + inputs: + ConnectedServiceName: vscjavaci_codesign + FolderPath: p2 + Pattern: "*.jar" + signConfigType: inlineSignParams + inlineOperation: |- + [ + { + "KeyCode" : "CP-447347-Java", + "OperationCode" : "JavaSign", + "Parameters" : { + "SigAlg" : "SHA256withRSA", + "Timestamp" : "-tsa http://sha256timestamp.ws.digicert.com/sha256/timestamp" + }, + "ToolName" : "sign", + "ToolVersion" : "1.0" + }, + { + "KeyCode" : "CP-447347-Java", + "OperationCode" : "JavaVerify", + "Parameters" : {}, + "ToolName" : "sign", + "ToolVersion" : "1.0" + } + ] + - task: CmdLine@2 + displayName: build m2 artifacts + inputs: + script: | + ./mvnw source:jar -f com.microsoft.java.debug.core/pom.xml -Dmaven.repo.local=./.repository + ./mvnw javadoc:jar -f com.microsoft.java.debug.core/pom.xml -Ddoclint=none -Dmaven.repo.local=./.repository + + ./mvnw source:jar -f com.microsoft.java.debug.plugin/pom.xml -Dmaven.repo.local=./.repository + ./mvnw javadoc:jar -f com.microsoft.java.debug.plugin/pom.xml -Ddoclint=none -Dmaven.repo.local=./.repository + + mkdir -p m2/java-debug-parent + cp pom.xml m2/java-debug-parent/java-debug-parent-$RELEASE_VERSION.pom + + mkdir -p m2/com.microsoft.java.debug.core + cp com.microsoft.java.debug.core/target/com.microsoft.java.debug.core*.jar m2/com.microsoft.java.debug.core + cp com.microsoft.java.debug.core/pom.xml m2/com.microsoft.java.debug.core/com.microsoft.java.debug.core-$RELEASE_VERSION.pom + + mkdir -p m2/com.microsoft.java.debug.plugin + cp com.microsoft.java.debug.plugin/target/com.microsoft.java.debug.plugin*.jar m2/com.microsoft.java.debug.plugin + cp com.microsoft.java.debug.plugin/pom.xml m2/com.microsoft.java.debug.plugin/com.microsoft.java.debug.plugin-$RELEASE_VERSION.pom + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 + displayName: Sign m2 + inputs: + ConnectedServiceName: vscjavaci_codesign + FolderPath: m2 + Pattern: "*.jar" + signConfigType: inlineSignParams + inlineOperation: |- + [ + { + "KeyCode" : "CP-447347-Java", + "OperationCode" : "JavaSign", + "Parameters" : { + "SigAlg" : "SHA256withRSA", + "Timestamp" : "-tsa http://sha256timestamp.ws.digicert.com/sha256/timestamp" + }, + "ToolName" : "sign", + "ToolVersion" : "1.0" + }, + { + "KeyCode" : "CP-447347-Java", + "OperationCode" : "JavaVerify", + "Parameters" : {}, + "ToolName" : "sign", + "ToolVersion" : "1.0" + } + ] + - task: CopyFiles@2 + displayName: "Copy p2/m2 to: $(Build.ArtifactStagingDirectory)" + inputs: + Contents: |+ + p2/** + m2/** + + TargetFolder: $(Build.ArtifactStagingDirectory) From 431de232d233783f2711a880d0c498a27baccb13 Mon Sep 17 00:00:00 2001 From: Gayan Perera Date: Tue, 30 Jan 2024 06:13:54 +0100 Subject: [PATCH 26/72] Fix the step-into target on multi line expression. Fix #519 (#520) * Fix the step-into target on multi line expression. Fix #519 --------- Co-authored-by: Jinbo Wang --- .../core/adapter/handler/StepRequestHandler.java | 11 ++++++++--- .../plugin/internal/MethodInvocationLocator.java | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java index 71f28355a..e8f782668 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StepRequestHandler.java @@ -268,7 +268,8 @@ private void handleDebugEvent(DebugEvent debugEvent, IDebugSession debugSession, } else if (currentStackDepth == threadState.stackDepth) { // If the ending step location is same as the original location where the step into operation is originated, // do another step of the same kind. - if (isSameLocation(currentStepLocation, threadState.stepLocation)) { + if (isSameLocation(currentStepLocation, threadState.stepLocation, + threadState.targetStepIn)) { context.getStepResultManager().removeMethodResult(threadId); threadState.pendingStepRequest = DebugUtility.createStepIntoRequest(thread, context.getStepFilters().allowClasses, @@ -438,15 +439,19 @@ private boolean shouldDoExtraStepInto(int originalStackDepth, Location originalL return true; } - private boolean isSameLocation(Location original, Location current) { + private boolean isSameLocation(Location current, Location original, MethodInvocation targetStepIn) { if (original == null || current == null) { return false; } Method originalMethod = original.method(); Method currentMethod = current.method(); + // if the lines doesn't match, check if the current line is still behind the + // target if a target exist. This handles where the target is part of a + // expression which is wrapped. return originalMethod.equals(currentMethod) - && original.lineNumber() == current.lineNumber(); + && (original.lineNumber() == current.lineNumber() + || (targetStepIn != null && targetStepIn.lineEnd >= current.lineNumber())); } /** diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/MethodInvocationLocator.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/MethodInvocationLocator.java index a25fbc3f6..654cbb00b 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/MethodInvocationLocator.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/MethodInvocationLocator.java @@ -217,7 +217,7 @@ public boolean visit(ClassInstanceCreation node) { private boolean shouldVisitNode(ASTNode node) { int start = unit.getLineNumber(node.getStartPosition()); - int end = unit.getLineNumber(node.getStartPosition() + node.getLength()); + int end = unit.getLineNumber(node.getStartPosition() + node.getLength() - 1); if (line >= start && line <= end) { return true; From fcfa80d2ba6b6e60da34d9451c4fc297fc821f0d Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Tue, 30 Jan 2024 13:59:01 +0800 Subject: [PATCH 27/72] Bump version to 0.51.0 (#533) --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/.classpath | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 4 ++-- com.microsoft.java.debug.plugin/pom.xml | 4 ++-- com.microsoft.java.debug.repository/category.xml | 2 +- com.microsoft.java.debug.repository/pom.xml | 2 +- com.microsoft.java.debug.target/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 635993d56..cd41ea9bc 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.50.0 + 0.51.0 com.microsoft.java.debug.core jar diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index ca5f41e6f..4d55efda0 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -11,6 +11,6 @@ - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 84a0ab36f..077d85c95 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true -Bundle-Version: 0.50.0 +Bundle-Version: 0.51.0 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.11.0.jar, ., lib/rxjava-2.2.21.jar, lib/reactive-streams-1.0.4.jar, - lib/com.microsoft.java.debug.core-0.50.0.jar + lib/com.microsoft.java.debug.core-0.51.0.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index b895ffd28..68e29fa33 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.50.0 + 0.51.0 com.microsoft.java.debug.plugin eclipse-plugin @@ -56,7 +56,7 @@ com.microsoft.java com.microsoft.java.debug.core - 0.50.0 + 0.51.0 diff --git a/com.microsoft.java.debug.repository/category.xml b/com.microsoft.java.debug.repository/category.xml index 639d50082..332d14f9e 100644 --- a/com.microsoft.java.debug.repository/category.xml +++ b/com.microsoft.java.debug.repository/category.xml @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.repository/pom.xml b/com.microsoft.java.debug.repository/pom.xml index 4f05eb331..314b894cb 100644 --- a/com.microsoft.java.debug.repository/pom.xml +++ b/com.microsoft.java.debug.repository/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.50.0 + 0.51.0 com.microsoft.java.debug.repository eclipse-repository diff --git a/com.microsoft.java.debug.target/pom.xml b/com.microsoft.java.debug.target/pom.xml index 80395f6dd..42dbf2724 100644 --- a/com.microsoft.java.debug.target/pom.xml +++ b/com.microsoft.java.debug.target/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.50.0 + 0.51.0 com.microsoft.java.debug.tp ${base.name} :: Target Platform diff --git a/pom.xml b/pom.xml index d562f82b5..46aece86b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ${base.name} :: Parent The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug - 0.50.0 + 0.51.0 pom Java Debug Server for Visual Studio Code From b5bc37d18e885c686866b40fbf7e8f9ed82a7d47 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Tue, 6 Feb 2024 09:20:06 +0800 Subject: [PATCH 28/72] Fix build errors (#535) * Fix build errors --- .../internal/CompletionProposalRequestor.java | 20 ++++++++++++++++++- .../com.microsoft.java.debug.tp.target | 5 ++++- pom.xml | 2 +- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java index 1df752f24..431c283f5 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/CompletionProposalRequestor.java @@ -72,6 +72,8 @@ public final class CompletionProposalRequestor extends CompletionRequestor { CompletionItemKind.Text); // @formatter:on + private static boolean isFilterFailed = false; + /** * Constructor. * @param typeRoot ITypeRoot @@ -321,7 +323,7 @@ private boolean isFiltered(CompletionProposal proposal) { case CompletionProposal.JAVADOC_TYPE_REF: case CompletionProposal.TYPE_REF: { char[] declaringType = getDeclaringType(proposal); - return declaringType != null && org.eclipse.jdt.ls.core.internal.contentassist.TypeFilter.isFiltered(declaringType); + return declaringType != null && isFiltered(declaringType); } default: // do nothing } @@ -332,6 +334,22 @@ private boolean isFiltered(CompletionProposal proposal) { return false; } + // Temp workaround for the completion error https://github.com/microsoft/java-debug/issues/534 + private static boolean isFiltered(char[] fullTypeName) { + if (isFilterFailed) { + return false; + } + + try { + return JavaLanguageServerPlugin.getInstance().getTypeFilter().filter(new String(fullTypeName)); + } catch (NoSuchMethodError ex) { + isFilterFailed = true; + JavaLanguageServerPlugin.logException("isFiltered for the completion failed.", ex); + } + + return false; + } + /** * copied from * org.eclipse.jdt.ui.text.java.CompletionProposalCollector.getDeclaringType(CompletionProposal) diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index 2e7920ed7..828da98a2 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -15,7 +15,10 @@ - + + + + diff --git a/pom.xml b/pom.xml index 46aece86b..8911c9d58 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ Java Debug Server for Visual Studio Code UTF-8 - 4.0.3 + 4.0.5 ${basedir} From f212c3a2f7aa2490c2df5dfa8dfda9fd0dd70d09 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Mon, 19 Feb 2024 11:27:03 +0800 Subject: [PATCH 29/72] Bump version to 0.51.1 (#536) --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/.classpath | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 4 ++-- com.microsoft.java.debug.plugin/pom.xml | 4 ++-- com.microsoft.java.debug.repository/category.xml | 2 +- com.microsoft.java.debug.repository/pom.xml | 2 +- com.microsoft.java.debug.target/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index cd41ea9bc..a7c2ca8ce 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.51.0 + 0.51.1 com.microsoft.java.debug.core jar diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index 4d55efda0..b4fb64d7d 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -11,6 +11,6 @@ - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 077d85c95..73af47a6d 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true -Bundle-Version: 0.51.0 +Bundle-Version: 0.51.1 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.11.0.jar, ., lib/rxjava-2.2.21.jar, lib/reactive-streams-1.0.4.jar, - lib/com.microsoft.java.debug.core-0.51.0.jar + lib/com.microsoft.java.debug.core-0.51.1.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index 68e29fa33..4657ab08b 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.51.0 + 0.51.1 com.microsoft.java.debug.plugin eclipse-plugin @@ -56,7 +56,7 @@ com.microsoft.java com.microsoft.java.debug.core - 0.51.0 + 0.51.1 diff --git a/com.microsoft.java.debug.repository/category.xml b/com.microsoft.java.debug.repository/category.xml index 332d14f9e..53e8bf963 100644 --- a/com.microsoft.java.debug.repository/category.xml +++ b/com.microsoft.java.debug.repository/category.xml @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.repository/pom.xml b/com.microsoft.java.debug.repository/pom.xml index 314b894cb..68ff9fc42 100644 --- a/com.microsoft.java.debug.repository/pom.xml +++ b/com.microsoft.java.debug.repository/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.51.0 + 0.51.1 com.microsoft.java.debug.repository eclipse-repository diff --git a/com.microsoft.java.debug.target/pom.xml b/com.microsoft.java.debug.target/pom.xml index 42dbf2724..6977f1831 100644 --- a/com.microsoft.java.debug.target/pom.xml +++ b/com.microsoft.java.debug.target/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.51.0 + 0.51.1 com.microsoft.java.debug.tp ${base.name} :: Target Platform diff --git a/pom.xml b/pom.xml index 8911c9d58..b039fe1c1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ${base.name} :: Parent The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug - 0.51.0 + 0.51.1 pom Java Debug Server for Visual Studio Code From 6e064b0ca2e8d894ab66b6b341dae00f4060317a Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Mon, 19 Feb 2024 13:39:33 +0800 Subject: [PATCH 30/72] Update signjars-rc.yml for Azure Pipelines --- .azure-pipelines/signjars-rc.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.azure-pipelines/signjars-rc.yml b/.azure-pipelines/signjars-rc.yml index 4e51eff7f..a8f1d3268 100644 --- a/.azure-pipelines/signjars-rc.yml +++ b/.azure-pipelines/signjars-rc.yml @@ -74,7 +74,7 @@ extends: - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 displayName: Sign core.jar inputs: - ConnectedServiceName: vscjavaci_codesign + ConnectedServiceName: vscjavaci_codesign_token FolderPath: jars Pattern: com.microsoft.java.debug.core*.jar signConfigType: inlineSignParams @@ -114,7 +114,7 @@ extends: - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 displayName: Sign plugin.jar inputs: - ConnectedServiceName: vscjavaci_codesign + ConnectedServiceName: vscjavaci_codesign_token FolderPath: jars Pattern: com.microsoft.java.debug.plugin*.jar signConfigType: inlineSignParams @@ -155,7 +155,7 @@ extends: - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 displayName: Sign p2 inputs: - ConnectedServiceName: vscjavaci_codesign + ConnectedServiceName: vscjavaci_codesign_token FolderPath: p2 Pattern: "*.jar" signConfigType: inlineSignParams @@ -202,7 +202,7 @@ extends: - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 displayName: Sign m2 inputs: - ConnectedServiceName: vscjavaci_codesign + ConnectedServiceName: vscjavaci_codesign_token FolderPath: m2 Pattern: "*.jar" signConfigType: inlineSignParams From 5f0d1bb9109f2ebfcc1f8faf12eac77f59b5a380 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Mon, 19 Feb 2024 14:59:26 +0800 Subject: [PATCH 31/72] Update signjars-rc.yml for Azure Pipelines --- .azure-pipelines/signjars-rc.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.azure-pipelines/signjars-rc.yml b/.azure-pipelines/signjars-rc.yml index a8f1d3268..ebb333f70 100644 --- a/.azure-pipelines/signjars-rc.yml +++ b/.azure-pipelines/signjars-rc.yml @@ -74,7 +74,7 @@ extends: - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 displayName: Sign core.jar inputs: - ConnectedServiceName: vscjavaci_codesign_token + ConnectedServiceName: vscjavaci_esrp_codesign FolderPath: jars Pattern: com.microsoft.java.debug.core*.jar signConfigType: inlineSignParams @@ -114,7 +114,7 @@ extends: - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 displayName: Sign plugin.jar inputs: - ConnectedServiceName: vscjavaci_codesign_token + ConnectedServiceName: vscjavaci_esrp_codesign FolderPath: jars Pattern: com.microsoft.java.debug.plugin*.jar signConfigType: inlineSignParams @@ -155,7 +155,7 @@ extends: - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 displayName: Sign p2 inputs: - ConnectedServiceName: vscjavaci_codesign_token + ConnectedServiceName: vscjavaci_esrp_codesign FolderPath: p2 Pattern: "*.jar" signConfigType: inlineSignParams @@ -202,7 +202,7 @@ extends: - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 displayName: Sign m2 inputs: - ConnectedServiceName: vscjavaci_codesign_token + ConnectedServiceName: vscjavaci_esrp_codesign FolderPath: m2 Pattern: "*.jar" signConfigType: inlineSignParams From 6c2377eae78c308bf87fbc2a6438a93734b06f5f Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Fri, 23 Feb 2024 14:18:08 +0800 Subject: [PATCH 32/72] Update signjars-nightly.yml for Azure Pipelines --- .azure-pipelines/signjars-nightly.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.azure-pipelines/signjars-nightly.yml b/.azure-pipelines/signjars-nightly.yml index bdaeea871..cae5ac6d5 100644 --- a/.azure-pipelines/signjars-nightly.yml +++ b/.azure-pipelines/signjars-nightly.yml @@ -73,7 +73,7 @@ extends: - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 displayName: Sign core.jar inputs: - ConnectedServiceName: vscjavaci_codesign + ConnectedServiceName: vscjavaci_esrp_codesign FolderPath: jars Pattern: com.microsoft.java.debug.core*.jar signConfigType: inlineSignParams @@ -113,7 +113,7 @@ extends: - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 displayName: Sign plugin.jar inputs: - ConnectedServiceName: vscjavaci_codesign + ConnectedServiceName: vscjavaci_esrp_codesign FolderPath: jars Pattern: com.microsoft.java.debug.plugin*.jar signConfigType: inlineSignParams From 98db4b16262488c5351a922f5781f7b95e1290d4 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Thu, 14 Mar 2024 13:58:54 +0800 Subject: [PATCH 33/72] Update com.microsoft.java.debug.tp.target to 4.31 release (#538) --- .../com.microsoft.java.debug.tp.target | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index 828da98a2..55695f6a9 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -16,7 +16,7 @@ - + From 736dcacf41e4da79b7419e7b7067f9c886252530 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Mon, 18 Mar 2024 18:29:13 +0800 Subject: [PATCH 34/72] Update lsp4j to 0.22.0 (#541) --- .../com.microsoft.java.debug.tp.target | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index 55695f6a9..200e532e3 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -31,7 +31,7 @@ - + From 56c014531273afd1c3a3b30712c2fb4d257e61f0 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Thu, 21 Mar 2024 20:34:44 +0800 Subject: [PATCH 35/72] Support debugging Java 21 instance main method and unnamed class (#542) * Support debugging Java 21 instance main method and unnamed class --- .github/workflows/build.yml | 4 +- .../internal/JdtSourceLookUpProvider.java | 32 ++++- .../internal/ResolveMainClassHandler.java | 124 ++++++++++-------- .../internal/ResolveMainMethodHandler.java | 51 ++++++- .../com.microsoft.java.debug.tp.target | 9 +- pom.xml | 2 +- 6 files changed, 158 insertions(+), 64 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 41c85cb62..1ace44224 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,7 +28,7 @@ jobs: ${{ runner.os }}-maven- - name: Verify - run: ./mvnw clean verify + run: ./mvnw clean verify -U - name: Checkstyle run: ./mvnw checkstyle:check @@ -85,7 +85,7 @@ jobs: ${{ runner.os }}-maven- - name: Verify - run: ./mvnw clean verify + run: ./mvnw clean verify -U - name: Checkstyle run: ./mvnw checkstyle:check diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java index 1ebf4c7c3..c96b98342 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java @@ -32,6 +32,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.apache.commons.lang3.StringUtils; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; @@ -56,6 +57,7 @@ import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.LambdaExpression; +import org.eclipse.jdt.core.dom.UnnamedClass; import org.eclipse.jdt.core.manipulation.CoreASTProvider; import org.eclipse.jdt.internal.core.JarPackageFragmentRoot; import org.eclipse.jdt.launching.IVMInstall; @@ -172,6 +174,11 @@ public JavaBreakpointLocation[] getBreakpointLocations(String sourceUri, SourceB .map(sourceBreakpoint -> new JavaBreakpointLocation(sourceBreakpoint.line, sourceBreakpoint.column)) .toArray(JavaBreakpointLocation[]::new); if (astUnit != null) { + List types = astUnit.types(); + String unnamedClass = null; + if (types.size() == 1 && types.get(0) instanceof UnnamedClass) { + unnamedClass = inferPrimaryTypeName(sourceUri, astUnit); + } Map resolvedLocations = new HashMap<>(); for (JavaBreakpointLocation sourceLocation : sourceLocations) { int sourceLine = sourceLocation.lineNumber(); @@ -222,7 +229,7 @@ public JavaBreakpointLocation[] getBreakpointLocations(String sourceUri, SourceB // be hit in current implementation. if (sourceLine == locator.getLineLocation() && locator.getLocationType() == BreakpointLocationLocator.LOCATION_LINE) { - sourceLocation.setClassName(locator.getFullyQualifiedTypeName()); + sourceLocation.setClassName(StringUtils.isBlank(unnamedClass) ? locator.getFullyQualifiedTypeName() : unnamedClass); if (resolvedLocations.containsKey(sourceLine)) { sourceLocation.setAvailableBreakpointLocations(resolvedLocations.get(sourceLine)); } else { @@ -231,7 +238,7 @@ public JavaBreakpointLocation[] getBreakpointLocations(String sourceUri, SourceB resolvedLocations.put(sourceLine, inlineLocations); } } else if (locator.getLocationType() == BreakpointLocationLocator.LOCATION_METHOD) { - sourceLocation.setClassName(locator.getFullyQualifiedTypeName()); + sourceLocation.setClassName(StringUtils.isBlank(unnamedClass) ? locator.getFullyQualifiedTypeName() : unnamedClass); sourceLocation.setMethodName(locator.getMethodName()); sourceLocation.setMethodSignature(locator.getMethodSignature()); } @@ -241,6 +248,27 @@ public JavaBreakpointLocation[] getBreakpointLocations(String sourceUri, SourceB return sourceLocations; } + private String inferPrimaryTypeName(String uri, CompilationUnit astUnit) { + String fileName = ""; + String filePath = AdapterUtils.toPath(uri); + if (filePath != null && Files.isRegularFile(Paths.get(filePath))) { + fileName = Paths.get(filePath).getFileName().toString(); + } else if (astUnit.getTypeRoot() != null) { + fileName = astUnit.getTypeRoot().getElementName(); + } + + if (StringUtils.isNotBlank(fileName)) { + String[] extensions = JavaCore.getJavaLikeExtensions(); + for (String extension : extensions) { + if (fileName.endsWith("." + extension)) { + return fileName.substring(0, fileName.length() - 1 - extension.length()); + } + } + } + + return fileName; + } + private BreakpointLocation[] getInlineBreakpointLocations(final CompilationUnit astUnit, int sourceLine) { List locations = new ArrayList<>(); // The starting position of each line is the default breakpoint location for diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java index f70d0c044..38ad1532b 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java @@ -43,6 +43,7 @@ import org.eclipse.jdt.core.search.SearchParticipant; import org.eclipse.jdt.core.search.SearchPattern; import org.eclipse.jdt.core.search.SearchRequestor; +import org.eclipse.jdt.internal.core.SourceMethod; import org.eclipse.jdt.ls.core.internal.ProjectUtils; import org.eclipse.jdt.ls.core.internal.ResourceUtils; import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager; @@ -101,8 +102,7 @@ private List resolveMainClassUnderPaths(List parentPaths) // Limit to search main method from source code only. IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(ProjectUtils.getJavaProjects(), IJavaSearchScope.REFERENCED_PROJECTS | IJavaSearchScope.SOURCES); - SearchPattern pattern = SearchPattern.createPattern("main(String[]) void", IJavaSearchConstants.METHOD, - IJavaSearchConstants.DECLARATIONS, SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_EXACT_MATCH); + SearchPattern pattern = createMainMethodSearchPattern(); final List res = new ArrayList<>(); SearchRequestor requestor = new SearchRequestor() { @Override @@ -110,40 +110,36 @@ public void acceptSearchMatch(SearchMatch match) { Object element = match.getElement(); if (element instanceof IMethod) { IMethod method = (IMethod) element; - try { - if (method.isMainMethod()) { - IResource resource = method.getResource(); - if (resource != null) { - IProject project = resource.getProject(); - if (project != null) { - String mainClass = method.getDeclaringType().getFullyQualifiedName(); - IJavaProject javaProject = JdtUtils.getJavaProject(project); - if (javaProject != null) { - String moduleName = JdtUtils.getModuleName(javaProject); - if (moduleName != null) { - mainClass = moduleName + "/" + mainClass; - } + if (isMainMethod(method)) { + IResource resource = method.getResource(); + if (resource != null) { + IProject project = resource.getProject(); + if (project != null) { + String mainClass = method.getDeclaringType().getFullyQualifiedName(); + IJavaProject javaProject = JdtUtils.getJavaProject(project); + if (javaProject != null) { + String moduleName = JdtUtils.getModuleName(javaProject); + if (moduleName != null) { + mainClass = moduleName + "/" + mainClass; } - String projectName = ProjectsManager.DEFAULT_PROJECT_NAME.equals(project.getName()) ? null : project.getName(); - if (parentPaths.isEmpty() - || ResourceUtils.isContainedIn(project.getLocation(), parentPaths) - || isContainedInInvisibleProject(project, parentPaths)) { - String filePath = null; - - if (match.getResource() instanceof IFile) { - try { - filePath = match.getResource().getLocation().toOSString(); - } catch (Exception ex) { - // ignore - } + } + String projectName = ProjectsManager.DEFAULT_PROJECT_NAME.equals(project.getName()) ? null : project.getName(); + if (parentPaths.isEmpty() + || ResourceUtils.isContainedIn(project.getLocation(), parentPaths) + || isContainedInInvisibleProject(project, parentPaths)) { + String filePath = null; + + if (match.getResource() instanceof IFile) { + try { + filePath = match.getResource().getLocation().toOSString(); + } catch (Exception ex) { + // ignore } - res.add(new ResolutionItem(mainClass, projectName, filePath)); } + res.add(new ResolutionItem(mainClass, projectName, filePath)); } } } - } catch (JavaModelException e) { - // ignore } } } @@ -166,8 +162,7 @@ private List resolveMainClassUnderProject(final String projectNa IJavaProject javaProject = ProjectUtils.getJavaProject(projectName); IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(javaProject == null ? new IJavaProject[0] : new IJavaProject[] {javaProject}, IJavaSearchScope.REFERENCED_PROJECTS | IJavaSearchScope.SOURCES); - SearchPattern pattern = SearchPattern.createPattern("main(String[]) void", IJavaSearchConstants.METHOD, - IJavaSearchConstants.DECLARATIONS, SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_EXACT_MATCH); + SearchPattern pattern = createMainMethodSearchPattern(); final List res = new ArrayList<>(); SearchRequestor requestor = new SearchRequestor() { @Override @@ -175,35 +170,31 @@ public void acceptSearchMatch(SearchMatch match) { Object element = match.getElement(); if (element instanceof IMethod) { IMethod method = (IMethod) element; - try { - if (method.isMainMethod()) { - IResource resource = method.getResource(); - if (resource != null) { - IProject project = resource.getProject(); - if (project != null) { - String mainClass = method.getDeclaringType().getFullyQualifiedName(); - IJavaProject javaProject = JdtUtils.getJavaProject(project); - if (javaProject != null) { - String moduleName = JdtUtils.getModuleName(javaProject); - if (moduleName != null) { - mainClass = moduleName + "/" + mainClass; - } + if (isMainMethod(method)) { + IResource resource = method.getResource(); + if (resource != null) { + IProject project = resource.getProject(); + if (project != null) { + String mainClass = method.getDeclaringType().getFullyQualifiedName(); + IJavaProject javaProject = JdtUtils.getJavaProject(project); + if (javaProject != null) { + String moduleName = JdtUtils.getModuleName(javaProject); + if (moduleName != null) { + mainClass = moduleName + "/" + mainClass; } + } - String filePath = null; - if (match.getResource() instanceof IFile) { - try { - filePath = match.getResource().getLocation().toOSString(); - } catch (Exception ex) { - // ignore - } + String filePath = null; + if (match.getResource() instanceof IFile) { + try { + filePath = match.getResource().getLocation().toOSString(); + } catch (Exception ex) { + // ignore } - res.add(new ResolutionItem(mainClass, projectName, filePath)); } + res.add(new ResolutionItem(mainClass, projectName, filePath)); } } - } catch (JavaModelException e) { - // ignore } } } @@ -221,6 +212,29 @@ public void acceptSearchMatch(SearchMatch match) { return resolutions; } + private SearchPattern createMainMethodSearchPattern() { + SearchPattern pattern1 = SearchPattern.createPattern("main(String[]) void", IJavaSearchConstants.METHOD, + IJavaSearchConstants.DECLARATIONS, SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_EXACT_MATCH); + SearchPattern pattern2 = SearchPattern.createPattern("main() void", IJavaSearchConstants.METHOD, + IJavaSearchConstants.DECLARATIONS, SearchPattern.R_CASE_SENSITIVE | SearchPattern.R_EXACT_MATCH); + return SearchPattern.createOrPattern(pattern1, pattern2); + } + + private boolean isMainMethod(IMethod method) { + try { + if (method instanceof SourceMethod + && ((SourceMethod) method).isMainMethodCandidate()) { + return true; + } + + return method.isMainMethod(); + } catch (JavaModelException e) { + // do nothing + } + + return false; + } + private boolean isContainedInInvisibleProject(IProject project, Collection rootPaths) { if (project == null) { return false; diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java index a3c61e814..fb8dfc33e 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java @@ -15,6 +15,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -30,7 +31,11 @@ import org.eclipse.jdt.core.ISourceRange; import org.eclipse.jdt.core.ISourceReference; import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.eclipse.jdt.internal.core.SourceMethod; import org.eclipse.jdt.ls.core.internal.JDTUtils; import org.eclipse.jdt.ls.core.internal.handlers.DocumentLifeCycleHandler; import org.eclipse.jdt.ls.core.internal.managers.ProjectsManager; @@ -104,16 +109,58 @@ private static List searchMainMethods(ICompilationUnit compilationUnit) * Returns the main method defined in the type. */ public static IMethod getMainMethod(IType type) throws JavaModelException { + boolean allowInstanceMethod = isInstanceMainMethodSupported(type); + List methods = new ArrayList<>(); for (IMethod method : type.getMethods()) { - // Have at most one main method in the member methods of the type. + if (method instanceof SourceMethod + && ((SourceMethod) method).isMainMethodCandidate()) { + methods.add(method); + } + if (method.isMainMethod()) { - return method; + methods.add(method); + } + + if (!allowInstanceMethod && !methods.isEmpty()) { + return methods.get(0); } } + if (!methods.isEmpty()) { + methods.sort((method1, method2) -> { + return getMainMethodPriority(method1) - getMainMethodPriority(method2); + }); + + return methods.get(0); + } + return null; } + private static boolean isInstanceMainMethodSupported(IType type) { + Map options = type.getJavaProject().getOptions(true); + return CompilerOptions.versionToJdkLevel(options.get(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM)) >= ClassFileConstants.JDK21; + } + + private static int getMainMethodPriority(IMethod method) { + int flags = 0; + try { + flags = method.getFlags(); + } catch (JavaModelException e) { + // do nothing + } + String[] params = method.getParameterTypes(); + if (Flags.isStatic(flags) && params.length == 1) { + return 1; + } else if (Flags.isStatic(flags)) { + return 2; + } else if (params.length == 1) { + return 3; + } + + return 4; + } + private static List getPotentialMainClassTypes(ICompilationUnit compilationUnit) throws JavaModelException { List result = new ArrayList<>(); IType[] topLevelTypes = compilationUnit.getTypes(); diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index 200e532e3..a52901d01 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -14,13 +14,18 @@ - + + + + + + - + diff --git a/pom.xml b/pom.xml index b039fe1c1..2917f4092 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ Java Debug Server for Visual Studio Code UTF-8 - 4.0.5 + 4.0.6 ${basedir} From 1a06b1f6d27be3e765750433792da5ed02b9b0cd Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Mon, 25 Mar 2024 12:50:51 +0800 Subject: [PATCH 36/72] bump version to 0.52.0 (#543) --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/.classpath | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 4 ++-- com.microsoft.java.debug.plugin/pom.xml | 4 ++-- com.microsoft.java.debug.repository/category.xml | 2 +- com.microsoft.java.debug.repository/pom.xml | 2 +- com.microsoft.java.debug.target/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index a7c2ca8ce..3b42e40cb 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.51.1 + 0.52.0 com.microsoft.java.debug.core jar diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index b4fb64d7d..6de8860a5 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -11,6 +11,6 @@ - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 73af47a6d..b45c99f7a 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true -Bundle-Version: 0.51.1 +Bundle-Version: 0.52.0 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.11.0.jar, ., lib/rxjava-2.2.21.jar, lib/reactive-streams-1.0.4.jar, - lib/com.microsoft.java.debug.core-0.51.1.jar + lib/com.microsoft.java.debug.core-0.52.0.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index 4657ab08b..6d58947b0 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.51.1 + 0.52.0 com.microsoft.java.debug.plugin eclipse-plugin @@ -56,7 +56,7 @@ com.microsoft.java com.microsoft.java.debug.core - 0.51.1 + 0.52.0 diff --git a/com.microsoft.java.debug.repository/category.xml b/com.microsoft.java.debug.repository/category.xml index 53e8bf963..fc6ff6a62 100644 --- a/com.microsoft.java.debug.repository/category.xml +++ b/com.microsoft.java.debug.repository/category.xml @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.repository/pom.xml b/com.microsoft.java.debug.repository/pom.xml index 68ff9fc42..3d5537f13 100644 --- a/com.microsoft.java.debug.repository/pom.xml +++ b/com.microsoft.java.debug.repository/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.51.1 + 0.52.0 com.microsoft.java.debug.repository eclipse-repository diff --git a/com.microsoft.java.debug.target/pom.xml b/com.microsoft.java.debug.target/pom.xml index 6977f1831..e4ee29b92 100644 --- a/com.microsoft.java.debug.target/pom.xml +++ b/com.microsoft.java.debug.target/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.51.1 + 0.52.0 com.microsoft.java.debug.tp ${base.name} :: Target Platform diff --git a/pom.xml b/pom.xml index 2917f4092..f2e4d0eef 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ${base.name} :: Parent The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug - 0.51.1 + 0.52.0 pom Java Debug Server for Visual Studio Code From ae16f7ce3205047fd687aab9d877eeb78c62ace2 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Tue, 26 Mar 2024 10:45:23 +0800 Subject: [PATCH 37/72] Check the class name of ASTNode to see if it's unnamed class (#544) --- .../plugin/internal/JdtSourceLookUpProvider.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java index c96b98342..5652b922e 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/JdtSourceLookUpProvider.java @@ -20,11 +20,14 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.jar.Attributes; import java.util.jar.Manifest; import java.util.logging.Level; @@ -57,7 +60,6 @@ import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.LambdaExpression; -import org.eclipse.jdt.core.dom.UnnamedClass; import org.eclipse.jdt.core.manipulation.CoreASTProvider; import org.eclipse.jdt.internal.core.JarPackageFragmentRoot; import org.eclipse.jdt.launching.IVMInstall; @@ -87,6 +89,9 @@ public class JdtSourceLookUpProvider implements ISourceLookUpProvider { private static final Logger logger = Logger.getLogger(Configuration.LOGGER_NAME); private static final String JDT_SCHEME = "jdt"; private static final String PATH_SEPARATOR = "/"; + private static final Set IMPLICITLY_DECLARED_CLASSES = new HashSet<>( + Arrays.asList("org.eclipse.jdt.core.dom.UnnamedClass", + "org.eclipse.jdt.core.dom.ImplicitTypeDeclaration")); private ISourceContainer[] sourceContainers = null; private HashMap options = new HashMap(); @@ -176,7 +181,10 @@ public JavaBreakpointLocation[] getBreakpointLocations(String sourceUri, SourceB if (astUnit != null) { List types = astUnit.types(); String unnamedClass = null; - if (types.size() == 1 && types.get(0) instanceof UnnamedClass) { + // See https://github.com/eclipse-jdt/eclipse.jdt.core/pull/2220 + // Given that the JDT plans to rename UnamedClass to ImplicitTypeDeclaration, we will check + // the class name of the ASTNode to prevent the potential breaking in the future. + if (types.size() == 1 && IMPLICITLY_DECLARED_CLASSES.contains(types.get(0).getClass().getName())) { unnamedClass = inferPrimaryTypeName(sourceUri, astUnit); } Map resolvedLocations = new HashMap<>(); From 37d4e66c5717179b1487ff72fcbc8622b31a3648 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Tue, 26 Mar 2024 12:47:07 +0800 Subject: [PATCH 38/72] Update signjars-nightly.yml for Azure Pipelines --- .azure-pipelines/signjars-nightly.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.azure-pipelines/signjars-nightly.yml b/.azure-pipelines/signjars-nightly.yml index cae5ac6d5..0e53a4219 100644 --- a/.azure-pipelines/signjars-nightly.yml +++ b/.azure-pipelines/signjars-nightly.yml @@ -105,6 +105,7 @@ extends: displayName: Build plugin.jar inputs: script: |- + ./mvnw clean install -N -f pom.xml -Dmaven.repo.local=./.repository ./mvnw clean install -f com.microsoft.java.debug.target/pom.xml -Dmaven.repo.local=./.repository ./mvnw clean install -f com.microsoft.java.debug.plugin/pom.xml -Dmaven.repo.local=./.repository From 83403a458e0d01fba5a3871fea81af742460bdf0 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Wed, 10 Apr 2024 15:59:06 +0800 Subject: [PATCH 39/72] fix Java 22 main method searching order (#548) --- .../internal/ResolveMainMethodHandler.java | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java index fb8dfc33e..be1092bb3 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainMethodHandler.java @@ -142,23 +142,15 @@ private static boolean isInstanceMainMethodSupported(IType type) { return CompilerOptions.versionToJdkLevel(options.get(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM)) >= ClassFileConstants.JDK21; } + /** + * See Java 22 JEP 463 https://openjdk.org/jeps/463. + * It searches the main method in the launched class by following a specific order: + * - If the launched class contains a main method with a String[] parameter then choose that method. + * - Otherwise, if the class contains a main method with no parameters then choose that method. + */ private static int getMainMethodPriority(IMethod method) { - int flags = 0; - try { - flags = method.getFlags(); - } catch (JavaModelException e) { - // do nothing - } String[] params = method.getParameterTypes(); - if (Flags.isStatic(flags) && params.length == 1) { - return 1; - } else if (Flags.isStatic(flags)) { - return 2; - } else if (params.length == 1) { - return 3; - } - - return 4; + return params.length == 1 ? 1 : 2; } private static List getPotentialMainClassTypes(ICompilationUnit compilationUnit) throws JavaModelException { From 36572435d0518cb2566ab9705c3d2b8e2a797402 Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Fri, 14 Jun 2024 16:04:40 +0800 Subject: [PATCH 40/72] Support HCR for gradle build server projects (#555) * Support HCR for gradle build server projects * Fix checkstyle violations * Fix NPE when auto build is disabled Signed-off-by: Sheng Chen * Address comments * Fix checkstyle violations * Use isNotBlank() --------- Signed-off-by: Sheng Chen --- .../java/debug/plugin/internal/Compile.java | 78 ++++++++++--------- .../internal/JavaHotCodeReplaceProvider.java | 45 +++++++++++ .../java/debug/plugin/internal/JdtUtils.java | 34 ++++++++ 3 files changed, 120 insertions(+), 37 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..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 @@ -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,20 +48,12 @@ 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) { - try { - // Q: is infer project by main class name necessary? perf impact? - List 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); - } + if (params == null) { + throw new IllegalArgumentException("The compile parameters should not be null."); } - if (isBspProject(mainProject) && !ProjectUtils.isGradleProject(mainProject)) { + 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. try { @@ -78,20 +73,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 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 +147,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) { @@ -153,11 +162,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..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,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; @@ -55,6 +59,7 @@ import org.eclipse.jdt.core.util.ISourceAttribute; import org.eclipse.jdt.internal.core.util.Util; 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; @@ -63,6 +68,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; @@ -104,6 +110,8 @@ public class JavaHotCodeReplaceProvider implements IHotCodeReplaceProvider, IRes private List deltaClassNames = new ArrayList<>(); + private String mainProjectName = ""; + /** * Visitor for resource deltas. */ @@ -269,6 +277,7 @@ public void initialize(IDebugAdapterContext context, Map options } this.context = context; currentDebugSession = context.getDebugSession(); + this.mainProjectName = ((String) options.get(Constants.PROJECT_NAME)); } @Override @@ -319,6 +328,7 @@ public void onClassRedefined(Consumer> consumer) { @Override public CompletableFuture> redefineClasses() { + triggerBuildForBspProject(); JobHelpers.waitForBuildJobs(10 * 1000); return CompletableFuture.supplyAsync(() -> { List classNames = new ArrayList<>(); @@ -737,4 +747,39 @@ private List 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.mainProjectName, 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 a4c06c6d4..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 @@ -40,6 +40,8 @@ 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; import com.microsoft.java.debug.core.StackFrameUtility; @@ -415,4 +417,36 @@ 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"); + } + + /** + * Get main project according to the main project name or main class name, + * or return null if the main project cannot be resolved. + */ + public static IProject getMainProject(String mainProjectName, String mainClassName) { + IProject mainProject = null; + if (StringUtils.isNotBlank(mainProjectName)) { + mainProject = ProjectUtils.getProject(mainProjectName); + } + + if (mainProject == null && StringUtils.isNotBlank(mainClassName)) { + try { + List 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 6511f97c76d4dd562f94c3ac503a982407d211a3 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Mon, 17 Jun 2024 16:50:27 +0800 Subject: [PATCH 41/72] Update tp to fix the build failure (#556) --- .../com.microsoft.java.debug.tp.target | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index a52901d01..6edb44dec 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -15,7 +15,7 @@ - + From e06a1b686625b28a66e0bd6a22f4668fb4f02b4d Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Thu, 27 Jun 2024 10:31:27 +0800 Subject: [PATCH 42/72] bump version to 0.53.0 (#557) --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/.classpath | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 4 ++-- com.microsoft.java.debug.plugin/pom.xml | 4 ++-- com.microsoft.java.debug.repository/category.xml | 2 +- com.microsoft.java.debug.repository/pom.xml | 2 +- com.microsoft.java.debug.target/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 3b42e40cb..bb1449401 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.52.0 + 0.53.0 com.microsoft.java.debug.core jar diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index 6de8860a5..dc81da8e6 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -11,6 +11,6 @@ - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index b45c99f7a..192908dcf 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true -Bundle-Version: 0.52.0 +Bundle-Version: 0.53.0 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.11.0.jar, ., lib/rxjava-2.2.21.jar, lib/reactive-streams-1.0.4.jar, - lib/com.microsoft.java.debug.core-0.52.0.jar + lib/com.microsoft.java.debug.core-0.53.0.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index 6d58947b0..93323db5c 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.52.0 + 0.53.0 com.microsoft.java.debug.plugin eclipse-plugin @@ -56,7 +56,7 @@ com.microsoft.java com.microsoft.java.debug.core - 0.52.0 + 0.53.0 diff --git a/com.microsoft.java.debug.repository/category.xml b/com.microsoft.java.debug.repository/category.xml index fc6ff6a62..b09605569 100644 --- a/com.microsoft.java.debug.repository/category.xml +++ b/com.microsoft.java.debug.repository/category.xml @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.repository/pom.xml b/com.microsoft.java.debug.repository/pom.xml index 3d5537f13..edb1c9891 100644 --- a/com.microsoft.java.debug.repository/pom.xml +++ b/com.microsoft.java.debug.repository/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.52.0 + 0.53.0 com.microsoft.java.debug.repository eclipse-repository diff --git a/com.microsoft.java.debug.target/pom.xml b/com.microsoft.java.debug.target/pom.xml index e4ee29b92..2dc407f6c 100644 --- a/com.microsoft.java.debug.target/pom.xml +++ b/com.microsoft.java.debug.target/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.52.0 + 0.53.0 com.microsoft.java.debug.tp ${base.name} :: Target Platform diff --git a/pom.xml b/pom.xml index f2e4d0eef..c277e8a98 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ${base.name} :: Parent The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug - 0.52.0 + 0.53.0 pom Java Debug Server for Visual Studio Code From 24c61a7b06b2e3dec661b97688f9b6d033de5fab Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Fri, 19 Jul 2024 13:34:22 +0800 Subject: [PATCH 43/72] Remove the deprecated debug parameters from the launching connector (#562) --- .../java/debug/plugin/internal/AdvancedLaunchingConnector.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/AdvancedLaunchingConnector.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/AdvancedLaunchingConnector.java index 3551ab2e6..087f0fae7 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/AdvancedLaunchingConnector.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/AdvancedLaunchingConnector.java @@ -195,7 +195,7 @@ private static String[] constructLaunchCommand(Map l StringBuilder execString = new StringBuilder(); execString.append("\"" + javaHome + slash + "bin" + slash + javaExec + "\""); - execString.append(" -Xdebug -Xnoagent -Djava.compiler=NONE"); + execString.append(" -Djava.compiler=NONE"); execString.append(" -Xrunjdwp:transport=dt_socket,address=" + address + ",server=n,suspend=" + (suspend ? "y" : "n")); if (javaOptions != null) { execString.append(" " + javaOptions); From 1b669f8c4c92c179acf89498cd14bcb8397bd3b5 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Fri, 19 Jul 2024 14:36:08 +0800 Subject: [PATCH 44/72] Adopt the new code sign job in the pipeline (#563) --- .azure-pipelines/signjars-nightly.yml | 18 +++++++++++--- .azure-pipelines/signjars-rc.yml | 36 +++++++++++++++++++++------ 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/.azure-pipelines/signjars-nightly.yml b/.azure-pipelines/signjars-nightly.yml index 0e53a4219..2c0373aab 100644 --- a/.azure-pipelines/signjars-nightly.yml +++ b/.azure-pipelines/signjars-nightly.yml @@ -70,10 +70,15 @@ extends: mkdir -p jars mv .repository/com/microsoft/java/com.microsoft.java.debug.core/$RELEASE_VERSION/com.microsoft.java.debug.core*.jar jars/ - - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 displayName: Sign core.jar inputs: - ConnectedServiceName: vscjavaci_esrp_codesign + ConnectedServiceName: $(ConnectedServiceName) + AppRegistrationClientId: $(AppRegistrationClientId) + AppRegistrationTenantId: $(AppRegistrationTenantId) + AuthAKVName: $(AuthAKVName) + AuthCertName: $(AuthCertName) + AuthSignCertName: $(AuthSignCertName) FolderPath: jars Pattern: com.microsoft.java.debug.core*.jar signConfigType: inlineSignParams @@ -111,10 +116,15 @@ extends: mkdir -p jars mv .repository/com/microsoft/java/com.microsoft.java.debug.plugin/$RELEASE_VERSION/com.microsoft.java.debug.plugin*.jar jars/ - - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 displayName: Sign plugin.jar inputs: - ConnectedServiceName: vscjavaci_esrp_codesign + ConnectedServiceName: $(ConnectedServiceName) + AppRegistrationClientId: $(AppRegistrationClientId) + AppRegistrationTenantId: $(AppRegistrationTenantId) + AuthAKVName: $(AuthAKVName) + AuthCertName: $(AuthCertName) + AuthSignCertName: $(AuthSignCertName) FolderPath: jars Pattern: com.microsoft.java.debug.plugin*.jar signConfigType: inlineSignParams diff --git a/.azure-pipelines/signjars-rc.yml b/.azure-pipelines/signjars-rc.yml index ebb333f70..851b73775 100644 --- a/.azure-pipelines/signjars-rc.yml +++ b/.azure-pipelines/signjars-rc.yml @@ -71,10 +71,15 @@ extends: mkdir -p jars mv .repository/com/microsoft/java/com.microsoft.java.debug.core/$RELEASE_VERSION/com.microsoft.java.debug.core*.jar jars/ - - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 displayName: Sign core.jar inputs: - ConnectedServiceName: vscjavaci_esrp_codesign + ConnectedServiceName: $(ConnectedServiceName) + AppRegistrationClientId: $(AppRegistrationClientId) + AppRegistrationTenantId: $(AppRegistrationTenantId) + AuthAKVName: $(AuthAKVName) + AuthCertName: $(AuthCertName) + AuthSignCertName: $(AuthSignCertName) FolderPath: jars Pattern: com.microsoft.java.debug.core*.jar signConfigType: inlineSignParams @@ -111,10 +116,15 @@ extends: mkdir -p jars mv .repository/com/microsoft/java/com.microsoft.java.debug.plugin/$RELEASE_VERSION/com.microsoft.java.debug.plugin*.jar jars/ - - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 displayName: Sign plugin.jar inputs: - ConnectedServiceName: vscjavaci_esrp_codesign + ConnectedServiceName: $(ConnectedServiceName) + AppRegistrationClientId: $(AppRegistrationClientId) + AppRegistrationTenantId: $(AppRegistrationTenantId) + AuthAKVName: $(AuthAKVName) + AuthCertName: $(AuthCertName) + AuthSignCertName: $(AuthSignCertName) FolderPath: jars Pattern: com.microsoft.java.debug.plugin*.jar signConfigType: inlineSignParams @@ -152,10 +162,15 @@ extends: mkdir -p p2/target cp -r com.microsoft.java.debug.repository/target/repository p2/target/ cp com.microsoft.java.debug.repository/pushToBintray.sh p2/ - - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 displayName: Sign p2 inputs: - ConnectedServiceName: vscjavaci_esrp_codesign + ConnectedServiceName: $(ConnectedServiceName) + AppRegistrationClientId: $(AppRegistrationClientId) + AppRegistrationTenantId: $(AppRegistrationTenantId) + AuthAKVName: $(AuthAKVName) + AuthCertName: $(AuthCertName) + AuthSignCertName: $(AuthSignCertName) FolderPath: p2 Pattern: "*.jar" signConfigType: inlineSignParams @@ -199,10 +214,15 @@ extends: mkdir -p m2/com.microsoft.java.debug.plugin cp com.microsoft.java.debug.plugin/target/com.microsoft.java.debug.plugin*.jar m2/com.microsoft.java.debug.plugin cp com.microsoft.java.debug.plugin/pom.xml m2/com.microsoft.java.debug.plugin/com.microsoft.java.debug.plugin-$RELEASE_VERSION.pom - - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@2 + - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 displayName: Sign m2 inputs: - ConnectedServiceName: vscjavaci_esrp_codesign + ConnectedServiceName: $(ConnectedServiceName) + AppRegistrationClientId: $(AppRegistrationClientId) + AppRegistrationTenantId: $(AppRegistrationTenantId) + AuthAKVName: $(AuthAKVName) + AuthCertName: $(AuthCertName) + AuthSignCertName: $(AuthSignCertName) FolderPath: m2 Pattern: "*.jar" signConfigType: inlineSignParams From 26daf612fb03f8dd7befaa980feb327644ee43a7 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Mon, 22 Jul 2024 10:07:30 +0800 Subject: [PATCH 45/72] Remove the obselete parameter '-Djava.compiler=NONE' from launching command (#564) --- .../java/debug/plugin/internal/AdvancedLaunchingConnector.java | 1 - 1 file changed, 1 deletion(-) diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/AdvancedLaunchingConnector.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/AdvancedLaunchingConnector.java index 087f0fae7..24c65785d 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/AdvancedLaunchingConnector.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/AdvancedLaunchingConnector.java @@ -195,7 +195,6 @@ private static String[] constructLaunchCommand(Map l StringBuilder execString = new StringBuilder(); execString.append("\"" + javaHome + slash + "bin" + slash + javaExec + "\""); - execString.append(" -Djava.compiler=NONE"); execString.append(" -Xrunjdwp:transport=dt_socket,address=" + address + ",server=n,suspend=" + (suspend ? "y" : "n")); if (javaOptions != null) { execString.append(" " + javaOptions); From 3691f3b5f2cae05b06b43333dc435c172e27f1a8 Mon Sep 17 00:00:00 2001 From: bsolar17 Date: Thu, 8 Aug 2024 03:49:58 +0200 Subject: [PATCH 46/72] Update lsp4j dependency to version 0.23.1 (#565) New version of jdtls core requires lsp4j 0.23 or greater. --- .../com.microsoft.java.debug.tp.target | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index 6edb44dec..41215e0ba 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -36,7 +36,7 @@ - + From e54f5c20c9cac846eab9f4af0f4fef671727b919 Mon Sep 17 00:00:00 2001 From: Vincentius Adrian Date: Wed, 18 Sep 2024 14:36:52 +0700 Subject: [PATCH 47/72] Update eclipse to use v4.33 (#571) --- .../com.microsoft.java.debug.tp.target | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index 41215e0ba..5c386e467 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -15,7 +15,7 @@ - + From d4afc7e55107b333c3a1126fbf42c18c0dfd69cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 11:32:24 +0800 Subject: [PATCH 48/72] Bump commons-io:commons-io in /com.microsoft.java.debug.core (#573) Bumps commons-io:commons-io from 2.11.0 to 2.14.0. --- updated-dependencies: - dependency-name: commons-io:commons-io dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- com.microsoft.java.debug.core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index bb1449401..d8dae21e7 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -62,7 +62,7 @@ commons-io commons-io - 2.11.0 + 2.14.0 From 5c7562ade22977b15f76f46d13c098e82cc58ced Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Thu, 31 Oct 2024 14:38:24 +0800 Subject: [PATCH 49/72] bump version to 0.53.1 (#574) --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/.classpath | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 4 ++-- com.microsoft.java.debug.plugin/pom.xml | 4 ++-- com.microsoft.java.debug.repository/category.xml | 2 +- com.microsoft.java.debug.repository/pom.xml | 2 +- com.microsoft.java.debug.target/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index d8dae21e7..64827ab13 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.53.0 + 0.53.1 com.microsoft.java.debug.core jar diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index dc81da8e6..dbf84ced8 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -11,6 +11,6 @@ - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 192908dcf..ea6b7127e 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true -Bundle-Version: 0.53.0 +Bundle-Version: 0.53.1 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.11.0.jar, ., lib/rxjava-2.2.21.jar, lib/reactive-streams-1.0.4.jar, - lib/com.microsoft.java.debug.core-0.53.0.jar + lib/com.microsoft.java.debug.core-0.53.1.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index 93323db5c..dde9c7ec6 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.53.0 + 0.53.1 com.microsoft.java.debug.plugin eclipse-plugin @@ -56,7 +56,7 @@ com.microsoft.java com.microsoft.java.debug.core - 0.53.0 + 0.53.1 diff --git a/com.microsoft.java.debug.repository/category.xml b/com.microsoft.java.debug.repository/category.xml index b09605569..5d3e664df 100644 --- a/com.microsoft.java.debug.repository/category.xml +++ b/com.microsoft.java.debug.repository/category.xml @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.repository/pom.xml b/com.microsoft.java.debug.repository/pom.xml index edb1c9891..40519fce2 100644 --- a/com.microsoft.java.debug.repository/pom.xml +++ b/com.microsoft.java.debug.repository/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.53.0 + 0.53.1 com.microsoft.java.debug.repository eclipse-repository diff --git a/com.microsoft.java.debug.target/pom.xml b/com.microsoft.java.debug.target/pom.xml index 2dc407f6c..737decee1 100644 --- a/com.microsoft.java.debug.target/pom.xml +++ b/com.microsoft.java.debug.target/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.53.0 + 0.53.1 com.microsoft.java.debug.tp ${base.name} :: Target Platform diff --git a/pom.xml b/pom.xml index c277e8a98..53aec5c9c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ${base.name} :: Parent The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug - 0.53.0 + 0.53.1 pom Java Debug Server for Visual Studio Code From 4cb23d2493aae8f17618764591fb37d71a178d0f Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Thu, 27 Feb 2025 18:49:15 -0800 Subject: [PATCH 50/72] Update CI to run against jdk 21 (#581) --- .azure-pipelines/signjars-nightly.yml | 4 ++-- .azure-pipelines/signjars-rc.yml | 4 ++-- .github/workflows/build.yml | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.azure-pipelines/signjars-nightly.yml b/.azure-pipelines/signjars-nightly.yml index 2c0373aab..8f405a725 100644 --- a/.azure-pipelines/signjars-nightly.yml +++ b/.azure-pipelines/signjars-nightly.yml @@ -46,9 +46,9 @@ extends: - checkout: self fetchTags: true - task: JavaToolInstaller@0 - displayName: Use Java 17 + displayName: Use Java 21 inputs: - versionSpec: "17" + versionSpec: "21" jdkArchitectureOption: x64 jdkSourceOption: PreInstalled - task: CmdLine@2 diff --git a/.azure-pipelines/signjars-rc.yml b/.azure-pipelines/signjars-rc.yml index 851b73775..c0c11e6cc 100644 --- a/.azure-pipelines/signjars-rc.yml +++ b/.azure-pipelines/signjars-rc.yml @@ -45,9 +45,9 @@ extends: - checkout: self fetchTags: true - task: JavaToolInstaller@0 - displayName: Use Java 17 + displayName: Use Java 21 inputs: - versionSpec: "17" + versionSpec: "21" jdkArchitectureOption: x64 jdkSourceOption: PreInstalled - task: CmdLine@2 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1ace44224..c147c4838 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,10 +14,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v1 with: - java-version: '17' + java-version: '21' - name: Cache local Maven repository uses: actions/cache@v2 @@ -45,10 +45,10 @@ jobs: - uses: actions/checkout@v2 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v1 with: - java-version: '17' + java-version: '21' - name: Cache local Maven repository uses: actions/cache@v2 @@ -71,10 +71,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v1 with: - java-version: '17' + java-version: '21' - name: Cache local Maven repository uses: actions/cache@v2 From dff3538d4f741e7e05a304614e3d5d9e7e0bfb0b Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Fri, 28 Feb 2025 07:13:49 +0000 Subject: [PATCH 51/72] Attempt to terminate the process normally (#579) Fixes https://github.com/microsoft/vscode-java-debug/issues/1274 --- .../main/java/com/microsoft/java/debug/core/DebugSession.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java index fbad52fe2..38a234fa9 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/DebugSession.java @@ -119,7 +119,9 @@ public void detach() { @Override public void terminate() { - if (vm.process() == null || vm.process().isAlive()) { + if (vm.process() != null && vm.process().isAlive()) { + vm.process().destroy(); + } else if (vm.process() == null || vm.process().isAlive()) { vm.exit(0); } } From 31b22551b27712d265694c7afbe21d0eabccd1d1 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Fri, 21 Mar 2025 16:31:31 +0800 Subject: [PATCH 52/72] Onboard pipelines to MicroBuild (#583) * Onboard pipelines to MicroBuild * onboard code sign to microbuild * remove p2 copy logic * remove p2 buildartifact dir * use MicroBuild to publish to maven * fix m2 sign path * upgrade to actions/cache@v4 --- .azure-pipelines/publish-to-maven.yml | 100 ++++++++++++++ .azure-pipelines/signjars-nightly.yml | 97 +++++-------- .azure-pipelines/signjars-rc.yml | 187 +++++++------------------- .github/workflows/build.yml | 6 +- 4 files changed, 183 insertions(+), 207 deletions(-) create mode 100644 .azure-pipelines/publish-to-maven.yml diff --git a/.azure-pipelines/publish-to-maven.yml b/.azure-pipelines/publish-to-maven.yml new file mode 100644 index 000000000..58dc58cf2 --- /dev/null +++ b/.azure-pipelines/publish-to-maven.yml @@ -0,0 +1,100 @@ +name: $(Date:yyyyMMdd).$(Rev:r) +resources: + repositories: + - repository: MicroBuildTemplate + type: git + name: 1ESPipelineTemplates/MicroBuildTemplate + ref: refs/tags/release +trigger: none +extends: + template: azure-pipelines/1ES.Official.Publish.yml@MicroBuildTemplate + parameters: + pool: + os: linux + name: 1ES_JavaTooling_Pool + image: 1ES_JavaTooling_Ubuntu-2004 + sdl: + sourceAnalysisPool: + name: 1ES_JavaTooling_Pool + image: 1ES_JavaTooling_Windows_2022 + os: windows + stages: + - stage: PublishToMaven + jobs: + - job: PublishToMaven + steps: + - task: DownloadBuildArtifacts@1 + displayName: 'Download Jar Artifacts' + inputs: + buildType: specific + project: 'a4d27ce2-a42d-4b71-8eef-78cee9a9728e' + pipeline: 16486 + downloadType: specific + extractTars: false + itemPattern: 'm2/**' + - script: | + echo "import public key" + echo $GPG_PUBLIC_B64 | base64 -d | gpg --import + + echo "import secret key" + echo $GPG_SECRET_B64 | base64 -d | gpg --batch --passphrase $GPGPASS --import + displayName: 'import GPG keys' + env: + GPG_PUBLIC_B64: $(GPG_PUBLIC_B64) + GPG_SECRET_B64: $(GPG_SECRET_B64) + GPGPASS: $(GPGPASS) + - task: NodeTool@0 + displayName: 'Use Node 20.x' + inputs: + versionSpec: 20.x + - script: | + cd $(System.ArtifactsDirectory)/m2 + pluginJarFile=$(basename -- java-debug-parent/*.pom) + + # remove .* from end + noExt=${pluginJarFile%.*} + + # remove *- from start + export releaseVersion=${noExt##*-} + echo $releaseVersion + + export artifactFolder=$(pwd .) + wget https://raw.githubusercontent.com/microsoft/java-debug/master/scripts/publishMaven.js + + export GPG_TTY=$(tty) + node publishMaven.js -task gpg + displayName: 'sign artifacts' + env: + GPG_PUBLIC_B64: $(GPG_PUBLIC_B64) + GPG_SECRET_B64: $(GPG_SECRET_B64) + GPGPASS: $(GPGPASS) + NEXUS_OSSRHPASS: $(NEXUS_OSSRHPASS) + NEXUS_OSSRHUSER: $(NEXUS_OSSRHUSER) + NEXUS_STAGINGPROFILEID: $(NEXUS_STAGINGPROFILEID) + - template: MicroBuild.Publish.yml@MicroBuildTemplate + parameters: + intent: 'PackageDistribution' + contentType: 'Maven' + contentSource: 'Folder' + folderLocation: '$(System.ArtifactsDirectory)/m2/java-debug-parent' + waitForReleaseCompletion: true + owners: 'jinbwan@microsoft.com' + approvers: 'roml@microsoft.com' + - template: MicroBuild.Publish.yml@MicroBuildTemplate + parameters: + intent: 'PackageDistribution' + contentType: 'Maven' + contentSource: 'Folder' + folderLocation: '$(System.ArtifactsDirectory)/m2/com.microsoft.java.debug.core' + waitForReleaseCompletion: true + owners: 'jinbwan@microsoft.com' + approvers: 'roml@microsoft.com' + - template: MicroBuild.Publish.yml@MicroBuildTemplate + parameters: + intent: 'PackageDistribution' + contentType: 'Maven' + contentSource: 'Folder' + folderLocation: '$(System.ArtifactsDirectory)/m2/com.microsoft.java.debug.plugin' + waitForReleaseCompletion: true + owners: 'jinbwan@microsoft.com' + approvers: 'roml@microsoft.com' \ No newline at end of file diff --git a/.azure-pipelines/signjars-nightly.yml b/.azure-pipelines/signjars-nightly.yml index 8f405a725..19ab29baf 100644 --- a/.azure-pipelines/signjars-nightly.yml +++ b/.azure-pipelines/signjars-nightly.yml @@ -45,6 +45,23 @@ extends: steps: - checkout: self fetchTags: true + - task: UsePythonVersion@0 + displayName: 'Use Python 3.11.x' + inputs: + versionSpec: 3.11.x + - task: UseDotNet@2 + displayName: 'Use .NET Core 3.1.x' + inputs: + packageType: 'sdk' + version: '3.1.x' + - task: MicroBuildSigningPlugin@4 + displayName: 'Install Signing Plugin' + inputs: + signType: real + azureSubscription: 'MicroBuild Signing Task (MSEng)' + feedSource: 'https://mseng.pkgs.visualstudio.com/DefaultCollection/_packaging/MicroBuildToolset/nuget/v3/index.json' + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - task: JavaToolInstaller@0 displayName: Use Java 21 inputs: @@ -70,38 +87,16 @@ extends: mkdir -p jars mv .repository/com/microsoft/java/com.microsoft.java.debug.core/$RELEASE_VERSION/com.microsoft.java.debug.core*.jar jars/ - - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 - displayName: Sign core.jar + - task: CmdLine@2 + displayName: Sign core jars inputs: - ConnectedServiceName: $(ConnectedServiceName) - AppRegistrationClientId: $(AppRegistrationClientId) - AppRegistrationTenantId: $(AppRegistrationTenantId) - AuthAKVName: $(AuthAKVName) - AuthCertName: $(AuthCertName) - AuthSignCertName: $(AuthSignCertName) - FolderPath: jars - Pattern: com.microsoft.java.debug.core*.jar - signConfigType: inlineSignParams - inlineOperation: |- - [ - { - "KeyCode" : "CP-447347-Java", - "OperationCode" : "JavaSign", - "Parameters" : { - "SigAlg" : "SHA256withRSA", - "Timestamp" : "-tsa http://sha256timestamp.ws.digicert.com/sha256/timestamp" - }, - "ToolName" : "sign", - "ToolVersion" : "1.0" - }, - { - "KeyCode" : "CP-447347-Java", - "OperationCode" : "JavaVerify", - "Parameters" : {}, - "ToolName" : "sign", - "ToolVersion" : "1.0" - } - ] + script: | + files=$(find . -type f -name "com.microsoft.java.debug.core*.jar") + for file in $files; do + fileName=$(basename "$file") + dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$fileName" /certs:100010171 + done + workingDirectory: 'jars' - task: CmdLine@2 displayName: install signed core.jar inputs: @@ -116,38 +111,16 @@ extends: mkdir -p jars mv .repository/com/microsoft/java/com.microsoft.java.debug.plugin/$RELEASE_VERSION/com.microsoft.java.debug.plugin*.jar jars/ - - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 - displayName: Sign plugin.jar + - task: CmdLine@2 + displayName: Sign plugin jars inputs: - ConnectedServiceName: $(ConnectedServiceName) - AppRegistrationClientId: $(AppRegistrationClientId) - AppRegistrationTenantId: $(AppRegistrationTenantId) - AuthAKVName: $(AuthAKVName) - AuthCertName: $(AuthCertName) - AuthSignCertName: $(AuthSignCertName) - FolderPath: jars - Pattern: com.microsoft.java.debug.plugin*.jar - signConfigType: inlineSignParams - inlineOperation: |- - [ - { - "KeyCode" : "CP-447347-Java", - "OperationCode" : "JavaSign", - "Parameters" : { - "SigAlg" : "SHA256withRSA", - "Timestamp" : "-tsa http://sha256timestamp.ws.digicert.com/sha256/timestamp" - }, - "ToolName" : "sign", - "ToolVersion" : "1.0" - }, - { - "KeyCode" : "CP-447347-Java", - "OperationCode" : "JavaVerify", - "Parameters" : {}, - "ToolName" : "sign", - "ToolVersion" : "1.0" - } - ] + script: | + files=$(find . -type f -name "com.microsoft.java.debug.plugin*.jar") + for file in $files; do + fileName=$(basename "$file") + dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$fileName" /certs:100010171 + done + workingDirectory: 'jars' - task: CopyFiles@2 displayName: "Copy plugin.jar to: $(Build.ArtifactStagingDirectory)" inputs: diff --git a/.azure-pipelines/signjars-rc.yml b/.azure-pipelines/signjars-rc.yml index c0c11e6cc..201ff20f8 100644 --- a/.azure-pipelines/signjars-rc.yml +++ b/.azure-pipelines/signjars-rc.yml @@ -37,13 +37,26 @@ extends: artifactName: m2 targetPath: $(Build.ArtifactStagingDirectory)/m2 displayName: "Publish Artifact: m2" - - output: pipelineArtifact - artifactName: p2 - targetPath: $(Build.ArtifactStagingDirectory)/p2 - displayName: "Publish Artifact: p2" steps: - checkout: self fetchTags: true + - task: UsePythonVersion@0 + displayName: 'Use Python 3.11.x' + inputs: + versionSpec: 3.11.x + - task: UseDotNet@2 + displayName: 'Use .NET Core 3.1.x' + inputs: + packageType: 'sdk' + version: '3.1.x' + - task: MicroBuildSigningPlugin@4 + displayName: 'Install Signing Plugin' + inputs: + signType: real + azureSubscription: 'MicroBuild Signing Task (MSEng)' + feedSource: 'https://mseng.pkgs.visualstudio.com/DefaultCollection/_packaging/MicroBuildToolset/nuget/v3/index.json' + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - task: JavaToolInstaller@0 displayName: Use Java 21 inputs: @@ -71,38 +84,16 @@ extends: mkdir -p jars mv .repository/com/microsoft/java/com.microsoft.java.debug.core/$RELEASE_VERSION/com.microsoft.java.debug.core*.jar jars/ - - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 - displayName: Sign core.jar + - task: CmdLine@2 + displayName: Sign core jars inputs: - ConnectedServiceName: $(ConnectedServiceName) - AppRegistrationClientId: $(AppRegistrationClientId) - AppRegistrationTenantId: $(AppRegistrationTenantId) - AuthAKVName: $(AuthAKVName) - AuthCertName: $(AuthCertName) - AuthSignCertName: $(AuthSignCertName) - FolderPath: jars - Pattern: com.microsoft.java.debug.core*.jar - signConfigType: inlineSignParams - inlineOperation: |- - [ - { - "KeyCode" : "CP-447347-Java", - "OperationCode" : "JavaSign", - "Parameters" : { - "SigAlg" : "SHA256withRSA", - "Timestamp" : "-tsa http://sha256timestamp.ws.digicert.com/sha256/timestamp" - }, - "ToolName" : "sign", - "ToolVersion" : "1.0" - }, - { - "KeyCode" : "CP-447347-Java", - "OperationCode" : "JavaVerify", - "Parameters" : {}, - "ToolName" : "sign", - "ToolVersion" : "1.0" - } - ] + script: | + files=$(find . -type f -name "com.microsoft.java.debug.core*.jar") + for file in $files; do + fileName=$(basename "$file") + dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$fileName" /certs:100010171 + done + workingDirectory: 'jars' - task: CmdLine@2 displayName: install signed core.jar inputs: @@ -116,84 +107,20 @@ extends: mkdir -p jars mv .repository/com/microsoft/java/com.microsoft.java.debug.plugin/$RELEASE_VERSION/com.microsoft.java.debug.plugin*.jar jars/ - - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 - displayName: Sign plugin.jar + - task: CmdLine@2 + displayName: Sign plugin jars inputs: - ConnectedServiceName: $(ConnectedServiceName) - AppRegistrationClientId: $(AppRegistrationClientId) - AppRegistrationTenantId: $(AppRegistrationTenantId) - AuthAKVName: $(AuthAKVName) - AuthCertName: $(AuthCertName) - AuthSignCertName: $(AuthSignCertName) - FolderPath: jars - Pattern: com.microsoft.java.debug.plugin*.jar - signConfigType: inlineSignParams - inlineOperation: |- - [ - { - "KeyCode" : "CP-447347-Java", - "OperationCode" : "JavaSign", - "Parameters" : { - "SigAlg" : "SHA256withRSA", - "Timestamp" : "-tsa http://sha256timestamp.ws.digicert.com/sha256/timestamp" - }, - "ToolName" : "sign", - "ToolVersion" : "1.0" - }, - { - "KeyCode" : "CP-447347-Java", - "OperationCode" : "JavaVerify", - "Parameters" : {}, - "ToolName" : "sign", - "ToolVersion" : "1.0" - } - ] + script: | + files=$(find . -type f -name "com.microsoft.java.debug.plugin*.jar") + for file in $files; do + fileName=$(basename "$file") + dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$fileName" /certs:100010171 + done + workingDirectory: 'jars' - task: CmdLine@2 displayName: install signed plugin.jar inputs: script: cp jars/com.microsoft.java.debug.plugin*.jar .repository/com/microsoft/java/com.microsoft.java.debug.plugin/$RELEASE_VERSION/ - - task: CmdLine@2 - displayName: Build p2 artifacts - inputs: - script: |- - # 3. Build the p2 artifacts. - ./mvnw clean package -f com.microsoft.java.debug.repository/pom.xml -Dmaven.repo.local=./.repository - - mkdir -p p2/target - cp -r com.microsoft.java.debug.repository/target/repository p2/target/ - cp com.microsoft.java.debug.repository/pushToBintray.sh p2/ - - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 - displayName: Sign p2 - inputs: - ConnectedServiceName: $(ConnectedServiceName) - AppRegistrationClientId: $(AppRegistrationClientId) - AppRegistrationTenantId: $(AppRegistrationTenantId) - AuthAKVName: $(AuthAKVName) - AuthCertName: $(AuthCertName) - AuthSignCertName: $(AuthSignCertName) - FolderPath: p2 - Pattern: "*.jar" - signConfigType: inlineSignParams - inlineOperation: |- - [ - { - "KeyCode" : "CP-447347-Java", - "OperationCode" : "JavaSign", - "Parameters" : { - "SigAlg" : "SHA256withRSA", - "Timestamp" : "-tsa http://sha256timestamp.ws.digicert.com/sha256/timestamp" - }, - "ToolName" : "sign", - "ToolVersion" : "1.0" - }, - { - "KeyCode" : "CP-447347-Java", - "OperationCode" : "JavaVerify", - "Parameters" : {}, - "ToolName" : "sign", - "ToolVersion" : "1.0" - } - ] - task: CmdLine@2 displayName: build m2 artifacts inputs: @@ -214,43 +141,19 @@ extends: mkdir -p m2/com.microsoft.java.debug.plugin cp com.microsoft.java.debug.plugin/target/com.microsoft.java.debug.plugin*.jar m2/com.microsoft.java.debug.plugin cp com.microsoft.java.debug.plugin/pom.xml m2/com.microsoft.java.debug.plugin/com.microsoft.java.debug.plugin-$RELEASE_VERSION.pom - - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 - displayName: Sign m2 + - task: CmdLine@2 + displayName: Sign m2 jars inputs: - ConnectedServiceName: $(ConnectedServiceName) - AppRegistrationClientId: $(AppRegistrationClientId) - AppRegistrationTenantId: $(AppRegistrationTenantId) - AuthAKVName: $(AuthAKVName) - AuthCertName: $(AuthCertName) - AuthSignCertName: $(AuthSignCertName) - FolderPath: m2 - Pattern: "*.jar" - signConfigType: inlineSignParams - inlineOperation: |- - [ - { - "KeyCode" : "CP-447347-Java", - "OperationCode" : "JavaSign", - "Parameters" : { - "SigAlg" : "SHA256withRSA", - "Timestamp" : "-tsa http://sha256timestamp.ws.digicert.com/sha256/timestamp" - }, - "ToolName" : "sign", - "ToolVersion" : "1.0" - }, - { - "KeyCode" : "CP-447347-Java", - "OperationCode" : "JavaVerify", - "Parameters" : {}, - "ToolName" : "sign", - "ToolVersion" : "1.0" - } - ] + script: | + files=$(find . -type f -name "*.jar") + for file in $files; do + # fileName=$(basename "$file") + dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$file" /certs:100010171 + done + workingDirectory: 'm2' - task: CopyFiles@2 - displayName: "Copy p2/m2 to: $(Build.ArtifactStagingDirectory)" + displayName: "Copy m2 to: $(Build.ArtifactStagingDirectory)" inputs: Contents: |+ - p2/** m2/** - TargetFolder: $(Build.ArtifactStagingDirectory) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c147c4838..71d726f63 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,7 +20,7 @@ jobs: java-version: '21' - name: Cache local Maven repository - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} @@ -51,7 +51,7 @@ jobs: java-version: '21' - name: Cache local Maven repository - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: $HOME/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} @@ -77,7 +77,7 @@ jobs: java-version: '21' - name: Cache local Maven repository - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} From b98d4936c52ea933b00faacfac67fd4fcb86e790 Mon Sep 17 00:00:00 2001 From: Roland Grunberg Date: Thu, 17 Apr 2025 03:47:29 -0400 Subject: [PATCH 53/72] Update target platform to more closely follow JDT-LS. (#585) - Update Apache Commons IO from 2.11.0 to 2.19.0 Signed-off-by: Roland Grunberg --- com.microsoft.java.debug.plugin/.classpath | 2 +- .../META-INF/MANIFEST.MF | 2 +- com.microsoft.java.debug.plugin/pom.xml | 2 +- .../com.microsoft.java.debug.tp.target | 42 ++++--------------- 4 files changed, 11 insertions(+), 37 deletions(-) diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index dbf84ced8..a83e822fe 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -7,7 +7,7 @@ - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index ea6b7127e..073c31c8e 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -21,7 +21,7 @@ Require-Bundle: org.eclipse.core.runtime, org.apache.commons.lang3, org.eclipse.lsp4j, com.google.guava -Bundle-ClassPath: lib/commons-io-2.11.0.jar, +Bundle-ClassPath: lib/commons-io-2.19.0.jar, ., lib/rxjava-2.2.21.jar, lib/reactive-streams-1.0.4.jar, diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index dde9c7ec6..d2d7b9aa4 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -51,7 +51,7 @@ commons-io commons-io - 2.11.0 + 2.19.0 com.microsoft.java diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index 5c386e467..8a85443a4 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -1,43 +1,17 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - + + + + + + From b77b590ad89345557c87c975a4b41c5f648e65f1 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Wed, 23 Apr 2025 13:39:54 +0800 Subject: [PATCH 54/72] Override MicroBuild Output Folder (#586) * Override MicroBuild Output Folder * Use env to override MicroBuildOutputFolder --- .azure-pipelines/signjars-nightly.yml | 1 + .azure-pipelines/signjars-rc.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.azure-pipelines/signjars-nightly.yml b/.azure-pipelines/signjars-nightly.yml index 19ab29baf..b2ab77ab7 100644 --- a/.azure-pipelines/signjars-nightly.yml +++ b/.azure-pipelines/signjars-nightly.yml @@ -62,6 +62,7 @@ extends: feedSource: 'https://mseng.pkgs.visualstudio.com/DefaultCollection/_packaging/MicroBuildToolset/nuget/v3/index.json' env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) + MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)' - task: JavaToolInstaller@0 displayName: Use Java 21 inputs: diff --git a/.azure-pipelines/signjars-rc.yml b/.azure-pipelines/signjars-rc.yml index 201ff20f8..8e639bafb 100644 --- a/.azure-pipelines/signjars-rc.yml +++ b/.azure-pipelines/signjars-rc.yml @@ -57,6 +57,7 @@ extends: feedSource: 'https://mseng.pkgs.visualstudio.com/DefaultCollection/_packaging/MicroBuildToolset/nuget/v3/index.json' env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) + MicroBuildOutputFolderOverride: '$(Agent.TempDirectory)' - task: JavaToolInstaller@0 displayName: Use Java 21 inputs: From 54058b9eb466576a7a77c9303963ca88967ec58b Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Sun, 27 Apr 2025 10:50:06 +0800 Subject: [PATCH 55/72] Bump version to 0.53.2 (#587) --- com.microsoft.java.debug.core/pom.xml | 2 +- com.microsoft.java.debug.plugin/.classpath | 2 +- com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF | 4 ++-- com.microsoft.java.debug.plugin/pom.xml | 4 ++-- com.microsoft.java.debug.repository/category.xml | 2 +- com.microsoft.java.debug.repository/pom.xml | 2 +- com.microsoft.java.debug.target/pom.xml | 2 +- pom.xml | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index 64827ab13..d63b93c01 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.53.1 + 0.53.2 com.microsoft.java.debug.core jar diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index a83e822fe..de9b5e366 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -11,6 +11,6 @@ - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 073c31c8e..442e9bb17 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true -Bundle-Version: 0.53.1 +Bundle-Version: 0.53.2 Bundle-RequiredExecutionEnvironment: JavaSE-11 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin @@ -25,4 +25,4 @@ Bundle-ClassPath: lib/commons-io-2.19.0.jar, ., lib/rxjava-2.2.21.jar, lib/reactive-streams-1.0.4.jar, - lib/com.microsoft.java.debug.core-0.53.1.jar + lib/com.microsoft.java.debug.core-0.53.2.jar diff --git a/com.microsoft.java.debug.plugin/pom.xml b/com.microsoft.java.debug.plugin/pom.xml index d2d7b9aa4..2e2c0e6a8 100644 --- a/com.microsoft.java.debug.plugin/pom.xml +++ b/com.microsoft.java.debug.plugin/pom.xml @@ -5,7 +5,7 @@ com.microsoft.java java-debug-parent - 0.53.1 + 0.53.2 com.microsoft.java.debug.plugin eclipse-plugin @@ -56,7 +56,7 @@ com.microsoft.java com.microsoft.java.debug.core - 0.53.1 + 0.53.2 diff --git a/com.microsoft.java.debug.repository/category.xml b/com.microsoft.java.debug.repository/category.xml index 5d3e664df..f30a2f4c4 100644 --- a/com.microsoft.java.debug.repository/category.xml +++ b/com.microsoft.java.debug.repository/category.xml @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.repository/pom.xml b/com.microsoft.java.debug.repository/pom.xml index 40519fce2..573aff2ac 100644 --- a/com.microsoft.java.debug.repository/pom.xml +++ b/com.microsoft.java.debug.repository/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.53.1 + 0.53.2 com.microsoft.java.debug.repository eclipse-repository diff --git a/com.microsoft.java.debug.target/pom.xml b/com.microsoft.java.debug.target/pom.xml index 737decee1..8e49b638b 100644 --- a/com.microsoft.java.debug.target/pom.xml +++ b/com.microsoft.java.debug.target/pom.xml @@ -4,7 +4,7 @@ com.microsoft.java java-debug-parent - 0.53.1 + 0.53.2 com.microsoft.java.debug.tp ${base.name} :: Target Platform diff --git a/pom.xml b/pom.xml index 53aec5c9c..9f59485d9 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ ${base.name} :: Parent The Java Debug Server is an implementation of Visual Studio Code (VSCode) Debug Protocol. It can be used in Visual Studio Code to debug Java programs. https://github.com/Microsoft/java-debug - 0.53.1 + 0.53.2 pom Java Debug Server for Visual Studio Code From bccb4808571f2fcdce497e5585320ff62491c9f5 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Thu, 26 Jun 2025 09:54:18 +0800 Subject: [PATCH 56/72] switch sha256 to calculate temp file name (#592) --- .../debug/core/adapter/handler/LaunchUtils.java | 15 +++++++++------ .../com.microsoft.java.debug.tp.target | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchUtils.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchUtils.java index 27fdb1813..7370328b2 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchUtils.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/LaunchUtils.java @@ -95,7 +95,7 @@ public static synchronized Path generateClasspathJar(String[] classPaths) throws // In jar manifest, the absolute path C:\a.jar should be converted to the url style file:///C:/a.jar String classpathValue = String.join(" ", classpathUrls); attributes.put(Attributes.Name.CLASS_PATH, classpathValue); - String baseName = "cp_" + getMd5(classpathValue); + String baseName = "cp_" + getSha256(classpathValue); cleanupTempFiles(baseName, ".jar"); Path tempfile = createTempFile(baseName, ".jar"); JarOutputStream jar = new JarOutputStream(new FileOutputStream(tempfile.toFile()), manifest); @@ -127,7 +127,7 @@ public static synchronized Path generateArgfile(String vmArgs, String[] classPat } argfile = argfile.replace("\\", "\\\\"); - String baseName = "cp_" + getMd5(argfile); + String baseName = "cp_" + getSha256(argfile); cleanupTempFiles(baseName, ".argfile"); Path tempfile = createTempFile(baseName, ".argfile"); Files.writeString(tempfile, argfile, encoding); @@ -364,12 +364,15 @@ private static Path createTempFile(String baseName, String suffix) throws IOExce } } - private static String getMd5(String input) { + private static String getSha256(String input) { try { - MessageDigest md = MessageDigest.getInstance("MD5"); + MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] messageDigest = md.digest(input.getBytes()); - BigInteger md5 = new BigInteger(1, messageDigest); - return md5.toString(Character.MAX_RADIX); + // Use only first 16 bytes to keep filename shorter + byte[] truncated = new byte[16]; + System.arraycopy(messageDigest, 0, truncated, 0, 16); + BigInteger hash = new BigInteger(1, truncated); + return hash.toString(Character.MAX_RADIX); } catch (NoSuchAlgorithmException e) { return Integer.toString(input.hashCode(), Character.MAX_RADIX); } diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index 8a85443a4..1d322d84c 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -2,7 +2,7 @@ - + From a1f68f4265458e9386bf16d107c2383b68690e43 Mon Sep 17 00:00:00 2001 From: Jinbo Wang Date: Fri, 27 Jun 2025 15:01:25 +0800 Subject: [PATCH 57/72] Update codesign task (#593) --- .azure-pipelines/signjars-nightly.yml | 10 ++++++---- .azure-pipelines/signjars-rc.yml | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.azure-pipelines/signjars-nightly.yml b/.azure-pipelines/signjars-nightly.yml index b2ab77ab7..2045f54ce 100644 --- a/.azure-pipelines/signjars-nightly.yml +++ b/.azure-pipelines/signjars-nightly.yml @@ -45,20 +45,22 @@ extends: steps: - checkout: self fetchTags: true - - task: UsePythonVersion@0 - displayName: 'Use Python 3.11.x' - inputs: - versionSpec: 3.11.x - task: UseDotNet@2 displayName: 'Use .NET Core 3.1.x' inputs: packageType: 'sdk' version: '3.1.x' + - task: UseDotNet@2 + displayName: 'Use .NET Core 8.0.x' + inputs: + packageType: 'sdk' + version: '8.0.x' - task: MicroBuildSigningPlugin@4 displayName: 'Install Signing Plugin' inputs: signType: real azureSubscription: 'MicroBuild Signing Task (MSEng)' + useEsrpCli: true feedSource: 'https://mseng.pkgs.visualstudio.com/DefaultCollection/_packaging/MicroBuildToolset/nuget/v3/index.json' env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) diff --git a/.azure-pipelines/signjars-rc.yml b/.azure-pipelines/signjars-rc.yml index 8e639bafb..cd3377cfd 100644 --- a/.azure-pipelines/signjars-rc.yml +++ b/.azure-pipelines/signjars-rc.yml @@ -40,20 +40,22 @@ extends: steps: - checkout: self fetchTags: true - - task: UsePythonVersion@0 - displayName: 'Use Python 3.11.x' - inputs: - versionSpec: 3.11.x - task: UseDotNet@2 displayName: 'Use .NET Core 3.1.x' inputs: packageType: 'sdk' version: '3.1.x' + - task: UseDotNet@2 + displayName: 'Use .NET Core 8.0.x' + inputs: + packageType: 'sdk' + version: '8.0.x' - task: MicroBuildSigningPlugin@4 displayName: 'Install Signing Plugin' inputs: signType: real azureSubscription: 'MicroBuild Signing Task (MSEng)' + useEsrpCli: true feedSource: 'https://mseng.pkgs.visualstudio.com/DefaultCollection/_packaging/MicroBuildToolset/nuget/v3/index.json' env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) From 36a6b3f3606bd500fd7b257c55ae2572893d319e Mon Sep 17 00:00:00 2001 From: chagong Date: Wed, 13 Aug 2025 14:35:29 +0800 Subject: [PATCH 58/72] Update CODEOWNERS (#599) --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b11684f52..9d7579633 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @testforstephen @jdneo \ No newline at end of file +* @testforstephen @jdneo @chagong @wenytang-ms From c7642bc738b2dbfeefa0ea85e338d9eefd0ebc25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Aug 2025 15:09:45 +0800 Subject: [PATCH 59/72] Bump org.apache.commons:commons-lang3 in /com.microsoft.java.debug.core (#594) Bumps org.apache.commons:commons-lang3 from 3.6 to 3.18.0. --- updated-dependencies: - dependency-name: org.apache.commons:commons-lang3 dependency-version: 3.18.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: chagong --- com.microsoft.java.debug.core/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.core/pom.xml b/com.microsoft.java.debug.core/pom.xml index d63b93c01..8bfdb7292 100644 --- a/com.microsoft.java.debug.core/pom.xml +++ b/com.microsoft.java.debug.core/pom.xml @@ -42,7 +42,7 @@ org.apache.commons commons-lang3 - 3.6 + 3.18.0 com.google.code.gson From a209e39b9e07e5b2eacb74a2a2250da99c6751e3 Mon Sep 17 00:00:00 2001 From: Snjeza Date: Wed, 13 Aug 2025 09:18:31 +0200 Subject: [PATCH 60/72] Improve ResolveMainClassHandler.resolveMainClassUnderPaths (#596) Co-authored-by: wenyt <75360946+wenytang-ms@users.noreply.github.com> --- .../plugin/internal/ResolveMainClassHandler.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java index 38ad1532b..fc8189445 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveMainClassHandler.java @@ -35,6 +35,7 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.search.IJavaSearchConstants; import org.eclipse.jdt.core.search.IJavaSearchScope; @@ -100,8 +101,18 @@ private List resolveMainClassCore(List arguments) { private List resolveMainClassUnderPaths(List parentPaths) { // Limit to search main method from source code only. - IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(ProjectUtils.getJavaProjects(), - IJavaSearchScope.REFERENCED_PROJECTS | IJavaSearchScope.SOURCES); + IJavaProject[] projects; + if (parentPaths == null || parentPaths.isEmpty()) { + projects = ProjectUtils.getJavaProjects(); + } else { + projects = Stream.of(ProjectUtils.getAllProjects()) + .filter(p -> ProjectUtils.isJavaProject(p) && p.getLocation() != null && ResourceUtils.isContainedIn(p.getLocation(), parentPaths)) + .map(p -> JavaCore.create(p)) + .filter(p -> p.exists()) + .toArray(IJavaProject[]::new); + } + IJavaSearchScope searchScope = SearchEngine.createJavaSearchScope(projects, + IJavaSearchScope.SOURCES); SearchPattern pattern = createMainMethodSearchPattern(); final List res = new ArrayList<>(); SearchRequestor requestor = new SearchRequestor() { From 65dcd3d77c548bd842a74e472c8b25cd8489905a Mon Sep 17 00:00:00 2001 From: wenyt <75360946+wenytang-ms@users.noreply.github.com> Date: Thu, 21 Aug 2025 10:24:44 +0800 Subject: [PATCH 61/72] ci: update the pipeline to do publish (#602) --- .azure-pipelines/publish-to-maven.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.azure-pipelines/publish-to-maven.yml b/.azure-pipelines/publish-to-maven.yml index 58dc58cf2..a1ef0a204 100644 --- a/.azure-pipelines/publish-to-maven.yml +++ b/.azure-pipelines/publish-to-maven.yml @@ -22,6 +22,10 @@ extends: - stage: PublishToMaven jobs: - job: PublishToMaven + displayName: Maven Release job + templateContext: + type: releaseJob + isProduction: true steps: - task: DownloadBuildArtifacts@1 displayName: 'Download Jar Artifacts' From 3bec8be6525ff8ced06d57157c847870adc2bc49 Mon Sep 17 00:00:00 2001 From: wenyt <75360946+wenytang-ms@users.noreply.github.com> Date: Mon, 25 Aug 2025 11:27:00 +0800 Subject: [PATCH 62/72] ci: support PME to do code sign (#603) --- .azure-pipelines/signjars-nightly.yml | 1 + .azure-pipelines/signjars-rc.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.azure-pipelines/signjars-nightly.yml b/.azure-pipelines/signjars-nightly.yml index 2045f54ce..70fe81be2 100644 --- a/.azure-pipelines/signjars-nightly.yml +++ b/.azure-pipelines/signjars-nightly.yml @@ -61,6 +61,7 @@ extends: signType: real azureSubscription: 'MicroBuild Signing Task (MSEng)' useEsrpCli: true + ConnectedPMEServiceName: 0e38ce24-f885-4c86-b997-5887b97a1899 feedSource: 'https://mseng.pkgs.visualstudio.com/DefaultCollection/_packaging/MicroBuildToolset/nuget/v3/index.json' env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) diff --git a/.azure-pipelines/signjars-rc.yml b/.azure-pipelines/signjars-rc.yml index cd3377cfd..819d39de7 100644 --- a/.azure-pipelines/signjars-rc.yml +++ b/.azure-pipelines/signjars-rc.yml @@ -56,6 +56,7 @@ extends: signType: real azureSubscription: 'MicroBuild Signing Task (MSEng)' useEsrpCli: true + ConnectedPMEServiceName: 0e38ce24-f885-4c86-b997-5887b97a1899 feedSource: 'https://mseng.pkgs.visualstudio.com/DefaultCollection/_packaging/MicroBuildToolset/nuget/v3/index.json' env: SYSTEM_ACCESSTOKEN: $(System.AccessToken) From 77d10aa0e8030da7570bdde8400f2d0fb3aa9e7d Mon Sep 17 00:00:00 2001 From: wenyt <75360946+wenytang-ms@users.noreply.github.com> Date: Tue, 26 Aug 2025 10:16:24 +0800 Subject: [PATCH 63/72] ci: sign jar with access token (#604) --- .azure-pipelines/signjars-nightly.yml | 4 ++++ .azure-pipelines/signjars-rc.yml | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/.azure-pipelines/signjars-nightly.yml b/.azure-pipelines/signjars-nightly.yml index 70fe81be2..8b1e8d12a 100644 --- a/.azure-pipelines/signjars-nightly.yml +++ b/.azure-pipelines/signjars-nightly.yml @@ -101,6 +101,8 @@ extends: dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$fileName" /certs:100010171 done workingDirectory: 'jars' + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - task: CmdLine@2 displayName: install signed core.jar inputs: @@ -125,6 +127,8 @@ extends: dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$fileName" /certs:100010171 done workingDirectory: 'jars' + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - task: CopyFiles@2 displayName: "Copy plugin.jar to: $(Build.ArtifactStagingDirectory)" inputs: diff --git a/.azure-pipelines/signjars-rc.yml b/.azure-pipelines/signjars-rc.yml index 819d39de7..e87444603 100644 --- a/.azure-pipelines/signjars-rc.yml +++ b/.azure-pipelines/signjars-rc.yml @@ -98,6 +98,8 @@ extends: dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$fileName" /certs:100010171 done workingDirectory: 'jars' + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - task: CmdLine@2 displayName: install signed core.jar inputs: @@ -121,6 +123,8 @@ extends: dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$fileName" /certs:100010171 done workingDirectory: 'jars' + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - task: CmdLine@2 displayName: install signed plugin.jar inputs: @@ -155,6 +159,8 @@ extends: dotnet "$MBSIGN_APPFOLDER/DDSignFiles.dll" -- /file:"$file" /certs:100010171 done workingDirectory: 'm2' + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - task: CopyFiles@2 displayName: "Copy m2 to: $(Build.ArtifactStagingDirectory)" inputs: From 614b10df99acc34ced35fc50b9b70a8191719e2c Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 3 Sep 2025 16:30:26 +0800 Subject: [PATCH 64/72] Add AI triage workflow and LLM documentation for automated issue management (#606) * Initial plan * Add triage agent workflow and LLM documentation from vscode-gradle Co-authored-by: chagong <831821+chagong@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: chagong <831821+chagong@users.noreply.github.com> --- .github/llms.md | 38 +++++++++ .github/workflows/triage-agent.yml | 122 +++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+) create mode 100644 .github/llms.md create mode 100644 .github/workflows/triage-agent.yml diff --git a/.github/llms.md b/.github/llms.md new file mode 100644 index 000000000..55d69b238 --- /dev/null +++ b/.github/llms.md @@ -0,0 +1,38 @@ +# Extension Pack for Java +Extension Pack for Java is a collection of popular extensions that can help write, test and debug Java applications in Visual Studio Code. By installing Extension Pack for Java, the following extensions are installed: + +- [📦 Language Support for Java™ by Red Hat ](https://marketplace.visualstudio.com/items?itemName=redhat.java) + - Code Navigation + - Auto Completion + - Refactoring + - Code Snippets +- [📦 Debugger for Java](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-debug) + - Debugging +- [📦 Test Runner for Java](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-test) + - Run & Debug JUnit/TestNG Test Cases +- [📦 Maven for Java](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-maven) + - Project Scaffolding + - Custom Goals +- [📦 Gradle for Java](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-gradle) + - View Gradle tasks and project dependencies + - Gradle file authoring + - Import Gradle projects via [Gradle Build Server](https://github.com/microsoft/build-server-for-gradle) +- [📦 Project Manager for Java](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-dependency) + - Manage Java projects, referenced libraries, resource files, packages, classes, and class members +- [📦 Visual Studio IntelliCode](https://marketplace.visualstudio.com/items?itemName=VisualStudioExptTeam.vscodeintellicode) + - AI-assisted development + - Completion list ranked by AI + +## Label +When labeling an issue, follow the rules below per label category: +### General Rules +- Analyze if the issue is related with the scope of using extensions for Java development. If not, STOP labelling IMMEDIATELY. +- Assign label per category. +- If a category is not applicable or you're unsure, you may skip it. +- Do not assign multiple labels within the same category, unless explicitly allowed as an exception. + +### Issue Type Labels +- [bug]: Primary label for real bug issues +- [enhancement]: Primary label for enhancement issues +- [documentation]: Primary label for documentation issues +- [question]: Primary label for question issues \ No newline at end of file diff --git a/.github/workflows/triage-agent.yml b/.github/workflows/triage-agent.yml new file mode 100644 index 000000000..185cf8f32 --- /dev/null +++ b/.github/workflows/triage-agent.yml @@ -0,0 +1,122 @@ +name: AI Triage - Label and Comment on New Issues +on: + issues: + types: [opened] + workflow_dispatch: + inputs: + issue_number: + description: 'Issue number to triage (manual run). e.g. 123' + required: true + +permissions: + issues: write + contents: read + +jobs: + label_and_comment: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Get issue data + id: get_issue + uses: actions/github-script@v6 + with: + script: | + const eventName = context.eventName; + let issue; + if (eventName === 'workflow_dispatch') { + const inputs = context.payload.inputs || {}; + const issueNumber = inputs.issue_number || inputs.issueNumber; + if (!issueNumber) core.setFailed('Input issue_number is required for manual run.'); + const { data } = await github.rest.issues.get({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: parseInt(issueNumber, 10), + }); + issue = data; + } else if (context.payload.issue) { + issue = context.payload.issue; + } else { + core.setFailed('No issue information found in the event payload.'); + } + core.setOutput('id', String(issue.number)); + core.setOutput('user', String((issue.user && issue.user.login) || '')); + core.setOutput('title', String(issue.title || '')); + core.setOutput('body', String(issue.body || '')); + const labelNames = (issue.labels || []).map(label => label.name); + core.setOutput('labels', JSON.stringify(labelNames)); + + - name: Call Azure Function + id: call_azure_function + env: + PAYLOAD: >- + { + "authToken": "${{ secrets.GITHUB_TOKEN }}", + "repoId": "microsoft/java-debug", + "issueData": { + "id": ${{ steps.get_issue.outputs.id }}, + "user": ${{ toJson(steps.get_issue.outputs.user) }}, + "title": ${{ toJson(steps.get_issue.outputs.title) }}, + "body": ${{ toJson(steps.get_issue.outputs.body) }}, + "labels": ${{ steps.get_issue.outputs.labels }} + }, + "mode": "DirectUpdate" + } + + run: | + # Make the HTTP request with improved error handling and timeouts + echo "Making request to triage agent..." + + # Add timeout handling and better error detection + set +e # Don't exit on curl failure + response=$(timeout ${{ vars.TRIAGE_AGENT_TIMEOUT }} curl \ + --max-time 0 \ + --connect-timeout 30 \ + --fail-with-body \ + --silent \ + --show-error \ + --write-out "HTTPSTATUS:%{http_code}" \ + --header "Content-Type: application/json" \ + --request POST \ + --data "$PAYLOAD" \ + ${{ secrets.TRIAGE_FUNCTION_LINK }} 2>&1) + + curl_exit_code=$? + set -e # Re-enable exit on error + + echo "Curl exit code: $curl_exit_code" + + # Check if curl command timed out or failed + if [ $curl_exit_code -eq 124 ]; then + echo "❌ Request timed out after 650 seconds" + exit 1 + elif [ $curl_exit_code -ne 0 ]; then + echo "❌ Curl command failed with exit code: $curl_exit_code" + echo "Response: $response" + exit 1 + fi + + # Extract HTTP status code and response body + http_code=$(echo "$response" | grep -o "HTTPSTATUS:[0-9]*" | cut -d: -f2) + response_body=$(echo "$response" | sed 's/HTTPSTATUS:[0-9]*$//') + + echo "HTTP Status Code: $http_code" + + # Validate HTTP status code + if [ -z "$http_code" ]; then + echo "❌ Failed to extract HTTP status code from response" + echo "Raw response: $response" + exit 1 + fi + + # Check if the request was successful + if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then + echo "✅ Azure Function call succeeded" + else + echo "❌ Azure Function call failed with status code: $http_code" + echo "Response: $response_body" + exit 1 + fi \ No newline at end of file From ab5d534f5af932fc2fcb3f3c54be9777151b5c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Fu=C3=9Fenegger?= Date: Sat, 11 Oct 2025 04:33:46 +0200 Subject: [PATCH 65/72] Update target platform to 4.38 (#607) The 4.37 builds disappeared, breaking the build. --- .../com.microsoft.java.debug.tp.target | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index 1d322d84c..baf2807df 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -2,7 +2,7 @@ - + From 4c80493fa08dd31f4adc22722b8423ed148837ff Mon Sep 17 00:00:00 2001 From: Karl-Erik Enkelmann <110300169+playdohface@users.noreply.github.com> Date: Mon, 3 Nov 2025 09:24:35 +0100 Subject: [PATCH 66/72] Handle unavailable sources in compliance with DAP spec (#609) --- .../debug/core/adapter/handler/StackTraceRequestHandler.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index 49f304771..3fa0a9a9b 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -220,8 +220,10 @@ private Types.StackFrame convertDebuggerStackFrameToClient(StackFrameInfo jdiFra } else { // For other unavailable method, such as lambda expression's built-in methods run/accept/apply, // display "Unknown Source" in the Call Stack View. - clientSource = null; + clientSource = new Types.Source("Unknown Source", "unknown", 0); } + // DAP specifies lineNumber to be set to 0 when unavailable + clientLineNumber = 0; } else if (DebugSettings.getCurrent().debugSupportOnDecompiledSource == Switch.ON && clientSource != null && clientSource.path != null) { // Align the original line with the decompiled line. From 6ff846580e33dd5f935d86da80674a4de15f1527 Mon Sep 17 00:00:00 2001 From: mozhuanzuojing <63572041+mozhuanzuojing@users.noreply.github.com> Date: Mon, 3 Nov 2025 16:49:23 +0800 Subject: [PATCH 67/72] Update tycho-version 5.0.0 (#598) * Update tycho-version 4.0.13 upgrade tycho * bump JavaSE-11 to JavaSE-21 of eclipse config * Update maven-wrapper.properties bump maven wrapper 3.0.11 * Update pom.xml bump tycho 5.0.0 * mvn wrapper:wrapper -Dmaven=3.9.11 --------- Co-authored-by: Changyong Gong --- .mvn/wrapper/maven-wrapper.jar | Bin 47774 -> 0 bytes .mvn/wrapper/maven-wrapper.properties | 3 +- com.microsoft.java.debug.core/.classpath | 2 +- com.microsoft.java.debug.plugin/.classpath | 2 +- .../META-INF/MANIFEST.MF | 2 +- .../com.microsoft.java.debug.tp.target | 5 +- mvnw | 394 ++++++++++-------- mvnw.cmd | 332 ++++++++------- pom.xml | 2 +- 9 files changed, 430 insertions(+), 312 deletions(-) delete mode 100644 .mvn/wrapper/maven-wrapper.jar diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index 41c70a7e0b7da7ecbbcf53b62aacdf8bc81e10b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47774 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 Be7*nx diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 9e0264d04..44f3cf2c1 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1 +1,2 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.3/apache-maven-3.9.3-bin.zip \ No newline at end of file +distributionType=only-script +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip diff --git a/com.microsoft.java.debug.core/.classpath b/com.microsoft.java.debug.core/.classpath index 9ba41a249..b6fe6b96c 100644 --- a/com.microsoft.java.debug.core/.classpath +++ b/com.microsoft.java.debug.core/.classpath @@ -13,7 +13,7 @@ - + diff --git a/com.microsoft.java.debug.plugin/.classpath b/com.microsoft.java.debug.plugin/.classpath index de9b5e366..b2be945c8 100644 --- a/com.microsoft.java.debug.plugin/.classpath +++ b/com.microsoft.java.debug.plugin/.classpath @@ -1,6 +1,6 @@ - + diff --git a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF index 442e9bb17..f2ceffb53 100644 --- a/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF +++ b/com.microsoft.java.debug.plugin/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Java Debug Server Plugin Bundle-SymbolicName: com.microsoft.java.debug.plugin;singleton:=true Bundle-Version: 0.53.2 -Bundle-RequiredExecutionEnvironment: JavaSE-11 +Bundle-RequiredExecutionEnvironment: JavaSE-21 Bundle-ActivationPolicy: lazy Bundle-Activator: com.microsoft.java.debug.plugin.internal.JavaDebuggerServerPlugin Bundle-Vendor: Microsoft diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index baf2807df..deabb9f3e 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -1,4 +1,6 @@ - + + + @@ -14,4 +16,5 @@ + diff --git a/mvnw b/mvnw index e96ccd5fb..e9cf8d330 100755 --- a/mvnw +++ b/mvnw @@ -19,209 +19,277 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir +# Apache Maven Wrapper startup batch script, version 3.3.3 # # Optional ENV vars # ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output # ---------------------------------------------------------------------------- -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac -fi +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 fi fi - ;; -esac + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" +} - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } - saveddir=`pwd` +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac - M2_HOME=`dirname "$PRG"`/.. +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} - cd "$saveddir" - # echo Using m2 at $M2_HOME +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" fi -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" fi -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" - # TODO classpath? +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" fi -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" fi -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true fi else - JAVACMD="`which java`" + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 fi fi -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" fi -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" fi +fi - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi fi - # end of workaround done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; + set -f fi -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" fi -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd index 019bd74d7..3fd2be860 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -1,143 +1,189 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" - -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.3 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/pom.xml b/pom.xml index 9f59485d9..b8320ef8f 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ Java Debug Server for Visual Studio Code UTF-8 - 4.0.6 + 5.0.0 ${basedir} From dabcc49979f45e34216a83dd9fbd126852f6ec1f Mon Sep 17 00:00:00 2001 From: mozhuanzuojing <63572041+mozhuanzuojing@users.noreply.github.com> Date: Mon, 10 Nov 2025 10:14:04 +0800 Subject: [PATCH 68/72] Update build.yml add distribution: 'temurin' of `JDK` (#600) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update build.yml add distribution: 'temurin' of `JDK` add distribution: 'temurin' of JavaSE-21 * upgrade actions v4 、v5 * format yml --------- Co-authored-by: Changyong Gong Co-authored-by: wenyt <75360946+wenytang-ms@users.noreply.github.com> --- .github/workflows/build.yml | 115 ++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 56 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 71d726f63..553d95a9a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,80 +12,83 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v5 - - name: Set up JDK 21 - uses: actions/setup-java@v1 - with: - java-version: '21' + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'temurin' - - name: Cache local Maven repository - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- + - name: Cache local Maven repository + uses: actions/cache@v4 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- - - name: Verify - run: ./mvnw clean verify -U + - name: Verify + run: ./mvnw clean verify -U - - name: Checkstyle - run: ./mvnw checkstyle:check + - name: Checkstyle + run: ./mvnw checkstyle:check windows: name: Windows runs-on: windows-latest timeout-minutes: 30 steps: - - name: Set git to use LF - run: | - git config --global core.autocrlf false - git config --global core.eol lf + - name: Set git to use LF + run: | + git config --global core.autocrlf false + git config --global core.eol lf - - uses: actions/checkout@v2 + - uses: actions/checkout@v5 - - name: Set up JDK 21 - uses: actions/setup-java@v1 - with: - java-version: '21' + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'temurin' - - name: Cache local Maven repository - uses: actions/cache@v4 - with: - path: $HOME/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- + - name: Cache local Maven repository + uses: actions/cache@v4 + with: + path: $HOME/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- - - name: Verify - run: ./mvnw.cmd clean verify + - name: Verify + run: ./mvnw.cmd clean verify - - name: Checkstyle - run: ./mvnw.cmd checkstyle:check + - name: Checkstyle + run: ./mvnw.cmd checkstyle:check darwin: name: macOS runs-on: macos-latest timeout-minutes: 30 steps: - - uses: actions/checkout@v2 - - - name: Set up JDK 21 - uses: actions/setup-java@v1 - with: - java-version: '21' - - - name: Cache local Maven repository - uses: actions/cache@v4 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} - restore-keys: | - ${{ runner.os }}-maven- - - - name: Verify - run: ./mvnw clean verify -U - - - name: Checkstyle - run: ./mvnw checkstyle:check + - uses: actions/checkout@v5 + + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + java-version: '21' + distribution: 'temurin' + + - name: Cache local Maven repository + uses: actions/cache@v4 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + + - name: Verify + run: ./mvnw clean verify -U + + - name: Checkstyle + run: ./mvnw checkstyle:check From 905c7ba292bf52e7ed324a8fab80669b3806a6e5 Mon Sep 17 00:00:00 2001 From: Changyong Gong Date: Tue, 11 Nov 2025 13:46:33 +0800 Subject: [PATCH 69/72] chore: add triage open issues workflow (#613) --- .github/workflows/triage-agent.yml | 5 +- .github/workflows/triage-all-open-issues.yml | 145 +++++++++++++++++++ 2 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/triage-all-open-issues.yml diff --git a/.github/workflows/triage-agent.yml b/.github/workflows/triage-agent.yml index 185cf8f32..f1df6e117 100644 --- a/.github/workflows/triage-agent.yml +++ b/.github/workflows/triage-agent.yml @@ -1,4 +1,4 @@ -name: AI Triage - Label and Comment on New Issues +name: AI Triage on: issues: types: [opened] @@ -8,6 +8,9 @@ on: description: 'Issue number to triage (manual run). e.g. 123' required: true +run-name: >- + AI Triage for Issue #${{ github.event.issue.number || github.event.inputs.issue_number }} + permissions: issues: write contents: read diff --git a/.github/workflows/triage-all-open-issues.yml b/.github/workflows/triage-all-open-issues.yml new file mode 100644 index 000000000..092f4ef70 --- /dev/null +++ b/.github/workflows/triage-all-open-issues.yml @@ -0,0 +1,145 @@ +name: AI Triage - Process All Open Issues +on: + workflow_dispatch: + inputs: + dry_run: + description: 'Dry run mode - only list issues without processing' + required: false + default: false + type: boolean + max_issues: + description: 'Maximum number of issues to process (0 = all)' + required: false + default: '0' + type: string + +permissions: + issues: write + contents: read + actions: write + +jobs: + get_open_issues: + runs-on: ubuntu-latest + outputs: + issue_numbers: ${{ steps.get_issues.outputs.issue_numbers }} + total_count: ${{ steps.get_issues.outputs.total_count }} + + steps: + - name: Get all open issues + id: get_issues + uses: actions/github-script@v6 + with: + script: | + // Use Search API to filter issues at API level + const { data } = await github.rest.search.issuesAndPullRequests({ + q: `repo:${context.repo.owner}/${context.repo.repo} is:issue is:open -label:ai-triaged -label:invalid`, + sort: 'created', + order: 'asc', + per_page: 100 + }); + + const actualIssues = data.items; + + let issuesToProcess = actualIssues; + const maxIssues = parseInt('${{ inputs.max_issues }}' || '0'); + + if (maxIssues > 0 && actualIssues.length > maxIssues) { + issuesToProcess = actualIssues.slice(0, maxIssues); + console.log(`Limiting to first ${maxIssues} issues out of ${actualIssues.length} total`); + } + + const issueNumbers = issuesToProcess.map(issue => issue.number); + const totalCount = issuesToProcess.length; + + console.log(`Found ${actualIssues.length} open issues, processing ${totalCount}:`); + issuesToProcess.forEach(issue => { + console.log(` #${issue.number}: ${issue.title}`); + }); + + core.setOutput('issue_numbers', JSON.stringify(issueNumbers)); + core.setOutput('total_count', totalCount); + + process_issues: + runs-on: ubuntu-latest + needs: get_open_issues + if: needs.get_open_issues.outputs.total_count > 0 + + strategy: + # Process issues one by one (max-parallel: 1) + max-parallel: 1 + matrix: + issue_number: ${{ fromJSON(needs.get_open_issues.outputs.issue_numbers) }} + + steps: + - name: Log current issue being processed + run: | + echo "🔄 Processing issue #${{ matrix.issue_number }}" + echo "Total issues to process: ${{ needs.get_open_issues.outputs.total_count }}" + + - name: Check if dry run mode + if: inputs.dry_run == true + run: | + echo "🔍 DRY RUN MODE: Would process issue #${{ matrix.issue_number }}" + echo "Skipping actual triage processing" + + - name: Trigger triage workflow for issue + if: inputs.dry_run != true + uses: actions/github-script@v6 + with: + script: | + const issueNumber = '${{ matrix.issue_number }}'; + + try { + console.log(`Triggering triage workflow for issue #${issueNumber}`); + + const response = await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'triage-agent.yml', + ref: 'main', + inputs: { + issue_number: issueNumber + } + }); + + console.log(`✅ Successfully triggered triage workflow for issue #${issueNumber}`); + + } catch (error) { + console.error(`❌ Failed to trigger triage workflow for issue #${issueNumber}:`, error); + core.setFailed(`Failed to process issue #${issueNumber}: ${error.message}`); + } + + - name: Wait for workflow completion + if: inputs.dry_run != true + run: | + echo "⏳ Waiting for triage workflow to complete for issue #${{ matrix.issue_number }}..." + echo "Timeout: ${{ vars.TRIAGE_AGENT_TIMEOUT }} seconds" + sleep ${{ vars.TRIAGE_AGENT_TIMEOUT }} # Wait for triage workflow completion + + summary: + runs-on: ubuntu-latest + needs: [get_open_issues, process_issues] + if: always() + + steps: + - name: Print summary + run: | + echo "## Triage Processing Summary" + echo "Total open issues found: ${{ needs.get_open_issues.outputs.total_count }}" + + if [ "${{ inputs.dry_run }}" == "true" ]; then + echo "Mode: DRY RUN (no actual processing performed)" + else + echo "Mode: FULL PROCESSING" + fi + + if [ "${{ needs.process_issues.result }}" == "success" ]; then + echo "✅ All issues processed successfully" + elif [ "${{ needs.process_issues.result }}" == "failure" ]; then + echo "❌ Some issues failed to process" + elif [ "${{ needs.process_issues.result }}" == "skipped" ]; then + echo "⏭️ Processing was skipped (no open issues found)" + else + echo "⚠️ Processing completed with status: ${{ needs.process_issues.result }}" + fi From b62897e444a5b522b68dfb2c73aae21614d1fe30 Mon Sep 17 00:00:00 2001 From: Karl-Erik Enkelmann <110300169+playdohface@users.noreply.github.com> Date: Mon, 24 Nov 2025 07:49:45 +0100 Subject: [PATCH 70/72] Set source to null when unavailable in a StackTrace (#614) --- .../debug/core/adapter/handler/StackTraceRequestHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index 3fa0a9a9b..3bb319a01 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -220,7 +220,7 @@ private Types.StackFrame convertDebuggerStackFrameToClient(StackFrameInfo jdiFra } else { // For other unavailable method, such as lambda expression's built-in methods run/accept/apply, // display "Unknown Source" in the Call Stack View. - clientSource = new Types.Source("Unknown Source", "unknown", 0); + clientSource = null; } // DAP specifies lineNumber to be set to 0 when unavailable clientLineNumber = 0; From 81339de8108b50dfc93d2dc47dc48c72d8904902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathias=20Fu=C3=9Fenegger?= Date: Tue, 9 Dec 2025 02:13:35 +0100 Subject: [PATCH 71/72] Fix lspFrame.source NPE on stackTrace request (#616) * Fix lspFrame.source NPE on stackTrace request Follow up to: - https://github.com/microsoft/java-debug/pull/614 - https://github.com/microsoft/java-debug/pull/609 With the change to set the line number to 0 the jdiLineNumber != lspFrame.line comparison can evaluate to true: dap> lspFrame Types$StackFrame@78 column: 1 id: 6 line: 0 name: "0x000000002f0bc000.invokeVirtual(Object,Object)" presentationHint: "subtle" source: null dap> jdiLineNumber -1 `source` being null caused an NPE * Fix line number comparison in StackTraceRequestHandler --------- Co-authored-by: Changyong Gong --- .../core/adapter/handler/StackTraceRequestHandler.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index 3bb319a01..f63d1b24e 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -29,9 +29,9 @@ import com.google.gson.JsonObject; import com.microsoft.java.debug.core.AsyncJdwpUtils; import com.microsoft.java.debug.core.DebugSettings; +import com.microsoft.java.debug.core.DebugSettings.Switch; import com.microsoft.java.debug.core.DebugUtility; import com.microsoft.java.debug.core.IBreakpoint; -import com.microsoft.java.debug.core.DebugSettings.Switch; import com.microsoft.java.debug.core.adapter.AdapterUtils; import com.microsoft.java.debug.core.adapter.IDebugAdapterContext; import com.microsoft.java.debug.core.adapter.IDebugRequestHandler; @@ -40,13 +40,13 @@ import com.microsoft.java.debug.core.adapter.SourceType; import com.microsoft.java.debug.core.adapter.formatter.SimpleTypeFormatter; import com.microsoft.java.debug.core.adapter.variables.StackFrameReference; +import com.microsoft.java.debug.core.protocol.Events.TelemetryEvent; import com.microsoft.java.debug.core.protocol.Messages.Response; import com.microsoft.java.debug.core.protocol.Requests.Arguments; import com.microsoft.java.debug.core.protocol.Requests.Command; import com.microsoft.java.debug.core.protocol.Requests.StackTraceArguments; import com.microsoft.java.debug.core.protocol.Responses; import com.microsoft.java.debug.core.protocol.Types; -import com.microsoft.java.debug.core.protocol.Events.TelemetryEvent; import com.sun.jdi.AbsentInformationException; import com.sun.jdi.IncompatibleThreadStateException; import com.sun.jdi.LocalVariable; @@ -114,7 +114,7 @@ public CompletableFuture handle(Command command, Arguments arguments, result.add(lspFrame); frameReference.setSource(lspFrame.source); int jdiLineNumber = AdapterUtils.convertLineNumber(jdiFrame.lineNumber, context.isDebuggerLinesStartAt1(), context.isClientLinesStartAt1()); - if (jdiLineNumber != lspFrame.line) { + if (jdiLineNumber >= 0 && jdiLineNumber != lspFrame.line) { decompiledClasses.add(lspFrame.source.path); } } From 9623b8ff69b188c5d0325110a5977a2623a67ea1 Mon Sep 17 00:00:00 2001 From: Changyong Gong Date: Tue, 16 Dec 2025 15:42:19 +0800 Subject: [PATCH 72/72] fix: lspFrame.source.path is null (#618) * fix: lspFrame.source.path is null * fix: update bundle location --- .../debug/core/adapter/handler/StackTraceRequestHandler.java | 2 +- .../com.microsoft.java.debug.tp.target | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java index f63d1b24e..6f54bcedb 100644 --- a/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java +++ b/com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/StackTraceRequestHandler.java @@ -114,7 +114,7 @@ public CompletableFuture handle(Command command, Arguments arguments, result.add(lspFrame); frameReference.setSource(lspFrame.source); int jdiLineNumber = AdapterUtils.convertLineNumber(jdiFrame.lineNumber, context.isDebuggerLinesStartAt1(), context.isClientLinesStartAt1()); - if (jdiLineNumber >= 0 && jdiLineNumber != lspFrame.line) { + if (jdiLineNumber != lspFrame.line && lspFrame.source != null && lspFrame.source.path != null) { decompiledClasses.add(lspFrame.source.path); } } diff --git a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target index deabb9f3e..31462a770 100644 --- a/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target +++ b/com.microsoft.java.debug.target/com.microsoft.java.debug.tp.target @@ -4,7 +4,7 @@ - +