I am getting a NullPointerException
when trying to open excel from SWT. Sadly I can't post the full stacktrace and some of the code because it has references to the company that I work for. Hopefully someone has run into this issue before and might recognize it.
Here is the part of the stacktrace that I can post
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)
Here is the code. It's on the last line that the exception gets thrown, when a new OleControlSite is instantiated.
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);
This code works in windows XP, but not in windows 7 it throws the NullPointerException
.
As per cubic suggestion I created a self contained example here is the code.
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();
}
}
});
}
}
}
And here is the exception
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)
Update:
I created an entirely new project with maven and just added one dependency for eclipse sdk 4.2 here is my pom file you can see there is only one dependency. The code in the project is the same as the class above.
<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>
I noticed that the source code for the OleControlSite class is the same from 3.8 sdk to the 4.2 sdk, which makes it unlikely that it's the SDK version that's causing the issue for me.
Update:
I download the SWT Source code and the exception get's thrown at line 392 of OleClientSite at this line.
if (result != COM.S_OK) OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result)
And the hidden exception is
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)
Update 09/05 9:35am
Thanks to favonius's information I was able to find out some more information. I found this discussion about 32bit com's on a 64bit windows OS. This is where the 32bit com on 64bit is discussed. http://www.eclipse.org/forums/index.php/mv/msg/264018/763345/ This might be my issue as we are running Office 2007 which only comes in 32bit and it's running on a 64bit OS. I would like to check the registry but I don't know what key's I should look up. Does anyone know what the registry key is?
Update 09/05 9:45am
Here are the results of the TestCode class that favonius provided.
Run 1 with line 57 commented
{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)
Run 2 line 57 uncommented
{00020820-0000-0000-C000-000000000046}
Excel.Sheet.8
Update 09/05 1:51pm
Our app outputs an xls file for excel to open. I just tried reading in an xlsx file and it works. This is a reasonable change to fix the problem with this specific app. Is it not supposed to open xls files?