我們有一個桌面Swing應用程序和Google Guice 4.1.0依賴注入。在開發過程中一切正常,但當同事嘗試運行應用程序時發生了一些奇怪的事情。Guice無法實例化擴展JPanel的類 - NPE調用超級構造函數
我們有一個MainWindow
類延伸JPanel
。在構造函數中,這個類需要一些本身是可注入的控制器。在主要方法Guice注射器創建。然後噴油器試圖實例化MainWindow
(injector.getInstance(MainWindow.class)
)。它失敗了NullPointerException
!
這不會發生在我的電腦上,我們使用相同的JDK。
下面是MainWindow
類剝離下來到有問題的代碼(注意:這不會重現該問題,不幸):
class MainWindow extends JPanel {
private final Foo foo;
private final JFrame frame;
@Inject
public MainWindow(Foo foo) {
super(new GridBagLayout()); // <-- NullPointerException
this.foo = foo;
this.frame = new JFrame("title");
}
public void createAndShowGUI() {
// ...
frame.add(this);
frame.pack();
frame.setVisible(true);
}
}
這裏是main()
方法:
class Main {
private static final Injector injector = Guice.createInjector();
public static void main(String[] args) {
MainWindow mainWindow = injector.getInstance(MainWindow.class);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
mainWindow.createAndShowGUI();
}
});
}
}
下面是堆棧跟蹤的例外情況:
com.google.inject.ProvisionException: Unable to provision, see the following errors:
1) Error injecting constructor, java.lang.NullPointerException
at app.gui.MainWindow.<init>(MainWindow.java:133)
while locating app.gui.MainWindow
1 error
at com.google.inject.internal.InjectorImpl$2.get(InjectorImpl.java:1028) ~[app-1.0-SNAPSHOT.jar:?]
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1054) ~[app-1.0-SNAPSHOT.jar:?]
at app.Main.createAndShowGUI(Main.java:40) ~[app-1.0-SNAPSHOT.jar:?]
at app.Main.access$000(Main.java:26) ~[app-1.0-SNAPSHOT.jar:?]
at app.Main$2.run(Main.java:67) ~[app-1.0-SNAPSHOT.jar:?]
NPE被引入了最令人驚訝的地方 - 在調用MainWindow
的超類構造函數(這是133行)。我開始挖掘,發現,手動創建MainWindow
並注入其依賴正常工作:
MainWindow mainWindow = new MainWindow(injector.getInstance(Foo.class));
我懷疑,也許類加載器不能正常工作,所以我既MainWindow
和JPanel
的日誌記錄的類加載器再次嘗試:
System.out.println("MainWindow: " + MainWindow.class.getClassLoader());
System.out.println("JPanel: " + JPanel.class.getClassLoader());
MainWindow mainWindow = injector.getInstance(MainWindow.class);
類加載器是不同的(JPanel
通過引導加載),但現在的噴射工作正常。我想這是因爲現在JPanel
類被顯式加載到main方法上下文中。
所以我的問題是:
- 沒有人有類似的問題?
- 這是我的錯,還是它的一個錯誤?
- 如果這是一個bug,它發生在Guice嗎?或者也許JRE?
更多關於Java和操作系統的詳細信息:
- 我最初JDK 1.8.0u111開發的,但後來改JDK 1.8.0u121。
- 應用程序被編譯爲Java 6.
- 在我的電腦上運行完美的Windows 10版本1607(操作系統版本14393.693),在JRE 6和JRE 8(來自JDK)。
NullPointerException
是在同事的電腦上用Windows 10,1511(OS Build 10586.753),JDK 1.8.0u112和1.8.0u121提出的。
不幸的是,我無法提供重現問題的最小版本。哎呀,我甚至不能重現問題,它只發生在同事的環境中。
你看過Guice配置文件嗎?你和同事之間有什麼分別嗎? –
@ M.Prokhorov沒有區別。項目是從Maven構建的,不需要添加額外的配置。更何況,這是一個運行時失敗,而不是編譯。完全相同的JAR適用於我的電腦,但不適用於他。不管它是由我還是他編譯的都沒關係。 – Archie
那麼,如果類加載器不同,那麼它肯定是一個運行時問題。這兩臺機器都有不同的類加載器,由該日誌語句報告?噴射器被調用時是否有任何打印? –