Error when modifying combine annotation results script

Hi @petebankhead ,

I am trying to adapt your old Groovy script to combine the annotation results exported by your other old script but I ran into an error that I am not able to troubleshoot.

The lines in question are:

// Prompt for directory containing the results
// def dirResults = Dialogs.promptForDirectory() // This original one works
def dirResults = buildFilePath(PROJECT_BASE_DIR, 'TissueQC') // I am trying to use this as my export folder is in a fixed location relative to the project directory
if (dirResults == null)
    return
def fileResults = new File(dirResults, outputName)

// Get a list of all the files to merge
def files = dirResults.listFiles({
    File f -> f.isFile() &&
            f.getName().toLowerCase().endsWith(ext) &&
            f.getName() != outputName} as FileFilter)

Running the script produces this error:

ERROR: MissingMethodException at line 18: No signature of method: java.lang.String.listFiles() is applicable for argument types: (com.sun.proxy.$Proxy26) values: [Script147$_run_closure1@45f1787d]

ERROR: org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:70)
    org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:46)
    org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:139)
    Script147.run(Script147.groovy:19)
    org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:317)
    org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:155)
    qupath.lib.gui.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:926)
    qupath.lib.gui.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:859)
    qupath.lib.gui.scripting.DefaultScriptEditor.executeScript(DefaultScriptEditor.java:782)
    qupath.lib.gui.scripting.DefaultScriptEditor$2.run(DefaultScriptEditor.java:1271)
    java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    java.base/java.util.concurrent.FutureTask.run(Unknown Source)
    java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    java.base/java.lang.Thread.run(Unknown Source)

Where line 18 is:

def files = dirResults.listFiles({

I will be grateful if you can point me in the right direction!

Many thanks,
Yau

Hi @ym.lim ,

buildFilePath(...) returns a String, not a File. You could change
def dirResults = buildFilePath(PROJECT_BASE_DIR, 'TissueQC')
to
def dirResults = new File(buildFilePath(PROJECT_BASE_DIR, 'TissueQC'))

And then use listFiles(yourFilter).

3 Likes

Thank you so much @melvingelbard ! It works now!

Might be a stupid question to ask, but why would

def dirResults = Dialogs.promptForDirectory()

work without needing to specify it as a File? When I tried printing the paths produced by both methods, they are exactly the same. I’m guessing that promptForDirectory() automatically converts it to a File?

Great!

Basically, Dialogs.promptForDirectory() returns a File, as defined here. On the other hand, buildFilePath() returns a (path) String (which is taken from the File object), as defined here.

It just turns out that the toString() method for your File object (that you get from promptForDirectory()) returns its String path, and buildFilePath() also returns the String path, so basically they wouldn’t look different because they represent the same thing, the String file path.

2 Likes

Once again, thank you so much for taking the time to explain it!

1 Like