Question

I am using Com4J to interact with Microsoft Outlook. I have generated the Java type definitions as per the Com4J tutorial. Here is an example of some code that waits for the user to close an email.

// Registers my event handler
mailItem.advise(
        ItemEvents.class,
        new ItemEvents() {
            @Override
            public void close(Holder<Boolean> cancel) {
                // TODO Auto-generated method stub
                super.close(cancel);
                System.out.println("Closed");
            }
        }
    );

// Displays the email to the user
mailItem.display();

This code successfully displays the email to the user. Unfortunately, my program never prints "Closed" when the user closes the window.

Was it helpful?

Solution

When Com4J generates an event class (ItemEvents in my scenario), the default behavior for all generated methods is to throw an UnsupportedOperationException (see the com4j.tlbimp.EventInterfaceGenerator class for details).

For example, here is the close method of the ItemEvents class that my anonymous class overrides:

@DISPID(61444)
public void close(Holder<Boolean> cancel) {
    throw new UnsupportedOperationException();
}

Therefore, when my anonymous class calls super.close(cancel);, the parent class throws an UnsupportedOperationException, preventing execution from reaching my System.out.println("Closed"); statement. Therefore, my anonymous class should really have looked like this:

mailItem.advise(
        ItemEvents.class,
        new ItemEvents() {
            @Override
            public void close(Holder<Boolean> cancel) {
                System.out.println("Closed");
            }
        }
    );

What surprised me is that Com4J appears to have simply ignored the UnsupportedOperationException thrown from the event handler altogether, leaving me no indication of what actually happened. I wrote this code to demonstrate:

mailItem.advise(
        ItemEvents.class,
        new ItemEvents() {
            @Override
            public void close(Holder<Boolean> cancel) {
                System.out.println("Getting ready to throw the exception...");
                throw new RuntimeException("ERROR! ERROR!");
            }
        }
    );

The program emits this output:

Getting ready to throw the exception...

However, there is no indication that a RuntimeException was ever thrown.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top