tango-controls / JTango

TANGO kernel Java implementation. JTango moved to https://gitlab.com/tango-controls/JTango
http://tango-controls.org
8 stars 14 forks source link

Failed to push State attribute #70

Closed Ingvord closed 5 years ago

Ingvord commented 5 years ago

Trying to push State attribute change event (deviceManager.pushEvent("State", value, EventType.CHANGE_EVENT);) fails due to:

ERROR 2019-04-18 10:21:27,988 [main - development/hq/main - o.t.u.DevFailedUtils] org.tango.utils.DevFailedUtils.newDevFailed:22 - API_AttrOptProp, org.tango.DeviceState is not of the good type
ERROR 2019-04-18 10:21:27,989 [main - development/hq/main - o.t.u.DevFailedUtils] org.tango.utils.DevFailedUtils.newDevFailed:24 - 
fr.esrf.Tango.DevFailed: API_AttrOptProp
    at org.tango.utils.DevFailedUtils.newDevFailed(DevFailedUtils.java:23)
    at org.tango.server.idl.CleverAttrValUnion.set(CleverAttrValUnion.java:152)
    at org.tango.server.idl.TangoIDLAttributeUtil.toAttributeValue5(TangoIDLAttributeUtil.java:156)
    at org.tango.server.attribute.AttributeImpl.updateValue(AttributeImpl.java:273)
    at org.tango.server.device.DeviceManager.pushEvent(DeviceManager.java:275)
    at org.tango.server.ChangeEventPusher.run(ChangeEventPusher.java:41)
    at de.hzg.wpi.xenv.hq.HeadQuarter.setState(HeadQuarter.java:339)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.tango.server.device.StateImpl.stateMachine(StateImpl.java:143)
    at org.tango.server.device.InitImpl.doInit(InitImpl.java:162)
    at org.tango.server.device.InitImpl.execute(InitImpl.java:127)
    at org.tango.server.servant.DeviceImpl.doInit(DeviceImpl.java:634)
    at org.tango.server.servant.DeviceImpl.initDevice(DeviceImpl.java:676)
    at org.tango.server.build.DeviceBuilder.createDevice(DeviceBuilder.java:127)
    at org.tango.server.build.DeviceClassBuilder.buildDevice(DeviceClassBuilder.java:70)
    at org.tango.server.export.TangoExporter.buildDevice(TangoExporter.java:228)
    at org.tango.server.export.TangoExporter.exportDevices(TangoExporter.java:118)
    at org.tango.server.export.TangoExporter.exportAll(TangoExporter.java:87)
    at org.tango.server.ServerManager.init(ServerManager.java:262)
    at org.tango.server.ServerManager.start(ServerManager.java:181)
    at de.hzg.wpi.xenv.hq.HeadQuarter.main(HeadQuarter.java:56)

I have inspected the following in CleverAttrValUnion.java#set:

//...
// put in an array before inserting for scalars
            array = Array.newInstance(AttributeTangoType.getTypeFromTango(tangoType).getType(), 1);
            try {
                Array.set(array, 0, value);
            } catch (final IllegalArgumentException e) {
                throw DevFailedUtils.newDevFailed(ExceptionMessages.ATTR_OPT_PROP, value.getClass().getCanonicalName()
                        + " is not of the good type");
            }
//...

Here value.getClass == org.tango.DeviceState, while AttributeTangoType.getTypeFromTango(tangoType).getType() == fr.esrf.tango.DevState i.e. fr.esrf.tango.DevState[0] = org.tango.DeviceState which obviously leads to IAE

Temporary workaround: transform DeviceState to DevState before pushing e.g. deviceManager.pushEvent("State", value.getDevState(), EventType.CHANGE_EVENT);.

Solution: encapsulate transformation into the library