Instr fails to add instrumenation arguments to classpath for Java 11 causing instrumentation failures

leonid.kuskov at oracle.com leonid.kuskov at oracle.com
Sat Oct 10 00:07:43 UTC 2020


Hi Clemens,

Yes, this is a latent defect that will be fixed (*). Unfortunately, some 
parts of the old code are not yet adapted to Java 9,11.
Since using Java 11 with jcov does not improve the quality of the 
instrumented code there are no needs to use versions higher than 8. The 
result will be the same.
Please just use Java 8 or merge <inputs> that depend on each other into 
one <input>

Thanks,
Leonid

*)CODETOOLS-7902783 
<https://bugs.openjdk.java.net/browse/CODETOOLS-7902783> Static 
instrumentation fails with Java 11 and above if multiple inputs are used

On 10/9/20 2:48 AM, 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 at 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)
>
> Is there a recommended workaround?
>
> Clemens
>
>


More information about the jcov-dev mailing list