I've created a utility that combines zip file archives into a single archive. In doing so, I originally had the following method (see this question for some background on ExceptionWrapper
):
private void addFile(File f, final ZipOutputStream out, final Set<String> entryNames){
ZipFile source = getZipFileFromFile(f);
source.stream().forEach(ExceptionWrapper.wrapConsumer(e -> addEntryContent(out, source, e, entryNames)));
}
Here is the code for ExceptionWrapper.wrapConsumer
and ConsumerWrapper
public static <T> Consumer<T> wrapConsumer(ConsumerWrapper<T> consumer){
return t -> {
try {
consumer.accept(t);
} catch (Exception e) {
throw new IllegalStateException(e);
}
};
}
public interface ConsumerWrapper<T>{
void accept(T t) throws Exception;
}
This results in the compilation errors:
Error:(128, 62) java: incompatible types: java.util.function.Consumer<capture#1 of ? extends java.util.zip.ZipEntry> cannot be converted to java.util.function.Consumer<? super capture#1 of ? extends java.util.zip.ZipEntry> Error:(128, 97) java: incompatible types: java.lang.Object cannot be converted to java.util.zip.ZipEntry
However, the following change compiles just fine and works as expected:
private void addFile(File f, final ZipOutputStream out, final Set<String> entryNames){
ZipFile source = getZipFileFromFile(f);
Consumer<ZipEntry> consumer = ExceptionWrapper.wrapConsumer(e -> addEntryContent(out, source, e, entryNames));
source.stream().forEach(consumer);
}
Notice that all I did was pull out the in-lined creation of the Consumer
into a separate variable. Any spec experts know what changes for the compiler when the Consumer
is in-lined?
EDIT: As requested, this is the signature of addEntryContent(...)
:
private void addEntryContent(final ZipOutputStream out,
final ZipFile source,
final ZipEntry entry,
final Set<String> entryNames) throws IOException {