【问题标题】:Java 7: COM-API does not work with Quality Center (OTAClient.dll), but works with Java 6Java 7:COM-API 不适用于 Quality Center (OTAClient.dll),但适用于 Java 6
【发布时间】: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


【解决方案1】:

Jacob DLL 与来自 JRE 的jvm.dll(方法和结构)链接。所以我的猜测是 Jacob DLL 应该使用 Java 7 从源代码编译,才能正确加载到 Java 7 JRE 中。

你是not alone,但我想已经很少有人在运行 Java 7...

更新:我建议您先使用Process Monitor 进行调查,如果您的 Java 进程中有一些库或系统调用失败,然后在调试器中运行进程本身......也许 OpenJDK 7 可能也是一个尝试的选项,那么它应该更容易调试,至少可以诊断出问题所在。

【讨论】:

  • 我已经用 java 7 构建了 jacob,但这并没有改变任何东西......无论如何,谢谢你的回答!
猜你喜欢
  • 2013-08-19
  • 1970-01-01
  • 2014-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 2013-11-20
相关资源
最近更新 更多