diff --git a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/runner/classpath/ModifiedClassPathRunner.java b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/runner/classpath/ModifiedClassPathRunner.java index d18141734e..a9937548c2 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/runner/classpath/ModifiedClassPathRunner.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-test-support/src/main/java/org/springframework/boot/testsupport/runner/classpath/ModifiedClassPathRunner.java @@ -28,6 +28,7 @@ import java.util.Collections; import java.util.List; import java.util.jar.Attributes; import java.util.jar.JarFile; +import java.util.regex.Pattern; import java.util.stream.Stream; import org.apache.maven.repository.internal.MavenRepositorySystemUtils; @@ -66,6 +67,9 @@ import org.springframework.util.StringUtils; */ public class ModifiedClassPathRunner extends BlockJUnit4ClassRunner { + private static final Pattern INTELLIJ_CLASSPATH_JAR_PATTERN = Pattern.compile( + ".*classpath(\\d+)?.jar"); + public ModifiedClassPathRunner(Class testClass) throws InitializationError { super(testClass); } @@ -98,7 +102,7 @@ public class ModifiedClassPathRunner extends BlockJUnit4ClassRunner { private URL[] extractUrls(ClassLoader classLoader) throws Exception { List extractedUrls = new ArrayList<>(); doExtractUrls(classLoader).forEach((URL url) -> { - if (isSurefireBooterJar(url)) { + if (isManifestOnlyJar(url)) { extractedUrls.addAll(extractUrlsFromManifestClassPath(url)); } else { @@ -125,10 +129,30 @@ public class ModifiedClassPathRunner extends BlockJUnit4ClassRunner { } } + private boolean isManifestOnlyJar(URL url) { + return isSurefireBooterJar(url) || isShortenedIntelliJJar(url); + } + private boolean isSurefireBooterJar(URL url) { return url.getPath().contains("surefirebooter"); } + private boolean isShortenedIntelliJJar(URL url) { + String urlPath = url.getPath(); + boolean isCandidate = INTELLIJ_CLASSPATH_JAR_PATTERN.matcher(urlPath).matches(); + if (isCandidate) { + try { + Attributes attributes = getManifestMainAttributesFromUrl(url); + String createdBy = attributes.getValue("Created-By"); + return createdBy != null && createdBy.contains("IntelliJ"); + } + catch (Exception ex) { + return false; + } + } + return false; + } + private List extractUrlsFromManifestClassPath(URL booterJar) { List urls = new ArrayList<>(); try { @@ -143,9 +167,14 @@ public class ModifiedClassPathRunner extends BlockJUnit4ClassRunner { } private String[] getClassPath(URL booterJar) throws Exception { - try (JarFile jarFile = new JarFile(new File(booterJar.toURI()))) { - return StringUtils.delimitedListToStringArray(jarFile.getManifest() - .getMainAttributes().getValue(Attributes.Name.CLASS_PATH), " "); + Attributes attributes = getManifestMainAttributesFromUrl(booterJar); + return StringUtils.delimitedListToStringArray(attributes + .getValue(Attributes.Name.CLASS_PATH), " "); + } + + private Attributes getManifestMainAttributesFromUrl(URL url) throws Exception { + try (JarFile jarFile = new JarFile(new File(url.toURI()))) { + return jarFile.getManifest().getMainAttributes(); } }