ComException, error code: 0x80080005 by RTDServerSample

295 views
Skip to first unread message

Emre K S

unread,
Jul 31, 2014, 7:17:32 AM7/31/14
to comfyj...@teamdev.com
Hello,

currently I am trying to execute the RTDServerSample. I ran the project as described in http://comfyj-support.teamdev.com/samples/ms-office/excel-rtd-server-sample (comments). But Excel failed to connect to the server and returned only N/A results. So I thought, something is wrong with the  the Server Manager Application (actually it looked working but no real LOG informations were comming out. The static fields are working but other methods are not called at all, including the constructor). So i tried further...

I decided to execute the server at Run Time as described in the documentation... You can see below my main method. It looks like, the server is "registered" correctly: eclipse without Admin-rights fails to execute registerComServer, but with rights there are no errors or warnings. Asserts are working, too. After it is registered, excel still cannot access the information. So I decided to create a client, as you can see in the middle of the method.

I am not sure about the client part, but I think it is programmed like it is described in the documentation. And like excel, this client fails to start the server with the exception below.

public static void main(String[] args) throws InterruptedException,
InvocationTargetException {
LOG.info("...");
// registering the server
final String classPath = System.getProperty("java.class.path");
ComServerDescriptor serverDescriptor = new RegisterDispatchComServer.ComServerDescriptor(
RTDServerSample.class, classPath,
System.getProperty("jvm.path"), classPath, null, false);
List<Object> warnings = new ArrayList<Object>();
RegisterDispatchComServer.registerComServer(serverDescriptor, warnings);
assert RegisterDispatchComServer
.isRegistered(RTDServerSample.COM_SERVER_CLSID);
LOG.info("Server registered.");

// client side. actually, this should be done in excel.
Runnable client = new Runnable() {
public void run() {
IDispatch cDispatch = null;
int count = 0;
int maxTries = 3;
while (true) {
try {
 
// FAILING CALL
cDispatch = new IDispatchImpl(
CLSID.createFromProgID(RTDServerSample.PROG_ID
.toLowerCase()), ClsCtx.LOCAL_SERVER);
if (cDispatch != null)
break;
} catch (ComException e) {
if (++count == maxTries)
throw e;
}
}

IRtdServerImpl ci = new IRtdServerImpl(cDispatch);
System.out.println("IID" + ci.getIID());
}
};
OleMessageLoop.invokeAndWait(client);
OleMessageLoop.stop();

// unregistering the server
assert RegisterDispatchComServer
.isRegistered(RTDServerSample.COM_SERVER_CLSID);
RegisterDispatchComServer.unregisterComServer(serverDescriptor);
assert !RegisterDispatchComServer
.isRegistered(RTDServerSample.COM_SERVER_CLSID);
LOG.info("Server unregistered.");
}
}


com.jniwrapper.win32.com.ComException: COM object method returns error code: 0x80080005; Starten des Servers fehlgeschlagen (something like, the server failed to start. My system is German, so i assume this error is generated by the windows.). The failing statement is cDispatch = new IDispatchImpl(...). 

To summarize: Server is registered. The static parts are existing but when the client tries to connect to the server, the server "object" will be not constructed, etc. I could not debug the part between the failing call and the class, as i don't have the source-code. 

Do you have any idea, how can I solve this problem? Btw. sorry about the long post :) 

Sergei Piletsky

unread,
Jul 31, 2014, 8:20:12 AM7/31/14
to Emre K S, comfyj...@teamdev.com
Hi,

I think the cause of the issue is in improper registration of server in your case

I should mention here that in RTDServer project there is the RTDSererRegistration.java example that demonstrates the proper registration of the server. It demonstrates how to configure class path of RTD server, its location, and the path to Java executable. This is important, because all these parameters should be properly specified, and it's definitely should not be "System.getProperty("java.class.path");" like in your case. You also need to pay the attention to the server.jar\META-INF\MANIFEST.MF file, where all required libraries are specified in Class-Path attribute of the manifest file. And, of course, you also need to put your valid ComfyJ license files to the licenses.jar, because one fromlicenses.jar\META-INF folder is already expired.

The sample project also includes RTDClientSample.java example that demonstrates how to create a client for testing the RTD server at runtime.

Please let me know if you have any further questions.

Sincerely,
Sergei


--
You are receiving this email because you have joined the "ComfyJ Forum" group or have been added by request. You may choose not to receive emails from this group or unsubscribe completely on "Edit my membership" page.
Go to http://links.teamdev.com/comfyj-forum, choose "Edit my membership" link on the right. Specify your email preferences in suggested options, or click "Unsubscribe" button.
---
You received this message because you are subscribed to the Google Groups "ComfyJ Forum" group.
To unsubscribe from this group and stop receiving emails from it, send an email to comfyj-forum...@teamdev.com.
To post to this group, send email to comfyj...@teamdev.com.
Visit this group at http://groups.google.com/a/teamdev.com/group/comfyj-forum/.
For more options, visit https://groups.google.com/a/teamdev.com/d/optout.

Emre K S

