Java lang IllegalAccess on collecting Guava Immutable Table via HashBasedTable accumulator

后端 未结 3 703
轮回少年
轮回少年 2020-12-04 01:18

Error while executing below code,

Caused by: java.lang.IllegalAccessError: tried to access class com.google.common.collect.AbstractTable from class

相关标签:
3条回答
  • 2020-12-04 01:40

    This is a compiler bug, related reports are

    • JDK-8152643: “Javac compiles method reference that allows results in an IllegalAccessError”
    • JDK-8059632: “Method reference compilation uses incorrect qualifying type”

    Note that the first report has the status “Fixed in 8u102”, so downloading JDK8u102 could solve the issue. Of course, when using a compiler other than javac, e.g. ECJ, you have to ensure that that compiler is up to date as well.

    In either case, you have to recompile the source code, as it is a compiler issue. But then, the compiled code should even work with older JREs.


    To explain the issue, normally, invocations should be encoded into the byte code using the compile-time type of the receiver (or the explicit type in case of static methods), regardless of the declaring type of the actual method implementation. So if you have a public class A inheriting the public method foo from the non-public class B, an invocation of A.foo should be encoded as A.foo rather than B.foo. For ordinary invocations, the compilers work that way, but for method references, javac (and afaik also older versions of ECJ) failed to do that correctly. So when encountering a class trying to access B.foo directly without having access to B, an IllegalAccessError is thrown.

    It works when using a lambda expression instead, as then, the invocation is compiled into an ordinary invocation instruction, for which the compiler works correctly, within a synthetic method and a reference to that synthetic method is used when constructing an instance of the functional interface at runtime. Since the synthetic method recides within the same class, it’s always accessible.

    0 讨论(0)
  • 2020-12-04 01:42

    AbstractTable was introduced in Guava version 15. Take a look at your classpath configuration; you're probably using an earlier library version at runtime.

    0 讨论(0)
  • 2020-12-04 01:56

    Interesting, i replaced method references with Lambda expression and it worked.

        ImmutableTable.copyOf(itemList.parallelStream()
                        .map(item ->
                                ProcessorInstanceProvider.get()
                                .buildImmutableTable(item))
                        .collect(() -> HashBasedTable.create(),
                                (a, b) -> a.putAll(b),
                                (a, b) -> a.putAll(b))
                        );
    
    0 讨论(0)
提交回复
热议问题