Merge pull request #2945 from apache/delivery

Sync release124 with delivery for rc3
diff --git a/extide/gradle/src/org/netbeans/modules/gradle/GradleModuleFileCache21.java b/extide/gradle/src/org/netbeans/modules/gradle/GradleModuleFileCache21.java
index f0be755..b81a28a 100644
--- a/extide/gradle/src/org/netbeans/modules/gradle/GradleModuleFileCache21.java
+++ b/extide/gradle/src/org/netbeans/modules/gradle/GradleModuleFileCache21.java
@@ -247,17 +247,17 @@
         // the general GAV format is - <group>:<artifact>:<version/snapshot>[:<classifier>][@extension]
         int firstColon = gav.indexOf(':'); // NOI18N
         int versionColon = gav.indexOf(':', firstColon + 1); // NOI18N
-        int versionEnd = gav.indexOf(':', versionColon + 1); // NO18N
+        int versionEnd = versionColon > firstColon ? gav.indexOf(':', versionColon + 1) : -1; // NO18N
 
+        if (firstColon == -1 || versionColon == -1 || firstColon == versionColon) {
+            throw new IllegalArgumentException("Invalid GAV format: '" + gav + "'"); //NOI18N
+        }
         int end = versionEnd == -1 ? gav.length() : versionEnd;
 
-        if (firstColon == -1 || firstColon == versionColon) {
-            throw new IllegalArgumentException("Invalid GAV format: " + gav); //NOI18N
-        }
         return new String[]{
             gav.substring(0, firstColon),
             gav.substring(firstColon + 1, versionColon),
-             gav.substring(versionColon + 1, end)
+            gav.substring(versionColon + 1, end)
         };
     }
 }
diff --git a/extide/gradle/test/unit/src/org/netbeans/modules/gradle/GradleModuleFileCache21Test.java b/extide/gradle/test/unit/src/org/netbeans/modules/gradle/GradleModuleFileCache21Test.java
index 1371d81..aa70337 100644
--- a/extide/gradle/test/unit/src/org/netbeans/modules/gradle/GradleModuleFileCache21Test.java
+++ b/extide/gradle/test/unit/src/org/netbeans/modules/gradle/GradleModuleFileCache21Test.java
@@ -35,9 +35,9 @@
      */
     public void testGavSplitFixedVersion() throws Exception {
         String[] parts = GradleModuleFileCache21.gavSplit("io.micronaut:micronaut-core:2.3.4"); // NOI18N
-        assertEquals(parts[0], "io.micronaut"); // NOI18N
-        assertEquals(parts[1], "micronaut-core"); // NOI18N
-        assertEquals(parts[2], "2.3.4"); // NOI18N
+        assertEquals("io.micronaut", parts[0]);
+        assertEquals("micronaut-core", parts[1]);
+        assertEquals("2.3.4", parts[2]);
     }
 
     /**
@@ -46,15 +46,63 @@
      */
     public void testGavSplitFixedSnapshotWithMavenTimestamp() throws Exception {
         String[] parts = GradleModuleFileCache21.gavSplit("io.micronaut:micronaut-core:2.3.4-SNAPSHOT:20210302.164619-21"); // NOI18N
-        assertEquals(parts[0], "io.micronaut"); // NOI18N
-        assertEquals(parts[1], "micronaut-core"); // NOI18N
-        assertEquals(parts[2], "2.3.4-SNAPSHOT"); // NOI18N
+        assertEquals("io.micronaut", parts[0]); 
+        assertEquals("micronaut-core", parts[1]);
+        assertEquals("2.3.4-SNAPSHOT", parts[2]);
     }
 
     public void testGavSplitFixedSnapshotWithoutUnqiueId() throws Exception {
         String[] parts = GradleModuleFileCache21.gavSplit("io.micronaut:micronaut-core:2.3.4-SNAPSHOT"); // NOI18N
-        assertEquals(parts[0], "io.micronaut"); // NOI18N
-        assertEquals(parts[1], "micronaut-core"); // NOI18N
-        assertEquals(parts[2], "2.3.4-SNAPSHOT"); // NOI18N
+        assertEquals("io.micronaut", parts[0]); 
+        assertEquals("micronaut-core", parts[1]);
+        assertEquals("2.3.4-SNAPSHOT", parts[2]);
+    }
+
+    public void testGavSplitIncomplete() throws Exception {
+        try {
+            GradleModuleFileCache21.gavSplit("junit:junit");
+            fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException iae) {
+            assertEquals("Invalid GAV format: 'junit:junit'", iae.getMessage());
+        }
+    }
+
+    public void testGavSplitIncomplete2() throws Exception {
+        try {
+            GradleModuleFileCache21.gavSplit("junit");
+            fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException iae) {
+            assertEquals("Invalid GAV format: 'junit'", iae.getMessage());
+        }
+    }
+
+    public void testGavSplitIncomplete3() throws Exception {
+        try {
+            GradleModuleFileCache21.gavSplit("");
+            fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException iae) {
+            assertEquals("Invalid GAV format: ''", iae.getMessage());
+        }
+    }
+
+    public void testGavSplitEmpty() throws Exception {
+        String[] parts = GradleModuleFileCache21.gavSplit("org.junit.jupiter:junit-jupiter-api:");
+        assertEquals("org.junit.jupiter", parts[0]); 
+        assertEquals("junit-jupiter-api", parts[1]);
+        assertEquals("", parts[2]);
+    }
+
+    public void testGavSplitEmpty2() throws Exception {
+        String[] parts = GradleModuleFileCache21.gavSplit("org.junit.jupiter::");
+        assertEquals("org.junit.jupiter", parts[0]); 
+        assertEquals("", parts[1]);
+        assertEquals("", parts[2]);
+    }
+
+    public void testGavSplitEmpty3() throws Exception {
+        String[] parts = GradleModuleFileCache21.gavSplit("::");
+        assertEquals("", parts[0]); 
+        assertEquals("", parts[1]);
+        assertEquals("", parts[2]);
     }
 }