unread,
Aug 4, 2014, 7:29:02 AM8/4/14
to comfyj...@teamdev.com, emrese...@gmail.com
Hello Sergei,

after downloading the whole sample, I made some progress but still Excel is failing to retrieve the data. I will try to describe what I am doing. Maybe you will see my mistake:
I import the sample into an eclipse project and I also use it to export the project as server.jar. The file comfyj-svrmanager-2.10.jar was missing in the sample, so I add it to lib folder and I add the all lib files to project build path. I change the following variables like this:

String jvmPath = "C:\\...\\jdk1.6.0_45\\bin\\java.exe";
String serverLocation = "C:\\...\\workspace\\RTDServerSample3\\";
String classpath = "C:\\...\\workspace\\RTDServerSample3\\lib\\server.jar"; 

The generated manifest file is for some reason empty in my server.jar. so I force eclipse to use the existing manifest file, which i copied from your server.jar and changed it to include comfyj-svrmanager-2.10.jar. 

By the way: the classes in package com.jniwrapper.win32.excel seems to be generated by CodegenByComfy application. They look same but I tried both versions (generated and the files in the sample). So this should not be the reason for the failure. also the licence.jar is ok. 

I altered the client method a little bit like this:
// ...
System.out.println("heartbeat = " + heartbeat);

// trying connecting data
System.out.println("trying connecting data");
Int32 intIn = new Int32(12345);
Variant topic1 = new Variant();
topic1.setValue(new BStr("AAA"));
Variant topic2 = new Variant();
topic2.setValue(new BStr("10"));
SafeArray safeArrayIn = new SafeArray(2, Variant.class);
safeArrayIn.set(0, topic1);
safeArrayIn.set(1, topic2);

VariantBool vBoolOut = new VariantBool(true);
Variant result = rtdServer.connectData(intIn, safeArrayIn, vBoolOut);
String resultValue = result.getBstrVal().getValue();
System.out.println("Result: " + resultValue);

(sorry that formating is not working :)). After I start the server, and i run the client; everything looks ok, as I get the result "AAA:10", which is as far as I understand the expected result. So practically everything is working... except the call in excel =RTD("rtdserversample";;"AAA"; "10") which still returns N/A...

the log of the server side prints the following (after I decide to kill the server and press enter), which doesn't look dangerous but might be interesting. 
- Changing of AutoDelete from 'false' to 'true' detected - this may cause memory management issue
java.lang.Exception: Stack Trace
at com.jniwrapper.win32.com.impl.IUnknownImpl.setAutoDelete(SourceFile:238)
at com.jniwrapper.win32.com.server.IUnknownServer.doQueryInterface(SourceFile:238)
at com.jniwrapper.win32.com.server.IUnknownServer.queryInterface(SourceFile:172)
at com.jniwrapper.win32.com.server.IUnknownServer.create(SourceFile:298)
at com.jniwrapper.win32.com.server.IClassFactoryServer.createIClassFactory(SourceFile:200)
at rtdsample.RTDSererRegistration$1.run(RTDSererRegistration.java:70)
at com.jniwrapper.win32.MessageLoopThread$ThreadSynchronizedAction.run(MessageLoopThread.java:620)
at com.jniwrapper.win32.MessageLoopThread$LoopThread.run(MessageLoopThread.java:562)
Registering our IClassFactory instance...
Our IClassFactory instance was successfully registered.
Press 'Enter' to terminate server.


Revoking our IClassFactory instance...
- Failed to invoke method: queryInterfaceAggregated; cause: COM object method returns error code: 0x80004002; E_NOINTERFACE (Schnittstelle nicht unterstützt) (engl. Interface not supported)
- Terminated thread Main message loop
Our IClassFactory instance was successfully revoked.

Other than that, after the client connects and gets the value, I get a message like this:
- There is no id for server class: class rtdsample.RTDServerSample
Though like said before, this doesn't cause any problem, when the custom client retrieves the value. 

What could be the error? Are the E_NOINTERFACE and ID- Messages important? after all, my custom client is working. Is it possible, that COM objects actually fail to register? Is there a way to control that? Maybe even the Excel Data Library is not registered? 

I apologize for the long post but I try to describe it as detailed as possible to avoid misunderstanding. thank you for your time. 

Sincerely,
Emre

Sergei Piletsky

unread,
Aug 4, 2014, 11:18:12 AM8/4/14
to Emre K S, comfyj...@teamdev.com
Hi Emre,

From your description I think that the most probable reason why Excel cannot see your RTD server (N/A messages in an Excel document) is that architecture of your Java RTD server differs from the architecture of Excel application on your computer.

Excel application can have either 32-bit or 64-bit architecture. You can find out architecture of your Excel installation in Excel About dialog/panel, for example:
Inline image 1

ComfyJ also provides the ability to to register the Java COM servers either in 32-bit or in 64-bit modes depending on which JVM you use for registering the server. So, if a COM server is registered in 32-bit mode then it can only visible for another 32-bit COM applications. The same rule applies for 64-bit COM servers: 64-bit COM servers are visible for 64-bit COM applications only. I am talking here about COM servers in general just to point out that such restriction is the limitation of COM itself, but not the limitation of ComfyJ. So, to summarize, 32-bit COM components are not visible for 64-bit COM applications and vice versa.

