Java controller to farm out concurrent tasks
Hints

I would have named the generic types properly.

Maybe I would have divided Logging from processing with help of a listener pattern.

I would have expected the input parameter to never be null, so returning null is obsolete.

I would have extracted some methods to have parts of code be named.

Code

On a very high level view I would have expected exactly what you described what the code should do. Splitting an input in parts, processing these parts in parallel, collect the results and aggregate them. This should have been expressed in the "process"-method.

public class Controller&lt;INPUT, RESULT, PARTIALINPUT, PARTIALRESULT&gt; {

    ...

    public RESULT process(INPUT input) {

        PARTIALINPUT[] partialInputArray = preprocessor.split(input);

        List&lt;Future&lt;PARTIALRESULT&gt;&gt; partialResultFutures = processAsynchronously(partialInputArray);
        List&lt;PARTIALRESULT&gt; partialResults = collectPartialResults(partialResultFutures);

        RESULT result = postprocessor.aggregate(partialResults);

        return result;
    }

    private List&lt;PARTIALRESULT&gt; collectPartialResults(List&lt;Future&lt;PARTIALRESULT&gt;&gt; partialResultFutures)
            throws InterruptedException, ExecutionException {

        List&lt;PARTIALRESULT&gt; partialResults = new ArrayList&lt;&gt;();

        for (Future&lt;PARTIALRESULT&gt; future : partialResultFutures) {
            partialResults.add(future.get());
        }

        return partialResults;
    }

    private List&lt;Future&lt;PARTIALRESULT&gt;&gt; processAsynchronously(PARTIALINPUT[] partialInputArray) {

        List&lt;Future&lt;PARTIALRESULT&gt;&gt; partialResultFutures = new ArrayList&lt;&gt;();

        for (PARTIALINPUT partialinput : partialInputArray) {
            Future&lt;PARTIALRESULT&gt; future = processAsyncronously(partialInput);
            partialResultFutures.add(future);
        }

        return partialResultFutures;
    }

    ...

}