【发布时间】:2012-05-19 20:24:10
【问题描述】:
我们在 Windows 7 Enterprise、SP1、64 位上运行。 我们刚刚在我们所有的机器上安装了 Java 7,这会导致以下问题:
当我的程序尝试从 Quality Center 与 OpenTestArchitecture-API 通信时,它无法创建 ActiveX-Component。我使用JACOB 作为我的Java-COM 库。升级到最新版本的 JACOB 不会改变任何东西。
以下测试适用于 jdk1.6.0_24(32 位),但适用于 jdk1.7.0_04(32 位):
import java.io.File;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.LibraryLoader;
public class JacobTest {
static {
File lib = new File("lib/" + LibraryLoader.getPreferredDLLName() + ".dll");
System.setProperty(LibraryLoader.JACOB_DLL_PATH, lib.getAbsolutePath());
System.out.println("JACOB_DLL_PATH = " + lib.getAbsolutePath());
LibraryLoader.loadJacobLibrary();
}
public static void main(String[] args) {
try {
// Excel: Works with jdk1.6.0_24 AND jdk1.7.0_04
System.out.println("new ActiveXComponent(\"Excel.Application\");");
new ActiveXComponent("Excel.Application");
// Quality Center OTAClient: Only works with jdk1.6.0_24
System.out.println("ActiveXComponent component = new ActiveXComponent(\"TDApiOle80.TDConnection\");");
ActiveXComponent component = new ActiveXComponent("TDApiOle80.TDConnection");
System.out.println("ComThread.InitSTA();");
ComThread.InitSTA();
System.out.println("Dispatch.call(component, \"InitConnectionEx\", \"http://intranet/qcbin\");");
Dispatch.call(component, "InitConnectionEx", "http://intranet/qcbin");
}
catch (Exception exception) {
exception.printStackTrace();
}
}
}
jdk1.6.0_24 输出:
JACOB_DLL_PATH = C:\Development\Java\Test\JacobTest\lib\jacob-1.17-M2-x86.dll
new ActiveXComponent("Excel.Application");
ActiveXComponent component = new ActiveXComponent("TDApiOle80.TDConnection");
ComThread.InitSTA();
Dispatch.call(component, "InitConnectionEx", "http://intranet/qcbin");
jdk1.7.0_04 输出:
JACOB_DLL_PATH = C:\Development\Java\Test\JacobTest\lib\jacob-1.17-M2-x86.dll
new ActiveXComponent("Excel.Application");
ActiveXComponent component = new ActiveXComponent("TDApiOle80.TDConnection");
com.jacob.com.ComFailException: Invalid access to memory location.
at com.jacob.com.Dispatch.createInstanceNative(Native Method)
at com.jacob.com.Dispatch.<init>(Dispatch.java:99)
at com.jacob.activeX.ActiveXComponent.<init>(ActiveXComponent.java:58)
at JacobTest.main(JacobTest.java:26)
原来的 ComFailException-Message 是“无法共同创建对象”,但我在 jacob Dispatch.cpp 中编辑了以下代码:(我没有接触 CoCreateInstance,我只是想知道 HRESULT 是什么)
// standard creation
hr = CoCreateInstance(clsid,NULL,CLSCTX_LOCAL_SERVER|CLSCTX_INPROC_SERVER,IID_IUnknown, (void **)&punk);
if (!SUCCEEDED(hr)) {
if (hr == REGDB_E_CLASSNOTREG)
ThrowComFail(env, "Can't co-create object: REGDB_E_CLASSNOTREG", hr);
if (hr == CLASS_E_NOAGGREGATION)
ThrowComFail(env, "Can't co-create object: CLASS_E_NOAGGREGATION", hr);
if (hr == E_NOINTERFACE)
ThrowComFail(env, "Can't co-create object: E_NOINTERFACE", hr);
if (hr == E_POINTER)
ThrowComFail(env, "Can't co-create object: E_POINTER", hr);
_com_error error(hr);
LPCTSTR errorText = error.ErrorMessage();
ThrowComFail(env, errorText, hr);
return;
}
有人知道问题可能是什么吗?唯一的区别是我在 Java 6 和 Java 7 运行时之间切换。
非常感谢您的帮助!
PS:Excel 可以在这两个版本中使用,切换到com4j-Library 不会改变任何内容。 (我有一个com4j-Test,但我没有发布它,因为我已经发布了足够的代码)
编辑:同样的测试适用于 Windows XP、SP3 和 Java 7。
【问题讨论】:
-
不清楚您从原始 jacob 代码中得到的异常是“内存访问冲突”还是 HRESULT?
-
如果你能澄清使用 com4j 和 java 7 是否会重现相同的行为。
-
原来的 Jacob-Exception 是“不能共同创建对象”。因为这并不能说明太多,所以我试图弄清楚 Native-Part 中 CoCreateInstance 函数的结果是什么。此方法的错误消息是“对内存位置的访问无效”。当我使用 com4j 而不是 Jacob 时,我得到相同的结果:“Excel.Application”和“TDApiOle80.TDConnection”适用于 Java 6,Java 7“Excel.Application”适用,但“TDApiOle80.TDConnection”不适用。
-
不应该在创建可能需要特定模型的组件之前设置 COM 线程模型 (
ComThread.InitSTA()) 吗? -
@cynic:不知道。它的工作原理与 java 6 一样。在创建 ActiveXComponent 之前调用 ComThread.InitSTA() 不会改变 java 7 的行为。我只是尝试过。
标签: java com java-7 jacob hp-quality-center