When I run a test that uses org.eclipse.equinox.common 3.6 with Java 6 in Eclipse Neon, I sometimes get the following error:
java.lang.UnsupportedClassVersionError: org/eclipse/core/runtime/IAdapterManager : Unsupported major.minor version 51.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
...
It seems that the test runner loads two different versions of org.eclipse.equinox.common. When I inspect the process properties in the debug view, I see (among others) the classpath entries
C:\workspace\.metadata\.plugins\org.eclipse.pde.core\.bundle_pool\plugins\org.eclipse.equinox.common_3.8.0.v20160509-1230.jar
C:\Users\me\.m2\repository\org\eclipse\org.eclipse.equinox.common\3.6.0.v20110523\org.eclipse.equinox.common-3.6.0.v20110523.jar
Version 3.8 requires Java 7, so I'd like to force the test to choose version 3.6. How can I achieve this?
I found an evil classloader hack that solves the problem, based on this answer:
@BeforeClass
public static void setUpClass() throws Exception {
removeJarFromClasspath("org.eclipse.equinox.common_3.8");
}
public static void removeJarFromClasspath(String namePart) throws Exception {
URLClassLoader urlClassLoader = (URLClassLoader)ClassLoader.getSystemClassLoader();
Field ucpField = URLClassLoader.class.getDeclaredField("ucp");
ucpField.setAccessible(true);
URLClassPath ucp = (URLClassPath)ucpField.get(urlClassLoader);
Field pathField = URLClassPath.class.getDeclaredField("path");
pathField.setAccessible(true);
List path = (List)pathField.get(ucp);
Field loadersField = URLClassPath.class.getDeclaredField("loaders");
loadersField.setAccessible(true);
List loaders = (List)loadersField.get(ucp);
Field lmapField = URLClassPath.class.getDeclaredField("lmap");
lmapField.setAccessible(true);
Map lmap = (Map)lmapField.get(ucp);
int index = 0;
for (Object entry : path) {
String url = entry.toString();
if (url.contains(namePart)) {
path.remove(index);
loaders.remove(index);
lmap.remove(url.replaceFirst("file:/", "file:///"));
break;
}
index++;
}
}