diff --git a/java/java.disco/external/binaries-list b/java/java.disco/external/binaries-list
index 91428bd..3bad9e3 100644
--- a/java/java.disco/external/binaries-list
+++ b/java/java.disco/external/binaries-list
@@ -19,4 +19,4 @@
 C4BC772689D4BB2D4128C5E4966F765A8A76E904 org.apache.httpcomponents.client5:httpclient5:5.0.3
 EA298CD1CE1D860747149FBB5F6236300219F378 org.apache.httpcomponents.core5:httpcore5:5.0.2
 7CAEB2EEBDFB7ECA30E7F64E8138D977FC85AB80 org.apache.httpcomponents.core5:httpcore5-h2:5.0.2
-1D077029A7B08C314B27CCD611B00D84EABD7384 io.foojay.api:discoclient:1.0
+377AD361D9938A7E98166E69CED2CB159B73F108 io.foojay.api:discoclient:1.0.1
diff --git a/java/java.disco/external/discoclient-1.0-license.txt b/java/java.disco/external/discoclient-1.0.1-license.txt
similarity index 98%
rename from java/java.disco/external/discoclient-1.0-license.txt
rename to java/java.disco/external/discoclient-1.0.1-license.txt
index 0939fbd..7d2a9e3 100644
--- a/java/java.disco/external/discoclient-1.0-license.txt
+++ b/java/java.disco/external/discoclient-1.0.1-license.txt
@@ -1,6 +1,6 @@
 Name: DiscoClient
 Origin: Azul
-Version: 1.0
+Version: 1.0.1
 License: BSD-azul
 Description: A Java library that makes it easier to access the foojay discovery API
 Origin: https://github.com/foojay2020/discoclient
