GReD-Clermont / simple-omero-client

Maven project to easily connect to OMERO.
GNU General Public License v2.0
10 stars 7 forks source link

Deleting list of ROIWrapper throws an error and no ROIs are deleted #59

Closed Rdornier closed 1 year ago

Rdornier commented 1 year ago

Bug report

Description

Throws an error when trying to delete a list of ROIWrapper() using the delete(Collection<? extends GenericObjectWrapper<?>> objects) method in Clientclass

The follwing script generates the follwing error

def image = user_client.getImage(id)
ROI_list = image.getROIs(user_client)
user_client.delete(ROI_list)

However, if I do the cast to IObject manually from ROIWrapper (and not from GenericObjectWrapper), then it does not throw any errors and delete all ROIs. The code snippet below works fine.

def image = user_client.getImage(id)
ROI_list = image.getROIs(user_client)
user_client.delete(ROI_list.stream().map(ROIWrapper::asIObject).collect(Collectors.toList()))

Error thrown

fr.igred.omero.exception.AccessException: Cannot delete objects
    at fr.igred.omero.exception.ExceptionHandler.rethrow(ExceptionHandler.java:258)
    at fr.igred.omero.exception.ExceptionHandler.handleException(ExceptionHandler.java:318)
    at fr.igred.omero.GatewayWrapper.delete(GatewayWrapper.java:435)
    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.codehaus.groovy.runtime.callsite.PlainObjectMetaMethodSite.doInvoke(PlainObjectMetaMethodSite.java:43)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoCachedMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:214)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:56)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
    at testPPouchin.run(testPPouchin.groovy:80)
    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:317)
    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:155)
    at org.scijava.plugins.scripting.groovy.GroovyScriptLanguage$1.eval(GroovyScriptLanguage.java:97)
    at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
    at org.scijava.script.ScriptModule.run(ScriptModule.java:157)
    at org.scijava.module.ModuleRunner.run(ModuleRunner.java:163)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:124)
    at org.scijava.module.ModuleRunner.call(ModuleRunner.java:63)
    at org.scijava.thread.DefaultThreadService.lambda$wrap$2(DefaultThreadService.java:225)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:750)
Caused by: omero.gateway.exception.DSAccessException: Cannot access data. 
Cannot delete the object.
    at omero.gateway.facility.Facility.handleException(Facility.java:305)
    at omero.gateway.facility.DataManagerFacility.delete(DataManagerFacility.java:225)
    at fr.igred.omero.GatewayWrapper.lambda$delete$6(GatewayWrapper.java:433)
    at fr.igred.omero.exception.ExceptionHandler.ofConsumer(ExceptionHandler.java:202)
    at fr.igred.omero.GatewayWrapper.delete(GatewayWrapper.java:433)
    ... 24 more
Caused by: java.lang.ClassCastException: fr.igred.omero.roi.ROIWrapper cannot be cast to omero.model.IObject
    at omero.gateway.facility.DataManagerFacility.delete(DataManagerFacility.java:220)
    ... 27 more

Expected results

Having the possibility to use directly client.delete() with a list of ROIWrappers

Version of the software

Tested on 5.9.2 and 5.12.2 => give the same error.

ppouchin commented 1 year ago

Is this in a Groovy script in Fiji?

It is weird, because there is a delete method for GenericObjectWrapper objects (and subclasses): https://github.com/GReD-Clermont/simple-omero-client/blob/main/src/main/java/fr/igred/omero/Client.java#L187

It looks as if the method called is GatewayWrapper::delete instead of Client::delete, but a method with the appropriate signature exists...

Rdornier commented 1 year ago

Yes, it is in a groovy script in Fiji.

ppouchin commented 1 year ago

Ok. I'm not sure but I think it is caused by type erasure in Groovy and the fact it uses the runtime type (and not the declared type) to determine which method should be used. For Groovy, ROI_list is a List of something, and GatewayWrapper::delete is the method with a List parameter.

Casting the argument in the call seems to work:

user_client.delete((Collection<ROIWrapper>) ROI_list);

The alternative would be to rename the methods so they have a distinct name, but that's not really a solution.

Rdornier commented 1 year ago

user_client.delete((Collection<ROIWrapper>) ROI_list);

I works fine, thanks.

The alternative would be to rename the methods so they have a distinct name, but that's not really a solution.

I agree, having a distinct name is not really helpful. In fact, I think the problem here is more groovy than method' name.