diff --git a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveClasspathsHandler.java b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveClasspathsHandler.java index be37285e3..5e7017128 100644 --- a/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveClasspathsHandler.java +++ b/com.microsoft.java.debug.plugin/src/main/java/com/microsoft/java/debug/plugin/internal/ResolveClasspathsHandler.java @@ -70,6 +70,9 @@ public class ResolveClasspathsHandler { */ public String[][] resolveClasspaths(List arguments) throws Exception { try { + if (arguments.size() == 3) { + return computeClassPath((String) arguments.get(0), (String) arguments.get(1), (String) arguments.get(2)); + } return computeClassPath((String) arguments.get(0), (String) arguments.get(1)); } catch (CoreException e) { logger.log(Level.SEVERE, "Failed to resolve classpath: " + e.getMessage(), e); @@ -159,6 +162,23 @@ public void acceptSearchMatch(SearchMatch match) { * CoreException */ private static String[][] computeClassPath(String mainClass, String projectName) throws CoreException { + return computeClassPath(mainClass, projectName, null); + } + + /** + * Accord to the project name and the main class, compute runtime classpath. + * + * @param mainClass + * fully qualified class name + * @param projectName + * project name + * @param scope + * scope of the classpath + * @return class path + * @throws CoreException + * CoreException + */ + private static String[][] computeClassPath(String mainClass, String projectName, String scope) throws CoreException { IJavaProject project = null; // if type exists in multiple projects, debug configuration need provide // project name. @@ -179,6 +199,12 @@ private static String[][] computeClassPath(String mainClass, String projectName) project = projects.get(0); } + if ("test".equals(scope)) { + return computeClassPath(project, mainClass, false /*excludeTestCode*/, Collections.EMPTY_LIST); + } else if ("runtime".equals(scope)) { + return computeClassPath(project, mainClass, true /*excludeTestCode*/, Collections.EMPTY_LIST); + } + IJavaElement testElement = findMainClassInTestFolders(project, mainClass); List mappedResources = (testElement != null && testElement.getResource() != null) ? Arrays.asList(testElement.getResource()) : Collections.EMPTY_LIST; @@ -275,7 +301,7 @@ public void acceptSearchMatch(SearchMatch match) { private static class JavaApplicationLaunchConfiguration extends LaunchConfiguration { public static final String JAVA_APPLICATION_LAUNCH = "\n" - + "\n" + + "\n" + "\n" + "\n" + "\n" @@ -302,7 +328,18 @@ protected JavaApplicationLaunchConfiguration(IProject project, String mainType, } else if (ProjectUtils.isGradleProject(project)) { classpathProvider = "org.eclipse.buildship.core.classpathprovider"; } - this.launchInfo = new JavaLaunchConfigurationInfo(JAVA_APPLICATION_LAUNCH); + + // Since MavenRuntimeClasspathProvider will only including test entries when: + // 1. Launch configuration is JUnit/TestNG type + // 2. Mapped resource is in test path. + // That's why we use JUnit launch configuration here to make sure the result is right when excludeTestCode is false. + String launchXml = null; + if (!excludeTestCode && mappedResources.isEmpty()) { + launchXml = String.format(JAVA_APPLICATION_LAUNCH, "org.eclipse.jdt.junit.launchconfig"); + } else { + launchXml = String.format(JAVA_APPLICATION_LAUNCH, "org.eclipse.jdt.launching.localJavaApplication"); + } + this.launchInfo = new JavaLaunchConfigurationInfo(launchXml); } @Override