These facts (and information that your server can be successfully instantiated by a test client application) should explain the issue that you found: apparently you registered your Java RTD server with a 32-bit JVM, whereas your Excel is 64-bit one, or you registered your Java RTD server with a 64-bit JVM, but your Excel is 32-bit one. In either case Excel will not be able to see your Java RTD server (in a COM registry). 

So, the simplest solution is to register your Java RTD server using a JVM with the same architecture as your Excel.

The general solution for 64-bit environment, when you want to make your component visible for 32-bit and 64-bit COM applications would be to register your Java RTD server for both architectures. In other words you will need to run registration procedure in a 32-bit JVM and then in 64-bit one. Current version of ComfyJ does not allow to register a Java COM server for different architectures, this is a planned feature for one of the next versions.

Of course, you may reasonably ask me why 32-bit COM applications can integrate 64-bit Excel, or a 64-bit COM application can use 32-bit Excel components. The answer to this question is that COM provides such possibility for so called out-of-process (or local) COM servers via RPC. It is still required that a COM server should be registered in each COM architecture. You can find out more information about this in different sources, for example this one that I found in the first ten results in a search engine. In general this technique allows using (out-of-proc) COM servers in applications which have different architectures

By the way, ComfyJ allows to register Java COM servers as LOCAL_SERVER ClsCtx only. This means, that if you have registered a Java COM server for both 32-bit and 64-bit architectures, you can substitute that COM server with any of architectures at runtime as it is demonstrated in the RTDSererRegistration sample in its registerRTDSererAtRuntime() method. This technique will allow you to run your RTD server on a 32-bit, or a 64-bit JVM, not depending on Excel's architecture.

Regarding your questions about "There is no id for server class" and  "Failed to invoke method: queryInterfaceAggregated" messages in a log I can say that you should not wary about them. Those are debug log messages and they should not affect the functioning of your application.

Please let me know if you have any further questions.

Sincerely,
Sergei


--

Emre K S

unread,
Aug 4, 2014, 12:15:54 PM8/4/14
to comfyj...@teamdev.com
Hello Sergei,

well, it worked. Both applications were actually on 32Bit mode. But your message lead me to somewhere else. I was using Microsoft Ole-Com-Object Viewer but I discovered that I was just seeing 64 bit objects. I run the 32 bit version of it and saw my old registered COM objects, whose CLSIDs were colliding with the application. I just changed the CLSID and it worked. In case someone else makes this mistake, I recommend to use MS OLE-COM-Object Viewer which is delivered as part of the (free) MS Windows SDK. I am ashamed of this silly mistake, but still publishing the solution :)

One last question: Is it safe to delete the registry entries of the servers? Which registries are changed, when a server is registered?

Thank you for your time,
Sincerely,
Emre

Sergei Piletsky

unread,
Aug 4, 2014, 12:43:24 PM8/4/14
to Emre K S, comfyj...@teamdev.com
Hi Emre,

Thanks for sharing your finding.

Of course it is safe to delete the registry entries of a server, but only if you know which entries to delete. 

You can find all required information about COM server registration in MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683954(v=vs.85).aspx

If you want to unregister your Java COM server, you can just call the RegisterDispatchComServer.doUnregisterComServer method and it will remove all entries from the registry.

Sincerely,
Sergei


--

Emre K S

unread,
Sep 23, 2014, 12:29:53 PM9/23/14
to comfyj...@teamdev.com, emrese...@gmail.com
Hello,

i have another question about the sample. The method CLSID.createFromProgID(Sample.PROG_ID) seems to throw always an exception. So, the isServerAlreadyRegisteredInSystem() returns always false. I actually tried to use same method to unregister servers, after I am done but it was not sucessful. 

Exception message: COM object method returns error code: 0x800401F3; CO_E_CLASSSTRING (Ungültige Klassenzeichenfolge)

I am currently using comfyj 2.10. Because I couldn't unregister the stuff created by the old versions, there lots of entries of the same program. Can this be the reason, that createFromProgID fails? I think it is unlikely, even though all different versions have different PROG_IDs they all have the same CLSID and VERSION_INDEPENDENT_PROG_ID.

What can be the reason for this? I am sure that the server is working and it is registered, because it is visible on OLE/COM Viewer and Windows registry.

Sincerely,
Emre

Emre K S

unread,
Sep 23, 2014, 12:47:37 PM9/23/14
to comfyj...@teamdev.com, emrese...@gmail.com
Just another question: In the following line, I am planning to leave the paramaters except serverClass empty.
RegisterDispatchComServer.ComServerDescriptor descriptor = new RegisterDispatchComServer.ComServerDescriptor(
serverClass, serverLocation, jvmPath, classpath, VMParameters,
runIndividualJVM);
My motivation is forcing excel to stop trying to restart the application, if it is not there. The server should be run only by another application. Would this cause me much trouble?
Reply all
Reply to author
Forward
0 new messages