2016-08-24 44 views
1

錯誤而下面的代碼執行,爪哇郎IllegalAccess經由HashBasedTable累加器收集番石榴不可變表

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

ImmutableTable.copyOf(listItemsToProcess.parallelStream() 
        .map(item -> 
          ProcessorInstanceProvider.getInstance() 
          .buildImmutableTable(item)) 
        .collect(() -> HashBasedTable.create(), 
          HashBasedTable::putAll, 

          HashBasedTable<Integer, String,  
          Boolean>::putAll) 
        ); 

Error in coming on - HashBasedTable::putAll Using Oracle's 1.8 jre

+0

它指向哪條線? – shmosel

+0

On HashBasedTable :: putAll, – sidss

+2

[Java 8採集器的Guava ImmutableTable使用HashBaseTable作爲累加器給出IllegalAccessError]的可能副本(http://stackoverflow.com/questions/39095205/java-8-collector-for-guava-immutabletable- using-hashbasedtable-as-accumulator-gi) – Xaerxess

回答

0

有趣的是,我用Lambda表達式替換了方法引用,並且它工作正常。

ImmutableTable.copyOf(itemList.parallelStream() 
        .map(item -> 
          ProcessorInstanceProvider.get() 
          .buildImmutableTable(item)) 
        .collect(() -> HashBasedTable.create(), 
          (a, b) -> a.putAll(b), 
          (a, b) -> a.putAll(b)) 
        ); 
+2

該修復可能與[this](http://stackoverflow.com/questions/36100552/illegalaccesserror-when-using-a-public-method-reference-of-a -package-private-cla),但是你的罐子可能仍然不同步。另外,如果您不想被禁止,請不要重複發佈相同的問題。 – shmosel

1

AbstractTable在番石榴版本15.引入看一看類路徑配置;您可能在運行時使用較早的庫版本。

5

這是編譯器故障,相關的報告是

  • JDK-8152643「的Javac編譯方法的參考,其允許導致一個IllegalAccessError」
  • JDK-8059632:「方法參考彙編使用不正確的合格的類型」

請注意,第一次報告的狀態爲「Fixed in 8u102」,所以下載JDK8u102可以解決這個問題。當然,當使用javac以外的編譯器時,例如ECJ,你必須確保該編譯器是最新的。

無論哪種情況,您都必須重新編譯源代碼,因爲這是編譯器問題。但是,編譯後的代碼甚至應該可以與舊的JRE一起工作。


爲了解釋這一問題,通常,調用應該編碼成使用接收器的編譯時間類型(或在static方法情況下,顯式類型)的字節代碼,而不管該聲明類型的實際的方法實現。所以,如果你有一個publicABpublic類繼承的public方法fooA.foo調用應該被編碼爲A.foo,而不是B.foo。對於普通的調用,編譯器以這種方式工作,但對於方法引用,javac(和afaik也是舊版本的ECJ)未能正確執行。所以當遇到一個班級直接嘗試訪問B.foo而沒有訪問到B時,會拋出一個IllegalAccessError

它在使用lambda表達式的時候起作用,因爲在那個時候,調用被編譯到一個普通的調用指令中,編譯器可以正常工作,在合成方法中,並且在構建一個實例時使用對該合成方法的引用在運行時的功能接口。由於合成方法在同一班級內進行,所以始終可以訪問。