Search code examples
javaautomationcomjacob

Set indexed Property with JACOB fails with 'Member not found'


I have to automate some tasks in XPedition with COM automation using Java and JACOB. When I try to set an indexed property of an object, I receive an error:

com.jacob.com.ComFailException: A COM exception has been encountered:
At Invoke of: Pad
Description: 80020003 / Mitglied nicht gefunden.

I use this method to deal with indexed properties:

public void setIndexedProperty(final String propertyName, final Variant[] indexes,
        final Variant propValue) {
    Variant[] parameters = new Variant[indexes.length + 1];
    for (int i = 0; i < indexes.length; i++) {
        parameters[i] = indexes[i];
    }
    parameters[indexes.length] = propValue;
    Dispatch.invokev(activeXComponent, propertyName, Dispatch.Put, parameters,
            new int[parameters.length]);
}

And call it like this:

ActiveXComponent pad = ... //Result of an other method;
padstack.setIndexedProperty("pad",new Variant[] { new Variant(-1)}, new Variant(pad) );

This gives the above error.

I created a vbs script to check if there is a general problem with the code. This gives the expected result (property is set).

...
set pad = padstackDBObj.NewPad()
...
set padstack = padstackDBObj.NewPadstack()
set padstack.pad(-1)=pad
...

I checked the pad object passed as the value in my java code and it is a valid object. I also can query the current pad(-1) property of a padstack object successfully.

I played around with the type of the parameter I pass. I tried long, short, byte, string, but I got the same error.

I set indexed properties at several other locations without any problems. New in this case is that the parameter is an negative integer and the value is an object. So one of those may cause the issue.


Solution

  • A look into the Type Library with oleview shows that the method requires a propputref call.

    So the correct jacob call uses Dispatch.PutRef and not Dispatch.Put:

    public void setIndexedRefProperty(final String propertyName, final Variant[] indexes,
            final Variant propValue) {
        Variant[] parameters = new Variant[indexes.length + 1];
        for (int i = 0; i < indexes.length; i++) {
            parameters[i] = indexes[i];
        }
        parameters[indexes.length] = propValue;
        Dispatch.invokev(activeXComponent, propertyName, Dispatch.PutRef, parameters,
                new int[parameters.length]);
    }