2222import org .eclipse .core .runtime .CoreException ;
2323import org .eclipse .core .runtime .IStatus ;
2424import org .eclipse .core .runtime .Status ;
25- import org .eclipse .jdt .core .IClasspathAttribute ;
26- import org .eclipse .jdt .core .IClasspathEntry ;
2725import org .eclipse .jdt .core .IJavaElement ;
2826import org .eclipse .jdt .core .IJavaProject ;
2927import org .eclipse .jdt .core .search .IJavaSearchConstants ;
4038
4139public class ResolveClasspathsHandler {
4240 private static final Logger logger = Logger .getLogger (Configuration .LOGGER_NAME );
43- private static final String SCOPE_ATTRIBUTE = "maven.scope" ;
41+
4442
4543 /**
4644 * Resolves class path for a java project.
@@ -150,7 +148,8 @@ private static String[][] computeClassPath(String mainClass, String projectName)
150148 }
151149 project = projects .get (0 );
152150 }
153- return computeClassPath (project );
151+
152+ return computeClassPath (project , isMainClassInTestFolder (project , mainClass ));
154153 }
155154
156155 /**
@@ -162,31 +161,34 @@ private static String[][] computeClassPath(String mainClass, String projectName)
162161 * @throws CoreException
163162 * CoreException
164163 */
165- private static String [][] computeClassPath (IJavaProject javaProject ) throws CoreException {
164+ private static String [][] computeClassPath (IJavaProject javaProject , boolean includeTestScope )
165+ throws CoreException {
166166 if (javaProject == null ) {
167167 throw new IllegalArgumentException ("javaProject is null" );
168168 }
169169 String [][] result = new String [2 ][];
170170 if (JavaRuntime .isModularProject (javaProject )) {
171- result [0 ] = computeDefaultRuntimeClassPath (javaProject );
171+ result [0 ] = computeDefaultRuntimeClassPath (javaProject , includeTestScope );
172172 result [1 ] = new String [0 ];
173173 } else {
174174 result [0 ] = new String [0 ];
175- result [1 ] = computeDefaultRuntimeClassPath (javaProject );
175+ result [1 ] = computeDefaultRuntimeClassPath (javaProject , includeTestScope );
176176 }
177177 return result ;
178178 }
179179
180- private static String [] computeDefaultRuntimeClassPath (IJavaProject jproject ) throws CoreException {
180+ private static String [] computeDefaultRuntimeClassPath (IJavaProject jproject , boolean includeTestScope )
181+ throws CoreException {
181182 IRuntimeClasspathEntry [] unresolved = JavaRuntime .computeUnresolvedRuntimeClasspath (jproject );
182183 Set <String > resolved = new LinkedHashSet <String >();
183184 for (int i = 0 ; i < unresolved .length ; i ++) {
184185 IRuntimeClasspathEntry entry = unresolved [i ];
185186 if (entry .getClasspathProperty () == IRuntimeClasspathEntry .USER_CLASSES ) {
186- IRuntimeClasspathEntry [] entries = JavaRuntime .resolveRuntimeClasspathEntry (entry , jproject , true );
187+ IRuntimeClasspathEntry [] entries = JavaRuntime .resolveRuntimeClasspathEntry (entry , jproject ,
188+ !includeTestScope );
187189 for (int j = 0 ; j < entries .length ; j ++) {
188190
189- if (entries [ j ]. getClasspathEntry (). isTest () && ! isRuntime (entries [j ].getClasspathEntry ())) {
191+ if (! includeTestScope && JdtUtils . isTest (entries [j ].getClasspathEntry ())) {
190192 continue ;
191193 }
192194 String location = entries [j ].getLocation ();
@@ -200,10 +202,43 @@ private static String[] computeDefaultRuntimeClassPath(IJavaProject jproject) th
200202 return resolved .toArray (new String [resolved .size ()]);
201203 }
202204
203- private static boolean isRuntime (final IClasspathEntry classpathEntry ) {
204- for (IClasspathAttribute attribute : classpathEntry .getExtraAttributes ()) {
205- if (SCOPE_ATTRIBUTE .equals (attribute .getName ()) && "runtime" .equals (attribute .getValue ())) {
206- return true ;
205+
206+ /**
207+ * Test whether the main class is located in test folders.
208+ * @param project the java project containing the main class
209+ * @param mainClass the main class name
210+ * @return whether the main class is located in test folders
211+ */
212+ private static boolean isMainClassInTestFolder (IJavaProject project , String mainClass ) {
213+ // get a list of test folders and check whether main class is here
214+ int constraints = IJavaSearchScope .SOURCES ;
215+ IJavaElement [] testFolders = JdtUtils .getTestPackageFragmentRoots (project );
216+ if (testFolders .length > 0 ) {
217+ try {
218+
219+ List <Object > mainClassesInTestFolder = new ArrayList <>();
220+ SearchPattern pattern = SearchPattern .createPattern (mainClass , IJavaSearchConstants .CLASS ,
221+ IJavaSearchConstants .DECLARATIONS ,
222+ SearchPattern .R_CASE_SENSITIVE | SearchPattern .R_EXACT_MATCH );
223+ SearchEngine searchEngine = new SearchEngine ();
224+ IJavaSearchScope scope = SearchEngine .createJavaSearchScope (testFolders , constraints );
225+ SearchRequestor requestor = new SearchRequestor () {
226+ @ Override
227+ public void acceptSearchMatch (SearchMatch match ) {
228+ Object element = match .getElement ();
229+ if (element instanceof IJavaElement ) {
230+ mainClassesInTestFolder .add (element );
231+ }
232+ }
233+ };
234+
235+ searchEngine .search (pattern , new SearchParticipant [] {
236+ SearchEngine .getDefaultSearchParticipant ()
237+ }, scope , requestor , null /* progress monitor */ );
238+
239+ return !mainClassesInTestFolder .isEmpty ();
240+ } catch (Exception e ) {
241+ logger .log (Level .SEVERE , String .format ("Searching the main class failure: %s" , e .toString ()), e );
207242 }
208243 }
209244 return false ;
0 commit comments