Nos estamos ejecutando en Windows 7 Enterprise, SP1, 64 bits. Acabamos de instalar Java 7 en todas nuestras máquinas, lo que provoca el siguiente problema:Java 7: COM-API no funciona con Quality Center (OTAClient.dll), pero funciona con Java 6
Cuando mi programa intenta comunicarse con la API OpenTestArchitecture de Quality Center, no puede crear el componente ActiveX. Yo uso JACOB como mi biblioteca Java-COM. La actualización a la última versión de JACOB no cambia nada.
La siguiente prueba funciona con jdk1.6.0_24 (32 bits), pero falla con jdk1.7.0_04 (32 bits):
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();
}
}
}
salida 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 de salida:
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)
el original ComFailException-mensaje es "no se puede co-crear el objeto" pero he editado el siguiente código en el j acob Dispatch.cpp: (no toqué CoCreateInstance, sólo quería saber cuál era el 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;
}
¿Alguien tiene una idea de lo que el problema podría ser? La única diferencia es que cambio entre Java 6 y Java 7 runtime.
Muchas gracias por su ayuda!
PD: Excel funciona con ambas versiones y un interruptor al com4j-Library no cambia nada. (Tengo un com4j-Test, pero No he puesto porque yo ya he publicado suficiente código)
Editar: La misma prueba funciona con Windows XP, SP3 y Java 7.
No está claro si la excepción que está recibiendo del código jacob original es una "violación de acceso a la memoria" o un HRESULT? –
Y si puede aclarar si se reproduce el mismo comportamiento usando com4j y java 7. –
La excepción Jacob original es "No se puede co-crear un objeto". Como esto no dice mucho, traté de averiguar cuál era el resultado de la función CoCreateInstance en la parte nativa. El mensaje de error de este método es "Acceso no válido a la ubicación de la memoria". Cuando uso com4j en lugar de Jacob obtengo los mismos resultados: "Excel.Application" y "TDApiOle80.TDConnection" funcionan con Java 6, con Java 7 "Excel.Application" funciona pero "TDApiOle80.TDConnection" no funciona. – r3zn1k