Skip to content

Commit 6b40c3c

Browse files
authored
Data Repo Aot Optimizations (#1713)
* Data Repo Aot Optimizations Signed-off-by: BoykoAlex <alex.boyko@broadcom.com> * Polish Signed-off-by: BoykoAlex <alex.boyko@broadcom.com> * WIP Signed-off-by: BoykoAlex <alex.boyko@broadcom.com> * WIP: Fix typo Signed-off-by: BoykoAlex <alex.boyko@broadcom.com> * Typo correction Signed-off-by: BoykoAlex <alex.boyko@broadcom.com> * Eclipse and VSCode command to execute maven goals Signed-off-by: BoykoAlex <alex.boyko@broadcom.com> * Tests Signed-off-by: BoykoAlex <alex.boyko@broadcom.com> * Fix test on win Signed-off-by: BoykoAlex <alex.boyko@broadcom.com> * Attempt to fix test on win Signed-off-by: BoykoAlex <alex.boyko@broadcom.com> * Boot RC2 and attempt to fix the test Signed-off-by: BoykoAlex <alex.boyko@broadcom.com> * Fix unit test on Windows Signed-off-by: BoykoAlex <alex.boyko@broadcom.com> * Workaround for lack of support in vscode-maven Signed-off-by: BoykoAlex <alex.boyko@broadcom.com> * Polish abd bit of fixing Signed-off-by: BoykoAlex <alex.boyko@broadcom.com> --------- Signed-off-by: BoykoAlex <alex.boyko@broadcom.com>
1 parent 870b881 commit 6b40c3c

File tree

47 files changed

+1997
-316
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1997
-316
lines changed

eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/META-INF/MANIFEST.MF

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ Require-Bundle: org.eclipse.jdt.launching;bundle-version="3.8.0",
2424
org.springsource.ide.eclipse.commons.core,
2525
org.eclipse.e4.ui.css.swt.theme,
2626
org.eclipse.swt,
27-
com.google.gson
27+
com.google.gson,
28+
org.eclipse.m2e.launching,
29+
org.eclipse.m2e.core
2830
Bundle-RequiredExecutionEnvironment: JavaSE-21
2931
Bundle-ActivationPolicy: lazy
3032
Export-Package: org.springframework.tooling.ls.eclipse.commons,

eclipse-language-servers/org.springframework.tooling.ls.eclipse.commons/plugin.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@
107107
class="org.springframework.tooling.ls.eclipse.commons.commands.OpenJarEntryInEditor"
108108
commandId="org.springframework.tooling.ls.eclipse.commons.commands.OpenJarEntryInEditor">
109109
</handler>
110+
<handler
111+
class="org.springframework.tooling.ls.eclipse.commons.commands.ExecuteMavenGoalHandler"
112+
commandId="maven.goal.custom">
113+
</handler>
110114
</extension>
111115
<extension
112116
point="org.eclipse.ui.commands">
@@ -195,6 +199,22 @@
195199
optional="false">
196200
</commandParameter>
197201
</command>
202+
<command
203+
id="maven.goal.custom"
204+
name="Explain with AI">
205+
<commandParameter
206+
id="org.eclipse.lsp4e.path.param"
207+
name="Resource Path (unnecessary, only to make lsp4e happy)"
208+
optional="true"
209+
typeId="org.eclipse.lsp4e.pathParameterType">
210+
</commandParameter>
211+
<commandParameter
212+
id="org.eclipse.lsp4e.command.param"
213+
name="Command id (unnecessary, only to make lsp4e happy)"
214+
optional="true"
215+
typeId="org.eclipse.lsp4e.commandParameterType">
216+
</commandParameter>
217+
</command>
198218
</extension>
199219
<extension
200220
point="org.eclipse.e4.ui.css.swt.theme">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Broadcom, Inc.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Broadcom, Inc. - initial API and implementation
10+
*******************************************************************************/
11+
package org.springframework.tooling.ls.eclipse.commons.commands;
12+
13+
import java.nio.file.Paths;
14+
15+
import org.eclipse.core.commands.AbstractHandler;
16+
import org.eclipse.core.commands.ExecutionEvent;
17+
import org.eclipse.core.commands.ExecutionException;
18+
import org.eclipse.core.resources.IContainer;
19+
import org.eclipse.core.resources.IFile;
20+
import org.eclipse.core.resources.IResource;
21+
import org.eclipse.core.runtime.CoreException;
22+
import org.eclipse.core.runtime.IPath;
23+
import org.eclipse.core.runtime.NullProgressMonitor;
24+
import org.eclipse.debug.core.DebugPlugin;
25+
import org.eclipse.debug.core.ILaunchConfiguration;
26+
import org.eclipse.debug.core.ILaunchConfigurationType;
27+
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
28+
import org.eclipse.debug.core.ILaunchManager;
29+
import org.eclipse.debug.ui.DebugUITools;
30+
import org.eclipse.debug.ui.IDebugUIConstants;
31+
import org.eclipse.debug.ui.RefreshTab;
32+
import org.eclipse.lsp4e.LSPEclipseUtils;
33+
import org.eclipse.lsp4e.command.LSPCommandHandler;
34+
import org.eclipse.lsp4j.Command;
35+
import org.eclipse.m2e.actions.MavenLaunchConstants;
36+
37+
import org.eclipse.m2e.core.MavenPlugin;
38+
import org.eclipse.m2e.core.internal.IMavenConstants;
39+
import org.eclipse.m2e.core.project.IMavenProjectFacade;
40+
import org.eclipse.m2e.core.project.IMavenProjectRegistry;
41+
import org.eclipse.m2e.core.project.IProjectConfiguration;
42+
43+
import com.google.gson.Gson;
44+
45+
@SuppressWarnings("restriction")
46+
public class ExecuteMavenGoalHandler extends AbstractHandler {
47+
48+
@Override
49+
public Object execute(ExecutionEvent event) throws ExecutionException {
50+
Command cmd = new Gson().fromJson(event.getParameter(LSPCommandHandler.LSP_COMMAND_PARAMETER_ID), Command.class);
51+
if (cmd != null) {
52+
try {
53+
String pomPath = (String) cmd.getArguments().get(0);
54+
String goal = (String) cmd.getArguments().get(1);
55+
System.out.println("Project: '%s', goal: '%s'".formatted(pomPath, goal));
56+
57+
IResource pomFile = LSPEclipseUtils.findResourceFor(Paths.get(pomPath).toUri());
58+
ILaunchConfiguration launchConfig = createLaunchConfiguration(pomFile.getParent(), goal);
59+
60+
DebugUITools.launch(launchConfig, ILaunchManager.RUN_MODE);
61+
} catch (Exception e) {
62+
throw new ExecutionException("Failed to execute Maven Goal command", e);
63+
}
64+
}
65+
throw new ExecutionException("Maven Goal Execution command is invalid");
66+
}
67+
68+
private ILaunchConfiguration createLaunchConfiguration(IContainer basedir, String goal) throws CoreException {
69+
ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
70+
ILaunchConfigurationType launchConfigurationType = launchManager
71+
.getLaunchConfigurationType(MavenLaunchConstants.LAUNCH_CONFIGURATION_TYPE_ID);
72+
73+
String safeConfigName = launchManager.generateLaunchConfigurationName("Goal `%s`".formatted(goal));
74+
75+
ILaunchConfigurationWorkingCopy workingCopy = launchConfigurationType.newInstance(null, safeConfigName);
76+
workingCopy.setAttribute(MavenLaunchConstants.ATTR_POM_DIR, basedir.getLocation().toOSString());
77+
workingCopy.setAttribute(MavenLaunchConstants.ATTR_GOALS, goal);
78+
workingCopy.setAttribute(IDebugUIConstants.ATTR_PRIVATE, true);
79+
workingCopy.setAttribute(RefreshTab.ATTR_REFRESH_SCOPE, "${project}"); //$NON-NLS-1$
80+
workingCopy.setAttribute(RefreshTab.ATTR_REFRESH_RECURSIVE, true);
81+
82+
setProjectConfiguration(workingCopy, basedir);
83+
84+
return workingCopy;
85+
}
86+
87+
private void setProjectConfiguration(ILaunchConfigurationWorkingCopy workingCopy, IContainer basedir) {
88+
IMavenProjectRegistry projectManager = MavenPlugin.getMavenProjectRegistry();
89+
IFile pomFile = basedir.getFile(IPath.fromOSString(IMavenConstants.POM_FILE_NAME));
90+
IMavenProjectFacade projectFacade = projectManager.create(pomFile, false, new NullProgressMonitor());
91+
if (projectFacade != null) {
92+
IProjectConfiguration configuration = projectFacade.getConfiguration();
93+
94+
String selectedProfiles = configuration.getSelectedProfiles();
95+
if (selectedProfiles != null && selectedProfiles.length() > 0) {
96+
workingCopy.setAttribute(MavenLaunchConstants.ATTR_PROFILES, selectedProfiles);
97+
}
98+
}
99+
}
100+
101+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Broadcom, Inc.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Broadcom, Inc. - initial API and implementation
10+
*******************************************************************************/
11+
package org.springframework.ide.vscode.commons.languageserver.util;
12+
13+
public class OS {
14+
15+
public static boolean isWindows() {
16+
String os = System.getProperty("os.name");
17+
if (os != null) {
18+
return os.toLowerCase().indexOf("win") >= 0;
19+
}
20+
return false;
21+
}
22+
23+
}

headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/util/ParentProcessWatcher.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ private boolean parentProcessStillRunning() {
7171
return true;
7272
}
7373
String command;
74-
if (isWindows()) {
74+
if (OS.isWindows()) {
7575
command = "cmd /c \"tasklist /FI \"PID eq " + pid + "\" | findstr " + pid + "\"";
7676
} else {
7777
command = "kill -0 " + pid;
@@ -85,7 +85,7 @@ private boolean parentProcessStillRunning() {
8585
process.destroy();
8686
finished = process.waitFor(POLL_DELAY_SECS, TimeUnit.SECONDS); // wait for the process to stop
8787
}
88-
if (isWindows() && finished && process.exitValue() > 1) {
88+
if (OS.isWindows() && finished && process.exitValue() > 1) {
8989
// the tasklist command should return 0 (parent process exists) or 1 (parent process doesn't exist)
9090
logger.info("The tasklist command: '{}' returns {}", command, process.exitValue());
9191
return true;
@@ -103,7 +103,7 @@ private boolean parentProcessStillRunning() {
103103
// It is only closed when the Process object is garbage collected (in its finalize() method).
104104
// On Windows, when the Java LS is idle, we need to explicitly request a GC,
105105
// to prevent an accumulation of zombie processes, as finalize() will be called.
106-
if (isWindows()) {
106+
if (OS.isWindows()) {
107107
// Java >= 9 doesn't close the handle when the process is garbage collected
108108
// We need to close the opened streams
109109
if (!isJava1x) {
@@ -134,11 +134,4 @@ public MessageConsumer apply(final MessageConsumer consumer) {
134134
};
135135
}
136136

137-
private static boolean isWindows() {
138-
String os = System.getProperty("os.name");
139-
if (os != null) {
140-
return os.toLowerCase().indexOf("win") >= 0;
141-
}
142-
return false;
143-
}
144137
}

headless-services/commons/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<parent>
1414
<groupId>org.springframework.boot</groupId>
1515
<artifactId>spring-boot-starter-parent</artifactId>
16-
<version>4.0.0-M3</version>
16+
<version>4.0.0-RC2</version>
1717
<relativePath></relativePath>
1818
</parent>
1919

headless-services/jdt-ls-extension/org.springframework.tooling.jdt.ls.commons/src/org/springframework/tooling/jdt/ls/commons/classpath/ClasspathUtil.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515

1616
import java.io.File;
1717
import java.net.MalformedURLException;
18+
import java.net.URI;
1819
import java.nio.file.Path;
20+
import java.nio.file.Paths;
1921
import java.util.ArrayList;
2022
import java.util.Collections;
2123
import java.util.HashSet;
@@ -244,14 +246,14 @@ public static ProjectBuild createProjectBuild(IJavaProject jp, Logger logger) {
244246
// if (facade != null) {
245247
// return ProjectBuild.createMavenBuild(facade.getPom().getLocationURI().toASCIIString());
246248
// } else {
247-
return ProjectBuild.createMavenBuild(jp.getProject().getFile("pom.xml").getLocationURI().toASCIIString());
249+
return ProjectBuild.createMavenBuild(fromIFile(jp.getProject().getFile("pom.xml")).toASCIIString());
248250
// }
249251
} else if (GradleProjectNature.isPresentOn(jp.getProject())) {
250252
IFile g = jp.getProject().getFile("build.gradle");
251253
if (!g.exists()) {
252254
g = jp.getProject().getFile("build.gradle.kts");
253255
}
254-
return ProjectBuild.createGradleBuild(g.exists() ? g.getLocationURI().toASCIIString() : null);
256+
return ProjectBuild.createGradleBuild(g.exists() ? fromIFile(g).toASCIIString() : null);
255257
} else {
256258
try {
257259
for (IClasspathEntry e : jp.getRawClasspath()) {
@@ -271,20 +273,24 @@ public static ProjectBuild createProjectBuild(IJavaProject jp, Logger logger) {
271273
if (likelyMaven) {
272274
IFile f = jp.getProject().getFile("pom.xml");
273275
if (f.exists()) {
274-
return ProjectBuild.createMavenBuild(f.getLocationURI().toASCIIString());
276+
return ProjectBuild.createMavenBuild(fromIFile(f).toASCIIString());
275277
}
276278
} else if (likelyGradle) {
277279
IFile g = jp.getProject().getFile("build.gradle");
278280
if (!g.exists()) {
279281
g = jp.getProject().getFile("build.gradle.kts");
280282
}
281283
if (g.exists()) {
282-
return ProjectBuild.createGradleBuild(g.getLocationURI().toASCIIString());
284+
return ProjectBuild.createGradleBuild(fromIFile(g).toASCIIString());
283285
}
284286
}
285287
// } catch (JavaModelException e) {
286288
// // ignore
287289
// }
288290
return new ProjectBuild(null, null);
289291
}
292+
293+
private static URI fromIFile(IFile f) {
294+
return Paths.get(f.getLocationURI()).toUri();
295+
}
290296
}

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/BootLanguageServerBootApp.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.springframework.ide.vscode.boot.index.cache.IndexCache;
4747
import org.springframework.ide.vscode.boot.index.cache.IndexCacheOnDiscDeltaBased;
4848
import org.springframework.ide.vscode.boot.index.cache.IndexCacheVoid;
49+
import org.springframework.ide.vscode.boot.java.BuildCommandProvider;
4950
import org.springframework.ide.vscode.boot.java.JavaDefinitionHandler;
5051
import org.springframework.ide.vscode.boot.java.beans.DependsOnDefinitionProvider;
5152
import org.springframework.ide.vscode.boot.java.beans.NamedDefinitionProvider;
@@ -436,8 +437,8 @@ ModulithService modulithService(SimpleLanguageServer server, JavaProjectFinder p
436437
}
437438

438439
@Bean
439-
DataRepositoryAotMetadataService dataAotMetadataService() {
440-
return new DataRepositoryAotMetadataService();
440+
DataRepositoryAotMetadataService dataAotMetadataService(FileObserver fileObserver, JavaProjectFinder projectFinder, BuildCommandProvider buildCmds) {
441+
return new DataRepositoryAotMetadataService(fileObserver, projectFinder, buildCmds);
441442
}
442443

443444
@Bean

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/JdtConfig.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
import org.springframework.context.annotation.Conditional;
1919
import org.springframework.context.annotation.Configuration;
2020
import org.springframework.ide.vscode.boot.index.SpringMetamodelIndex;
21+
import org.springframework.ide.vscode.boot.java.BuildCommandProvider;
22+
import org.springframework.ide.vscode.boot.java.DefaultBuildCommandProvider;
23+
import org.springframework.ide.vscode.boot.java.VSCodeBuildCommandProvider;
2124
import org.springframework.ide.vscode.boot.java.codeaction.JdtAstCodeActionProvider;
2225
import org.springframework.ide.vscode.boot.java.codeaction.JdtCodeActionHandler;
2326
import org.springframework.ide.vscode.boot.java.cron.CronExpressionsInlayHintsProvider;
@@ -228,4 +231,17 @@ public class JdtConfig {
228231
@Bean JdtCodeActionHandler jdtCodeActionHandler(CompilationUnitCache cuCache, Collection<JdtAstCodeActionProvider> providers) {
229232
return new JdtCodeActionHandler(cuCache, providers);
230233
}
234+
235+
@Bean BuildCommandProvider buildCommandProvider(SimpleLanguageServer server) {
236+
switch(LspClient.currentClient()) {
237+
case VSCODE:
238+
case THEIA:
239+
return new VSCodeBuildCommandProvider();
240+
case ECLIPSE:
241+
return new VSCodeBuildCommandProvider();
242+
default:
243+
return new DefaultBuildCommandProvider(server);
244+
}
245+
}
246+
231247
}

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/java/BootJavaLanguageServerComponents.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ protected BootJavaCodeLensEngine createCodeLensEngine(SpringMetamodelIndex sprin
327327
codeLensProvider.add(new WebfluxHandlerCodeLensProvider(springIndex));
328328
codeLensProvider.add(new CopilotCodeLensProvider(projectFinder, server, spelSemanticTokens));
329329
codeLensProvider.add(new RouterFunctionCodeLensProvider());
330-
codeLensProvider.add(new DataRepositoryAotMetadataCodeLensProvider(projectFinder, repositoryAotMetadataService, refactorings, config));
330+
codeLensProvider.add(new DataRepositoryAotMetadataCodeLensProvider(server, projectFinder, repositoryAotMetadataService, refactorings, config));
331331
codeLensProvider.add(new WebConfigCodeLensProvider(projectFinder, springIndex, config));
332332

333333
return new BootJavaCodeLensEngine(this, codeLensProvider);

0 commit comments

Comments
 (0)