diff --git a/java/java.disco/nbproject/project.properties b/java/java.disco/nbproject/project.properties
index 878f30c..74925df 100644
--- a/java/java.disco/nbproject/project.properties
+++ b/java/java.disco/nbproject/project.properties
@@ -18,7 +18,7 @@
 is.autoload=true
 release.external/checker-qual-3.9.1.jar=modules/ext/checker-qual-3.9.1.jar
 release.external/commons-compress-1.20.jar=modules/ext/commons-compress-1.20.jar
-release.external/discoclient-1.0.jar=modules/ext/discoclient-1.0.jar
+release.external/discoclient-1.0.1.jar=modules/ext/discoclient-1.0.1.jar
 release.external/httpclient5-5.0.3.jar=modules/ext/httpclient5-5.0.3.jar
 release.external/httpcore5-5.0.2.jar=modules/ext/httpcore5-5.0.2.jar
 release.external/httpcore5-h2-5.0.2.jar=modules/ext/httpcore5-h2-5.0.2.jar
diff --git a/java/java.disco/nbproject/project.xml b/java/java.disco/nbproject/project.xml
index 8ae2221..065bc94 100644
--- a/java/java.disco/nbproject/project.xml
+++ b/java/java.disco/nbproject/project.xml
@@ -213,8 +213,8 @@
                 <binary-origin>external/httpcore5-h2-5.0.2.jar</binary-origin>
             </class-path-extension>
             <class-path-extension>
-                <runtime-relative-path>ext/discoclient-1.0.jar</runtime-relative-path>
-                <binary-origin>external/discoclient-1.0.jar</binary-origin>
+                <runtime-relative-path>ext/discoclient-1.0.1.jar</runtime-relative-path>
+                <binary-origin>external/discoclient-1.0.1.jar</binary-origin>
             </class-path-extension>
             <class-path-extension>
                 <runtime-relative-path>ext/httpclient5-5.0.3.jar</runtime-relative-path>
diff --git a/java/java.lsp.server/vscode/CHANGELOG.md b/java/java.lsp.server/vscode/CHANGELOG.md
index afab2dc..7e480a2 100644
--- a/java/java.lsp.server/vscode/CHANGELOG.md
+++ b/java/java.lsp.server/vscode/CHANGELOG.md
@@ -21,6 +21,13 @@
 
 -->
 
+## Version 12.4
+
+* Numerous fixes in Code Completion and Code navigation, like Go To Super implementation, Find all implementations,...
+* Go To Definition works for Gradle projects 
+* GDB version check for proper version usable in native-image debugger
+* mx project fixes
+
 ## Version 12.4 Beta
 
 * Test results UI added using Test Explorer UI extension
diff --git a/java/java.lsp.server/vscode/README.md b/java/java.lsp.server/vscode/README.md
index 36f9532..753c58b 100644
--- a/java/java.lsp.server/vscode/README.md
+++ b/java/java.lsp.server/vscode/README.md
@@ -21,8 +21,6 @@
 
 -->
 
