How to override @OutputDirectory annotation?

I have written a custom task that extends from Copy task. But my task has only a single output file instead of an output directory. The copy is only for temporary files. That I have override the method getDestinationDir() to override the annotation @OutputDirectory. But it have no effect. Because the annotation does not implements @Inherited this should be work. This sound like a bug.

Are there any workarounds to remove the output directory and ignoring the annotation?

public class MyTask extends Copy {
    @Override
    public File getDestinationDir() {
        return super.getDestinationDir();
    }
    @OutputFile
    public File getOutputFile() {
        return new File( ... );
    }

}

In this instance it might make more sense for your task to use Project.copy() rather than extend the Copy task since the Copy tasks’s inputs and outputs don’t accurately model your task’s implementation.

I extends from the copy task because I want declare the source files like a copy task. If I does not extends from the copy task then I need to duplicate the completely features of the task in my plugin. This make no sense for me.

One option would be to add a method to your task that configures a CopySpec, kind of how the War task does with webinf. The user would then interact with your task something like this:

myTask {
    source {
        from 'src/mysource'
    }
}

The War task extends from the AbstractCopy task to prevent duplicate code. Of course I can do it the same. But then I must duplicate all the other stuff from the Copy task. This was many internal code. I am not sure if this will work with future versions.

From what I gather from your original post is that you want certina features from the Copy task’s DSL, but that it is only to be used for copying a group of potenitally temporary files, but the final output of the task is just as single file. I assume that you want to do some intermediate processing on the temporary files, before producing the final file.

To be this sounds like inherting from Copy is the wrong thing to do as the configuration you’ll be representing if you task closure will be semantically misleading. Therefore I’ll concur with @mark_vieira on this. You are better to create a task that dervies from DefaultTask and then use a method that represents hat needs to be copied as temporary files.

The resources block in the asciidoctor-gradle-plugin is a good example of how to add a CopySpec to a task.

I now extends from org.gradle.api.tasks.AbstractCopyTask and copy the follow code from the Copy task and all work as expected. Thanks for all the suggestions.

@Override
protected CopyAction createCopyAction() {
    File destinationDir = getDestinationDir();
    if (destinationDir == null) {
        throw new InvalidUserDataException("No copy destination directory has been specified, use 'into' to specify a target directory.");
    }
    return new FileCopyAction(getFileLookup().getFileResolver(destinationDir));
}

@Override
protected CopySpecInternal createRootSpec() {
    Instantiator instantiator = getInstantiator();
    FileResolver fileResolver = getFileResolver();

    return instantiator.newInstance(DestinationRootCopySpec.class, fileResolver, super.createRootSpec());
}

public File getDestinationDir() {
    return ((DestinationRootCopySpec)getRootSpec()).getDestinationDir();
}