Subscribing to COM Events with Com4j

1.5k views Asked by At

I'm trying to hook into a proprietary network stack from Java. The stack is provided by a COM object, and I've managed to hook into it using com4j. Unfortunately, the network stack is event-based, so I need my code to issue requests and subscribe to events that provide the responses.

Every time I try to subscribe to events, my code throws a com4j.ExecutionException that contains a stack trace similar to the following:

Exception in thread "main" com4j.ExecutionException: com4j.ComException: 80040200 (Unknown error) : .\invoke.cpp:517
at com4j.ComThread.execute(ComThread.java:203)
at com4j.Task.execute(Task.java:25)
at com4j.Wrapper.advise(Wrapper.java:255)
at com4j.Wrapper.advise(Wrapper.java:18)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com4j.Wrapper.invoke(Wrapper.java:135)
at $Proxy5.advise(Unknown Source)
at main.Main.<init>(Main.java:14)
at main.Main.main(Main.java:131)

Caused by: com4j.ComException: 80040200 (Unknown error) : .\invoke.cpp:517
at com4j.Native.invoke(Native Method)
at com4j.StandardComMethod.invoke(StandardComMethod.java:42)
at com4j.Wrapper$InvocationThunk.call(Wrapper.java:335)
at com4j.Task.execute(Task.java:36)
at com4j.Wrapper$InvocationThunk.invoke(Wrapper.java:324)
at com4j.Wrapper.invoke(Wrapper.java:163)
at com4j.$Proxy9.FindConnectionPoint(Unknown Source)
at com4j.Wrapper$3.call(Wrapper.java:261)
at com4j.Wrapper$3.call(Wrapper.java:255)
at com4j.Task.invoke(Task.java:51)
at com4j.ComThread.run0(ComThread.java:153)
at com4j.ComThread.run(ComThread.java:134)

At first, I figured that something was wrong with my code or with my COM object, so I went back to basics and tried to implement the iTunes example that ships with the com4j source. Their example looks like this:

public class Main {
public static void main(String[] args) throws Exception {
    IiTunes iTunes = ClassFactory.createiTunesApp();

    EventCookie cookie = iTunes.advise(_IiTunesEvents.class, new _IiTunesEvents() {
        public void onDatabaseChangedEvent(Object deletedObjectIDs, Object changedObjectIDs) {
            System.out.println("Database changed:" + deletedObjectIDs + "," + changedObjectIDs);
        }

        public void onPlayerPlayEvent(Object iTrack) {
            System.out.println("Playing " + iTrack);
        }

        public void onPlayerStopEvent(Object iTrack) {
            System.out.println("Stopped " + iTrack);
        }
    });

    IITTrack track = iTunes.currentTrack();
    if(track==null) {
        System.out.println("Nothing is playing");
    } else {
        System.out.println("Now playing: "+ track.name());
    }

    System.out.println("Listening to events (will quit in 15 seconds)");
    System.out.println("Play/stop songs in iTunes and see what happens");
    Thread.sleep(15000);

    cookie.close();
}
}

When I try to run this example on my machine, I get the above exception on the line

EventCookie cookie = iTunes.advise(_IiTunesEvents.class, new _IiTunesEvents() {...

Does anybody have any insight as to why I can't subscribe to events thrown by the COM object?

I've tried similar code with the object that I'm actually trying to wrap, and it fails in the same way, which leads me to believe that the issue has to do with my development environment.

1

There are 1 answers

0
jeid On

The thread is already some months old, but did you use the generated event interface and check for the correct @IID("{...}")? In my case this was wrong when I compared it with the same class in the typelib (.tlb file) with OLE/COM Object Viewer.

After creating a public abstract class with the correct @IID it worked fine for me.