-# 12.4 Beta release
-
 This is a technology preview of [Apache NetBeans](http://netbeans.org)
 based extension for VS Code. Use it to get all the _goodies of NetBeans_
 via the VS Code user interface! Run on __JDK8__[*], __JDK11__, __JDK15__, etc.
@@ -47,7 +45,7 @@
 * __GraalVM: Pause in Script__ - place a breakpoint into first executed polyglot script
 * Debugger __Java 8+__ - start test or main class on JDK8+ in polyglot mode
 * Progress shown for long running operations with cancel support for selected types
-* __Native Image Debugger__ is a new Run configuration added which allows Java style debugging of Ahead of Time compiled native-images, produced by GraalVM. It is experimental feature which works with GDB on Linux. GDB 7.11 or GDB 10.1 is required due to known issue [#26139](https://sourceware.org/bugzilla/show_bug.cgi?id=26139) in GDB 8 and 9.
+* __Native Image Debugger__ is a new Run configuration added which allows Java style debugging of Ahead of Time compiled native-images, produced by GraalVM. It is experimental feature which works with GDB on Linux. GDB 7.11 or GDB 10.1+ is required due to known issue [#26139](https://sourceware.org/bugzilla/show_bug.cgi?id=26139) in GDB 8 and 9.
 * __Micronaut and Spring__ support especially for YAML configuration files with code completion and source code navigation to Java.
 * __Test Explorer__ for Java tests results visualization and execution including editor code Lenses.
 * Improved Maven and Gradle support including multi-project projects, subprojects opening and Gradle priming builds.
@@ -62,6 +60,33 @@
 
 ![Override refactoring](images/Override_refactoring.png)
 
+## Test Explorer
+NetBeans Language Server provides Test Explorer view which allows to run all tests in a project, examine the results, go to source code and  run particular test.
+![Test Explorer](images/Test_explorer.png)
+
+
+## Native Image Debugger
+Experimental Support
+
+NetBeans Language Server allows Java like debugging of native images produced by GraalVM EE native-image tool. It is provided using GDB and via new Run configuration named __Launch Native Image__. This experimental feature works __now__ only on Linux with certain version of GDB, see above. GraalVM Enterprise Edition is needed as it produces full debug information for native images, at this time.
+
+In order to debug native image applications it is necessary to build such native image with debug information available. It can be done by providing following switches for native-image tool: 
+- `-g -O0` or 
+- `-H:Debug=2 -H:Optimize=0`. 
+
+### Using Native Image Maven Plugin
+It is possible to use [Native-Image Maven Plugin](https://www.graalvm.org/reference-manual/native-image/NativeImageMavenPlugin/) to run native-image builds for Maven projects. 
+In this case add following `<buildArgs>` into plugin `<configuration>`:
+```
+<buildArgs>
+  <buildArg>-g</buildArg>
+  <buildArg>-O0</buildArg>
+</buildArgs>
+```
+Setting project's Maven pom.xml to skip native-image build everytime when project is being built is a good practice.
+
+When native image is built, including debug info then add __Launch Native Image__ configuration to launch.json. Select it in Run & Debug activity window and press F5 to debug Java source code on native image.
+
 ## Supported Options
 
 * __netbeans.jdkhome__ - path to the JDK, see dedicated section below
@@ -86,8 +111,9 @@
 
 Apache NetBeans Language Server extension isn't the only Java supporting
 extension. To avoid duplicated code completion and other misleading clashes
-the extension disables certain functionality known to cause problems. This
-behavior can be disabled by setting `netbeans.conflict.check` setting to `false`.
+the extension disables certain functionality known to cause problems, this is done per __Workspace__. 
+
+This behavior can be disabled by setting `netbeans.conflict.check` setting to `false`.
 
 ## Contributing
 
diff --git a/java/java.lsp.server/vscode/images/Test_explorer.png b/java/java.lsp.server/vscode/images/Test_explorer.png
new file mode 100644
index 0000000..49c94fa
--- /dev/null
+++ b/java/java.lsp.server/vscode/images/Test_explorer.png
Binary files differ
diff --git a/java/java.lsp.server/vscode/package-lock.json b/java/java.lsp.server/vscode/package-lock.json
index f710c4b..3775aa2 100644
--- a/java/java.lsp.server/vscode/package-lock.json
+++ b/java/java.lsp.server/vscode/package-lock.json
@@ -1,6 +1,6 @@
 {
 	"name": "apache-netbeans-java",
-	"version": "12.3.9",
+	"version": "12.4.0",
 	"lockfileVersion": 1,
 	"requires": true,
 	"dependencies": {
diff --git a/java/java.lsp.server/vscode/package.json b/java/java.lsp.server/vscode/package.json
index 1a6670f..278a370 100644
--- a/java/java.lsp.server/vscode/package.json
+++ b/java/java.lsp.server/vscode/package.json
@@ -4,7 +4,7 @@
 	"description": "Apache NetBeans Language Server Extension for Visual Studio Code",
 	"author": "Apache NetBeans",
 	"license": "Apache 2.0",
-	"version": "12.3.9",
+	"version": "12.4.0",
 	"preview": true,
 	"repository": {
 		"type": "git",