diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 67db38a52..ca2ab11e1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -51,7 +51,7 @@ jobs: JAVA_HOME: "" NODE_OPTIONS: "--max-old-space-size=4096" - name: Upload lib - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: lib path: | @@ -93,7 +93,7 @@ jobs: restore-keys: | ${{ runner.os }}-vscode- - name: Download lib - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: lib path: extension/ diff --git a/extension/jdtls.ext/com.microsoft.gradle.bs.importer.target/com.microsoft.gradle.bs.importer.tp.target b/extension/jdtls.ext/com.microsoft.gradle.bs.importer.target/com.microsoft.gradle.bs.importer.tp.target index 4d5f4d344..e6151ef3f 100644 --- a/extension/jdtls.ext/com.microsoft.gradle.bs.importer.target/com.microsoft.gradle.bs.importer.tp.target +++ b/extension/jdtls.ext/com.microsoft.gradle.bs.importer.target/com.microsoft.gradle.bs.importer.tp.target @@ -22,11 +22,11 @@ - + - + diff --git a/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/GradleBuildServerBuildSupport.java b/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/GradleBuildServerBuildSupport.java index 978d36b9e..e004eae80 100644 --- a/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/GradleBuildServerBuildSupport.java +++ b/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/GradleBuildServerBuildSupport.java @@ -513,30 +513,33 @@ private void setProjectJdk(Map classpathMap, List classpathAttributes = new LinkedList<>(); - if (isModular) { - classpathAttributes.add(modularAttribute); + List classpathAttributes = new LinkedList<>(); + if (isModular) { + classpathAttributes.add(modularAttribute); + } + classpathAttributes.add(buildServerAttribute); + IClasspathEntry jdkEntry = JavaCore.newContainerEntry( + JavaRuntime.newJREContainerPath(vm), + ClasspathEntry.NO_ACCESS_RULES, + classpathAttributes.toArray(new IClasspathAttribute[0]), + false /*isExported*/ + ); + classpathMap.putIfAbsent(jdkEntry.getPath(), jdkEntry); + } catch (URISyntaxException e) { + throw new CoreException(new Status(IStatus.ERROR, ImporterPlugin.PLUGIN_ID, + "Invalid Java home: " + jvmBuildTarget.getJavaHome(), e)); } - classpathAttributes.add(buildServerAttribute); - IClasspathEntry jdkEntry = JavaCore.newContainerEntry( - JavaRuntime.newJREContainerPath(vm), - ClasspathEntry.NO_ACCESS_RULES, - classpathAttributes.toArray(new IClasspathAttribute[0]), - false /*isExported*/ - ); - classpathMap.putIfAbsent(jdkEntry.getPath(), jdkEntry); - } catch (URISyntaxException e) { - throw new CoreException(new Status(IStatus.ERROR, ImporterPlugin.PLUGIN_ID, - "Invalid Java home: " + jvmBuildTarget.getJavaHome(), e)); } } @@ -585,8 +588,10 @@ private JvmBuildTargetEx getJvmTarget(List buildTargets) throws Cor } if (StringUtils.isBlank(jvmTarget.getJavaHome()) || StringUtils.isBlank(jvmTarget.getGradleVersion())) { - throw new CoreException(new Status(IStatus.ERROR, ImporterPlugin.PLUGIN_ID, - "Invalid JVM build target: " + jvmTarget.toString())); + JavaLanguageServerPlugin.logException( + new CoreException(new Status(IStatus.WARNING, ImporterPlugin.PLUGIN_ID, + "Empty Java Home or Gradle Version in JVM target.")) + ); } return jvmTarget; @@ -641,7 +646,8 @@ private List getDependencyJars(DependencyModulesResult dependen } String classifier = artifactData.getClassifier(); try { - File jarFile = new File(new URI(uri)); + File artifactFile = new File(new URI(uri)); + File jarFile = Utils.getJarFile(artifactFile); if (classifier == null) { artifact = jarFile; } else if ("sources".equals(classifier)) { diff --git a/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/Utils.java b/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/Utils.java index fd312aee6..c365b5dd6 100644 --- a/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/Utils.java +++ b/extension/jdtls.ext/com.microsoft.gradle.bs.importer/src/com/microsoft/gradle/bs/importer/Utils.java @@ -2,14 +2,21 @@ import static org.eclipse.jdt.ls.core.internal.handlers.MapFlattener.getString; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.nio.file.Path; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IProject; @@ -22,6 +29,7 @@ import org.eclipse.core.runtime.URIUtil; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.ls.core.internal.JavaClientConnection.JavaLanguageClient; +import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin; import org.eclipse.jdt.ls.core.internal.ProjectUtils; import org.eclipse.jdt.ls.core.internal.preferences.Preferences; import org.eclipse.lsp4j.ExecuteCommandParams; @@ -214,4 +222,46 @@ public static void sendTelemetry(JavaLanguageClient client, Object message) { client.sendNotification(new ExecuteCommandParams("_java.gradle.buildServer.sendTelemetry", Arrays.asList(message))); } + + /** + * Extracts the jar file from the aar file, since JDT.LS is not able to understand + * the structure of aar files. + */ + public static File getJarFile(File file) { + + String filepath = file.getAbsolutePath(); + + if (filepath.endsWith(".aar")) { + + // Extracting classes.jar from AAR files + try(ZipInputStream is = new ZipInputStream(new FileInputStream(file))) { + + ZipEntry entry; + while ((entry = is.getNextEntry()) != null) { + if (entry.getName().equals("classes.jar")) { + String fileName = file.getName(); + fileName = fileName.substring(0, fileName.length() - 4); + fileName = fileName + ".jar"; + File outputFile = Path.of(file.getParentFile().getAbsolutePath(), fileName).toFile(); + try (FileOutputStream outputStream = new FileOutputStream(outputFile)) { + byte[] buffer = new byte[1024]; + int len; + while((len = is.read(buffer)) > 0) { + outputStream.write(buffer, 0, len); + } + return outputFile; + } + } + } + + } catch(IOException e) { + JavaLanguageServerPlugin.logException(e); + } + + } + + return file; + + } + } diff --git a/extension/src/stores/RootProjectsStore.ts b/extension/src/stores/RootProjectsStore.ts index f694e8b6e..2f07a6f89 100644 --- a/extension/src/stores/RootProjectsStore.ts +++ b/extension/src/stores/RootProjectsStore.ts @@ -7,7 +7,7 @@ import { RootProject } from "../rootProject/RootProject"; import { GRADLE_BUILD_FILE_NAMES } from "../constant"; async function getNestedRootProjectFolders(): Promise { - const matchingNestedWrapperFiles = await vscode.workspace.findFiles("**/{gradlew,gradlew.bat}"); + const matchingNestedWrapperFiles = await vscode.workspace.findFiles("**/{settings.gradle,settings.gradle.kts}"); return [...new Set(matchingNestedWrapperFiles.map((uri) => path.dirname(uri.fsPath)))]; } diff --git a/extension/src/test/testUtil.ts b/extension/src/test/testUtil.ts index 45ca12f0e..be0f6c33b 100644 --- a/extension/src/test/testUtil.ts +++ b/extension/src/test/testUtil.ts @@ -86,13 +86,13 @@ export function stubWorkspaceFolders(workspaceFolders: vscode.WorkspaceFolder[]) const getWorkspaceFolderStub = sinon.stub(vscode.workspace, "getWorkspaceFolder"); const dirnameStub = sinon.stub(path, "dirname"); workspaceFolders.forEach((workspaceFolder) => { - existsSyncStub.withArgs(path.join(workspaceFolder.uri.fsPath, "gradlew")).returns(true); + existsSyncStub.withArgs(path.join(workspaceFolder.uri.fsPath, "settings.gradle")).returns(true); getWorkspaceFolderStub.withArgs(sinon.match.has("fsPath", workspaceFolder.uri.fsPath)).returns(workspaceFolder); dirnameStub.withArgs(workspaceFolder.uri.fsPath).returns(workspaceFolder.uri.fsPath); }); sinon .stub(vscode.workspace, "findFiles") - .withArgs("**/{gradlew,gradlew.bat}") + .withArgs("**/{settings.gradle,settings.gradle.kts}") .returns(Promise.resolve(workspaceFolders.map((folder) => folder.uri))); } diff --git a/extension/src/util/index.ts b/extension/src/util/index.ts index 27d9ba0ef..cf05ca677 100644 --- a/extension/src/util/index.ts +++ b/extension/src/util/index.ts @@ -57,8 +57,8 @@ export function waitOnTcp(host: string, port: number): Promise { export function isGradleRootProject(rootProject: RootProject): boolean { return ( - fs.existsSync(path.join(rootProject.getProjectUri().fsPath, "gradlew")) || - fs.existsSync(path.join(rootProject.getProjectUri().fsPath, "gradlew.bat")) + fs.existsSync(path.join(rootProject.getProjectUri().fsPath, "settings.gradle")) || + fs.existsSync(path.join(rootProject.getProjectUri().fsPath, "settings.gradle.kts")) ); } diff --git a/extension/src/views/defaultProject/DefaultProjectsTreeDataProvider.ts b/extension/src/views/defaultProject/DefaultProjectsTreeDataProvider.ts index 89b87af65..2fc5ec0b6 100644 --- a/extension/src/views/defaultProject/DefaultProjectsTreeDataProvider.ts +++ b/extension/src/views/defaultProject/DefaultProjectsTreeDataProvider.ts @@ -55,7 +55,7 @@ export class DefaultProjectsTreeDataProvider implements vscode.TreeDataProvider< private async getChildrenForProjectTreeItem(element: ProjectTreeItem): Promise { const projectTaskItem = new ProjectTaskTreeItem("Tasks", vscode.TreeItemCollapsibleState.Collapsed, element); - projectTaskItem.setChildren([...element.groups, ...element.tasks]); + projectTaskItem.setChildren([...element.tasks, ...element.groups]); const results: vscode.TreeItem[] = [projectTaskItem]; const resourceUri = element.resourceUri; if (!resourceUri) { @@ -68,6 +68,6 @@ export class DefaultProjectsTreeDataProvider implements vscode.TreeDataProvider< path.dirname(resourceUri.fsPath), typeof element.label === "string" ? element.label : resourceUri.fsPath ); - return [...results, projectDependencyTreeItem]; + return [projectDependencyTreeItem, ...results]; } } diff --git a/extension/src/views/gradleTasks/GradleTasksTreeDataProvider.ts b/extension/src/views/gradleTasks/GradleTasksTreeDataProvider.ts index b37f0a931..d7c4007b7 100644 --- a/extension/src/views/gradleTasks/GradleTasksTreeDataProvider.ts +++ b/extension/src/views/gradleTasks/GradleTasksTreeDataProvider.ts @@ -213,11 +213,11 @@ export class GradleTasksTreeDataProvider implements vscode.TreeDataProvider { const projectTaskItem = new ProjectTaskTreeItem("Tasks", vscode.TreeItemCollapsibleState.Collapsed, element); - projectTaskItem.setChildren([...element.groups, ...element.tasks]); + projectTaskItem.setChildren([...element.tasks, ...element.groups]); const results: vscode.TreeItem[] = [projectTaskItem]; const resourceUri = element.resourceUri; if (!resourceUri) { - return results; + return [...results, ...element.subprojects]; } const projectDependencyTreeItem: ProjectDependencyTreeItem = new ProjectDependencyTreeItem( "Dependencies", @@ -226,7 +226,7 @@ export class GradleTasksTreeDataProvider implements vscode.TreeDataProvider