Sometimes I get an error (exception):
java.lang.IllegalStateException: Dispatch not hooked to windows memory
What does it mean? How to prevent it?
This is a sample code that results in this error:
import com.jacob.activeX.*;
import com.jacob.com.*;
public class Hooked {
public static void main(String[] args) {
ActiveXComponent e = new ActiveXComponent("Excel.Application");
ActiveXComponent sh = new ActiveXComponent(
e.getProperty("ActiveSheet").toDispatch());
System.out.println(sh.getPropertyAsString("Name"));
}
}
That means that Dispatch
= nothing
using vba syntax, it's empty. The same dispatch that you receive with new Dispatch()
. Unfortunately Jacob 1.17 does not provide any method to explicitly check whether the Dispatch
is empty or not. So I see 3 possible solutions:
1) Use Variant.isNull()
after receiving the Variant from COM call, before converting it to Dispatch. So it requires 1 additional line:
Variant vsh = e.getProperty("ActiveSheet");
if (vsh.isNull()) {
System.out.println("Null dispatch received.");
}
ActiveXComponent sh = new ActiveXComponent(vsh.toDispatch());
2) Catch IllegalStateException
when using suspected Dispatch for the first time.
3) Write a custom isNull(Dispatch d)
function
public static boolean isNull(Dispatch d)
{
try {
Dispatch.call(d, "");
}
catch (IllegalStateException ise) {
return true;
}
catch (ComFailException cfe) {
// that's ok, we didn't expect this call to succeed
}
return false;
}
In the specific example in the question the call was just a mistake, because Excel has no ActiveSheet if no workbook is open or created.