Skip to content

Commit

Permalink
Fix test failure on Java 9 and above
Browse files Browse the repository at this point in the history
Java 9 modified classloading to use modules, so the default classloader presented by JUnit is not a `URLClassloader` and therefore fails the type check in `ElevatedClassLoaderFactory`. As Sonarqube always creates a classloader for each plugin during the load of that plugin, the exposing of the default App Classloader in the unit test is therefore invalid, so switching to create a custom `URLClassloader` overcomes this. Similarly, Mockito throws an exception when running in Java 9 and above on Windows due to classes eing generated in the wrong module scope. Upgrading to the latest version of Mockito overcomes this.
  • Loading branch information
mc1arke committed Oct 15, 2019
1 parent 3eba672 commit e1e16dd
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 14 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ dependencies {
compileOnly fileTree(dir: sonarLibraries, include: '**/*.jar')
testCompile fileTree(dir: sonarLibraries, include: '**/*.jar')
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.24.0'
testCompile group: 'org.mockito', name: 'mockito-core', version: '3.1.0'
zip "sonarqube:sonarqube:${sonarqubeVersion}@zip"
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertEquals;
Expand All @@ -43,6 +47,7 @@
*/
public class ClassReferenceElevatedClassLoaderFactoryTest {

private static final String SVN_PLUGIN_CLASS = "org.sonar.plugins.scm.svn.SvnPlugin";
private final ExpectedException expectedException = ExpectedException.none();

@Rule
Expand All @@ -62,17 +67,15 @@ public void testExceptionOnNoSuchClass() {
}

@Test
public void testClassloaderReturnedOnHappyPath() {
ClassReferenceElevatedClassLoaderFactory testCase =
spy(new ClassReferenceElevatedClassLoaderFactory(getClass().getName()));
testCase.createClassLoader(((Plugin) context -> {
}).getClass());
public void testClassloaderReturnedOnHappyPath() throws ReflectiveOperationException, MalformedURLException {
URLClassLoader mockClassLoader = new URLClassLoader(findSonarqubePluginJars());
ElevatedClassLoaderFactory testCase = spy(new ClassReferenceElevatedClassLoaderFactory(getClass().getName()));
testCase.createClassLoader((Class<? extends Plugin>) mockClassLoader.loadClass(SVN_PLUGIN_CLASS));

ArgumentCaptor<ClassLoader> argumentCaptor = ArgumentCaptor.forClass(ClassLoader.class);
verify(testCase).createClassLoader(argumentCaptor.capture(), argumentCaptor.capture());

assertEquals(Arrays.asList(getClass().getClassLoader(), getClass().getClassLoader()),
argumentCaptor.getAllValues());
assertEquals(Arrays.asList(mockClassLoader, getClass().getClassLoader()), argumentCaptor.getAllValues());
}

@Test
Expand All @@ -85,17 +88,14 @@ public void testLoadClass() throws ClassNotFoundException, MalformedURLException
builder.setParent("_customPlugin", "_api_", new Mask());
builder.setLoadingOrder("_customPlugin", ClassloaderBuilder.LoadingOrder.SELF_FIRST);

File[] sonarQubeDistributions = new File("sonarqube-lib/").listFiles();

for (File pluginJar : new File(sonarQubeDistributions[0], "extensions/plugins/").listFiles()) {
builder.addURL("_customPlugin", pluginJar.toURI().toURL());
for (URL pluginUrl : findSonarqubePluginJars()) {
builder.addURL("_customPlugin", pluginUrl);
}

Map<String, ClassLoader> loaders = builder.build();
ClassLoader classLoader = loaders.get("_customPlugin");

Class<? extends Plugin> loadedClass =
(Class<? extends Plugin>) classLoader.loadClass("org.sonar.plugins.scm.svn.SvnPlugin");
Class<? extends Plugin> loadedClass = (Class<? extends Plugin>) classLoader.loadClass(SVN_PLUGIN_CLASS);

ClassReferenceElevatedClassLoaderFactory testCase =
new ClassReferenceElevatedClassLoaderFactory(ActiveRule.class.getName());
Expand All @@ -105,4 +105,14 @@ public void testLoadClass() throws ClassNotFoundException, MalformedURLException
assertNotSame(elevatedLoader, elevatedClass.getClassLoader());
}

private static URL[] findSonarqubePluginJars() throws MalformedURLException {
List<URL> pluginUrls = new ArrayList<>();
File[] sonarQubeDistributions = new File("sonarqube-lib/").listFiles();

for (File pluginJar : new File(sonarQubeDistributions[0], "extensions/plugins/").listFiles()) {
pluginUrls.add(pluginJar.toURI().toURL());
}
return pluginUrls.toArray(new URL[0]);
}

}

0 comments on commit e1e16dd

Please sign in to comment.