Copy errors out with copyspecwrapper error

@TaskAction
void buildShell(){
    project.with {
        def bOut = file("$buildDir/shell")
        def lOut = file("$buildDir/shell/lib")

        sourceSets.main.java.srcDirs.each{
            println it.getClass().name
            println bOut.getClass().name
            project.copy {
                into bOut
                from it
            }
        }

        copy {
            into lOut
            from configurations.runtime
        }
    }
}

generates

$ ./gradlew clean build --stacktrace
:clean
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:writeManifestProperties
:jar SKIPPED
:assemble UP-TO-DATE
:buildShell
java.io.File
java.io.File
:buildShell FAILED
:lintGradle

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':buildShell'.
> Cannot convert the provided notation to a File or URI: org.gradle.api.internal.file.copy.CopySpecWrapper_Decorated@18336e4.
  The following types/formats are supported:
    - A String or CharSequence path, for example 'src/main/java' or '/usr/include'.
    - A String or CharSequence URI, for example 'file:/usr/include'.
    - A File instance.
    - A URI or URL instance.

* Try:
Run with --info or --debug option to get more log output.

As you can see, both the in and out objects are being printed out as java.io.file objects. The second copy command works perfectly fine, but the first one keeps giving me this error. I have tried everything i know how to do, anyone see why this keeps blowing up?

I think Gradle tries to resolve it from the Closure passed to the copy method and can’t resolve it. You can still make this work by explicitly naming the iteration variable.

sourceSets.main.java.srcDirs.each { myFile ->
    project.copy {
        into project.file("$buildDir/shell")
        from myFile
    }
}

The more concise way would look like this:

project.copy {
     into file("$buildDir/shell")
     from sourceSets.main.java.srcDirs
}