NullPointerException
SWT から Excel を開こうとするとエラーが発生します。残念ながら、私が働いている会社への参照が含まれているため、完全なスタック トレースとコードの一部を投稿することはできません。うまくいけば、誰かが以前にこの問題に遭遇し、それを認識するかもしれません.
ここに投稿できるスタックトレースの一部があります
java.lang.NullPointerException
at org.eclipse.swt.ole.win32.OleControlSite.disconnectEventSinks(OleControlSite.java:468)
at org.eclipse.swt.ole.win32.OleControlSite.releaseObjectInterfaces(OleControlSite.java:774)
at org.eclipse.swt.ole.win32.OleClientSite.onDispose(OleClientSite.java:909)
at org.eclipse.swt.ole.win32.OleClientSite.access$1(OleClientSite.java:895)
at org.eclipse.swt.ole.win32.OleClientSite$1.handleEvent(OleClientSite.java:129)
これがコードです。新しい OleControlSite がインスタンス化されると、例外がスローされるのは最後の行です。
OleFrame frame1 = new OleFrame(shell, SWT.NONE);
if (clientSite != null && !clientSite.isDisposed()){
clientSite.dispose();
clientSite = null;
}
OleAutomation doc;
try{
clientSite = new OleControlSite(frame1, SWT.NONE, file);
このコードは Windows XP では機能しますが、Windows 7 では機能しませんNullPointerException
。
立方体の提案に従って、ここに自己完結型の例を作成しました。コードは次のとおりです。
package com.test;
import java.io.File;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.ole.win32.OLE;
import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.OleControlSite;
import org.eclipse.swt.ole.win32.OleEvent;
import org.eclipse.swt.ole.win32.OleFrame;
import org.eclipse.swt.ole.win32.OleListener;
import org.eclipse.swt.ole.win32.Variant;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Button;
public class OpenExcelExampleWindow extends Shell {
public final static int WorkbookBeforeClose = 0x00000622;
/**
* Launch the application.
* @param args
*/
public static void main(String args[]) {
try {
Display display = Display.getDefault();
OpenExcelExampleWindow shell = new OpenExcelExampleWindow(display);
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Create the shell.
* @param display
*/
public OpenExcelExampleWindow(Display display) {
super(display, SWT.SHELL_TRIM);
Button btnOpenExcel = new Button(this, SWT.NONE);
btnOpenExcel.setBounds(10, 10, 68, 23);
btnOpenExcel.setText("open excel");
btnOpenExcel.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
onOpenExcelClicked();
}
});
createContents();
}
protected void onOpenExcelClicked() {
openExcel("testfile.xls",this);
}
/**
* Create contents of the shell.
*/
protected void createContents() {
setText("SWT Application");
setSize(450, 300);
}
@Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
protected void openExcel(String fileName, Shell shell){
OleControlSite clientSite = null;
final File file = new File(fileName);
if (file.exists()) {
OleFrame frame1 = new OleFrame(shell, SWT.NONE);
if (clientSite != null && !clientSite.isDisposed()){
clientSite.dispose();
clientSite = null;
}
clientSite = new OleControlSite(frame1, SWT.NONE, file);
OleAutomation doc = new OleAutomation(clientSite);
int [] dispInfo = doc.getIDsOfNames(new String[] {"Application"});
Variant variant = doc.getProperty(dispInfo[0]);
OleAutomation app = variant.getAutomation();
variant.dispose();
doc.dispose();
doc = null;
int result = clientSite.doVerb(OLE.OLEIVERB_OPEN);
if (result != OLE.S_OK){
OLE.error(OLE.ERROR_CANNOT_OPEN_FILE, result);
}
//When user close workbook, dispose the clientSite.
clientSite.addEventListener(app, "{00024413-0000-0000-C000-000000000046}",
WorkbookBeforeClose,new OleListener() {
public void handleEvent(OleEvent event) {
OleControlSite oldControlSite = (OleControlSite)event.widget;
if ( !oldControlSite.isDisposed()){
//System.out.println("event in WorkbookBeforeClose");
oldControlSite.dispose();
}
}
});
}
}
}
そしてここに例外があります
java.lang.NullPointerException
at org.eclipse.swt.ole.win32.OleControlSite.disconnectEventSinks(OleControlSite.java:468)
at org.eclipse.swt.ole.win32.OleControlSite.releaseObjectInterfaces(OleControlSite.java:774)
at org.eclipse.swt.ole.win32.OleClientSite.onDispose(OleClientSite.java:909)
at org.eclipse.swt.ole.win32.OleClientSite.access$1(OleClientSite.java:895)
at org.eclipse.swt.ole.win32.OleClientSite$1.handleEvent(OleClientSite.java:129)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1077)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1058)
at org.eclipse.swt.widgets.Widget.release(Widget.java:808)
at org.eclipse.swt.widgets.Widget.dispose(Widget.java:446)
at org.eclipse.swt.ole.win32.OleClientSite.<init>(OleClientSite.java:194)
at org.eclipse.swt.ole.win32.OleControlSite.<init>(OleControlSite.java:96)
at com.test.OpenExcelExampleWindow.openExcel(OpenExcelExampleWindow.java:93)
at com.test.OpenExcelExampleWindow.onOpenExcelClicked(OpenExcelExampleWindow.java:65)
at com.test.OpenExcelExampleWindow$1.widgetSelected(OpenExcelExampleWindow.java:57)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:248)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4169)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3758)
at com.test.OpenExcelExampleWindow.main(OpenExcelExampleWindow.java:33)
アップデート:
Maven を使用してまったく新しいプロジェクトを作成し、Eclipse SDK 4.2 の依存関係を 1 つ追加しました。これが私の pom ファイルで、依存関係が 1 つしかないことがわかります。プロジェクト内のコードは、上記のクラスと同じです。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>excelopen</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>excelopen</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.eclipse.swt</groupId>
<artifactId>swt-win32-x86_64</artifactId>
<version>4.2_3.100.0.v4233d</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
OleControlSite クラスのソース コードは 3.8 sdk から 4.2 sdk まで同じであることに気付きました。これにより、問題の原因が SDK のバージョンである可能性は低くなります。
アップデート:
SWT ソース コードをダウンロードすると、OleClientSite の 392 行目のこの行で例外がスローされます。
if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result)
そして隠れた例外は
org.eclipse.swt.SWTException: Failed to create Ole Client. result = -2147221164
at org.eclipse.swt.ole.win32.OLE.error(OLE.java:302)
at org.eclipse.swt.ole.win32.OleClientSite.OleCreate(OleClientSite.java:392)
at org.eclipse.swt.ole.win32.OleClientSite.<init>(OleClientSite.java:192)
at org.eclipse.swt.ole.win32.OleControlSite.<init>(OleControlSite.java:96)
at com.test.OpenExcelExampleWindow.openExcel(OpenExcelExampleWindow.java:93)
at com.test.OpenExcelExampleWindow.onOpenExcelClicked(OpenExcelExampleWindow.java:65)
at com.test.OpenExcelExampleWindow$1.widgetSelected(OpenExcelExampleWindow.java:57)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:248)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4169)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3758)
at com.test.OpenExcelExampleWindow.main(OpenExcelExampleWindow.java:33)
更新 09/05 9:35am
favonius の情報のおかげで、さらに多くの情報を見つけることができました。64 ビット Windows OS での 32 ビット com に関するこのディスカッションを見つけました。ここでは、64 ビットでの 32 ビット com について説明します。 http://www.eclipse.org/forums/index.php/mv/msg/264018/763345/ 32 ビット版のみの Office 2007 を 64 ビット OS で実行しているため、これは私の問題かもしれません。レジストリを確認したいのですが、どのキーを調べればよいかわかりません。レジストリキーが何であるか知っている人はいますか?
更新 09/05 9:45am
以下は favonius が提供した TestCode クラスの結果です。
57 行目にコメントを付けて 1 を実行します。
{00020820-0000-0000-C000-000000000046}
Excel.Sheet.8
org.eclipse.swt.SWTException: Failed to create Ole Client. result = -2147221164
at org.eclipse.swt.ole.win32.OLE.error(OLE.java:302)
at com.test.TestCode.check(TestCode.java:62)
at com.test.TestCode.main(TestCode.java:23)
コメントを外して 2 行目 57 を実行
{00020820-0000-0000-C000-000000000046}
Excel.Sheet.8
更新 09/05 1:51pm
私たちのアプリは、開くための Excel 用の xls ファイルを出力します。xlsx ファイルを読み込もうとしたところ、動作しました。これは、この特定のアプリの問題を修正するための合理的な変更です。xlsファイルを開くことは想定されていませんか?