tango-controls/JTango

Failed to push State attribute

Closed this issue · 0 comments

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