Clemens Ballarin wrote:
> Static instrumentation is done as follows:
>
> java -jar jcov.jar instr -verbose -t <template> -i <pattern> -o <output> <input1> <input2> ...
>
> While this works for Java 8, with Java 11 I get error messages like this:
>
> [ERROR] Failed to read class: gnu/trove/map/hash/TIntLongHashMap. Reason: Can't read class gnu/trove/map/hash/TIntLongHashMap from classloader jdk.internal.loader.ClassLoaders$AppClassLoader@55054057
> [ERROR] SCHWERWIEGEND: Error instrumenting archive entry 'xxx.class' in 'yyy.jar' - skipped
> [ERROR] Exception details: Can't read superclass bytecode. Please add it to the classpath.
>
> It looks like for Java 8 all inputs are added to the system classpath via com.sun.tdk.jcov.Utils.addToClasspath(String[]):
>
> public static void addToClasspath(String[] path) {
> if (ClassLoader.getSystemClassLoader() instanceof URLClassLoader) {
> URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
> Class sysclass = URLClassLoader.class;
>
> try {
> Method method = sysclass.getDeclaredMethod("addURL", new Class[]{URL.class});
> method.setAccessible(true);
>
> URL[] urls = new URL[path.length];
> for (int i = 0; i < path.length; i++) {
> urls[i] = new File(path[i]).toURI().toURL();
> method.invoke(sysloader, new Object[]{urls[i]});
> }
> } catch (Throwable t) {
> t.printStackTrace();
> }
> }
> }
>
> But this doesn't work for Java 11 since jdk.internal.loader.ClassLoaders.AppClassLoader is not an instance of URLClassLoader. (jcov commit 4fd8b8e)
> Static instrumentation is done as follows:
>
> java -jar jcov.jar instr -verbose -t <template> -i <pattern> -o <output> <input1> <input2> ...
>
> While this works for Java 8, with Java 11 I get error messages like this:
>
> [ERROR] Failed to read class: gnu/trove/map/hash/TIntLongHashMap. Reason: Can't read class gnu/trove/map/hash/TIntLongHashMap from classloader jdk.internal.loader.ClassLoaders$AppClassLoader@55054057
> [ERROR] SCHWERWIEGEND: Error instrumenting archive entry 'xxx.class' in 'yyy.jar' - skipped
> [ERROR] Exception details: Can't read superclass bytecode. Please add it to the classpath.
>
> It looks like for Java 8 all inputs are added to the system classpath via com.sun.tdk.jcov.Utils.addToClasspath(String[]):
>
> public static void addToClasspath(String[] path) {
> if (ClassLoader.getSystemClassLoader() instanceof URLClassLoader) {
> URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
> Class sysclass = URLClassLoader.class;
>
> try {
> Method method = sysclass.getDeclaredMethod("addURL", new Class[]{URL.class});
> method.setAccessible(true);
>
> URL[] urls = new URL[path.length];
> for (int i = 0; i < path.length; i++) {
> urls[i] = new File(path[i]).toURI().toURL();
> method.invoke(sysloader, new Object[]{urls[i]});
> }
> } catch (Throwable t) {
> t.printStackTrace();
> }
> }
> }
>
> But this doesn't work for Java 11 since jdk.internal.loader.ClassLoaders.AppClassLoader is not an instance of URLClassLoader. (jcov commit 4fd8b8e)