2016-05-23 117 views
5

我不知道如何啓動它。我有一個荒謬的NullPointerException在一個不應該的地方。由於情況看起來很不正常,我不期待太多答案,但問題和答案(如果我終於找到答案)可能對教育目的有用。如果不會,我可能會刪除該問題。訪問final字段時出現奇怪的NullPointerException

Caused by: java.lang.NullPointerException 
     at com.ah.dao.hbase.Snapshotable.lock(Snapshotable.java:17) 
     at com.ah.pipeline.dump.DumpController.dump(DumpController.java:78) 

07: public abstract class Snapshotable { 
08: private final AtomicBoolean readonly = new AtomicBoolean(false); 
09: 
10: abstract public TableSuit getTableInfo(); 
11: 
12: public boolean locked() { 
13:  return readonly.get(); 
14: } 
15: 
16: public final void lock() { 
17:  readonly.set(true); <-- happens here 
18: } 
19: 
20: public final void release() { 
21:  readonly.set(false); 
22: } 
23: } 

起初readonly變量是不是最終的,所以我雖然它可能是不安全的出版效果,但現在我沒有任何想法。在我們的代碼中沒有這些變量的反射技巧,但是這個類的後代的一些方法是用aspectj代理的。


更新AOP的細節

@Service 
public class HDao extends Snapshotable { 

    @PerformanceMonitoring 
    public void save(PatchEvent patchEvent) { 
     if (locked()) { 
      throw new DumpException(tableName); 
     } 

@Aspect 
@Component 
public class PMAdvice { 

    @Around(value = "@annotation(performanceMonitoring)", argNames = "jp, p") 
    public Object saveEvent(ProceedingJoinPoint jp, PerformanceMonitoring p) throws Throwable { 
     // basic stuff 
+0

根據您發佈的代碼中缺少某些內容的假設,當我收到此類NullPointerException時,通常會查找自動拆箱空值。 – EasterBunnyBugSmasher

+1

_ **但這個類的後代的一些方法是用aspectj ** _代表的,它都在某處。沒有它就說不清。 –

+0

你可以嘗試看看反編譯方面的類(我認爲https://eclipse.org/aspectj/doc/released/pdguide/ltwdump.html#ltwdump-假設你使用ltw。運行時代理應該出現在stacktrace,也抱怨最終的方法) – zapl

回答

1

我可以重現的小程序。這個問題確實與AOP有關。在調試的幫助下,我發現最終的方法不適用於AspectJ代理。

原來,AspectJ中的代理是通過運行時子類來完成的。所以它創建一個包裝器子類,它將所有方法委託給代理對象。 它適用於非最終方法。

簡化的例子:

class WrapperProxy extends MyClass { 
    private MyClass delegate = new MyClass(); 

    @Override 
    public void run() { 
     delegate.run(); 
    } 
} 

該技術具有與最終的方法中的問題,因爲它們不能在子類中重寫。 AspectJ以一種奇怪的方式處理它:它創建另一個MyClass的委託實例,並將所有最終的方法調用重定向到它。這個代表甚至沒有初始化,在我的情況下它沒有最終字段。

要解決我的特定問題,我只是從方法中刪除了最後一個關鍵字。

+0

讓我希望更快速。如果AspectJ試圖用最終方法來繼承一個類,我會很感激一個錯誤。 – EasterBunnyBugSmasher

+0

@EasterBunnyBugSmasher技術上在啓動時有警告。問題是它在春季3中運行良好,在春季4中運行中斷 – AdamSkywalker