Kotlinc: catch FileNotFoundException caused by problematic destination.
This commit is contained in:
committed by
Alexander Udalov
parent
149282a888
commit
28452fc38e
@@ -23,13 +23,24 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
|
||||
fun OutputFileCollection.writeAll(outputDir: File, report: ((file: OutputFile, sources: List<File>, output: File) -> Unit)?) {
|
||||
for (file in asList()) {
|
||||
val sources = file.sourceFiles
|
||||
val output = File(outputDir, file.relativePath)
|
||||
report?.invoke(file, sources, output)
|
||||
FileUtil.writeToFile(output, file.asByteArray())
|
||||
try {
|
||||
FileUtil.writeToFile(output, file.asByteArray())
|
||||
} catch (e: FileNotFoundException) {
|
||||
if (outputDir.isDirectory) {
|
||||
// output directory exists
|
||||
throw NoPermissionException("error while writing $output (Permission denied)", e)
|
||||
}
|
||||
// Failed to create directory, possibly due to lack of write permission or clash with existing file.
|
||||
// In both cases, the directory will not exist, so for the sake of simplicity, we treat them same way.
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,8 +49,16 @@ fun OutputFileCollection.writeAllTo(outputDir: File) {
|
||||
}
|
||||
|
||||
fun OutputFileCollection.writeAll(outputDir: File, messageCollector: MessageCollector, reportOutputFiles: Boolean) {
|
||||
if (!reportOutputFiles) writeAllTo(outputDir)
|
||||
else writeAll(outputDir) { _, sources, output ->
|
||||
messageCollector.report(CompilerMessageSeverity.OUTPUT, OutputMessageUtil.formatOutputMessage(sources, output))
|
||||
try {
|
||||
if (!reportOutputFiles) writeAllTo(outputDir)
|
||||
else writeAll(outputDir) { _, sources, output ->
|
||||
messageCollector.report(CompilerMessageSeverity.OUTPUT, OutputMessageUtil.formatOutputMessage(sources, output))
|
||||
}
|
||||
} catch (e: NoPermissionException) {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, e.message!!)
|
||||
} catch (e: FileNotFoundException) {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "directory not found: $outputDir")
|
||||
}
|
||||
}
|
||||
|
||||
private class NoPermissionException(message: String, cause: Throwable?) : IllegalStateException(message, cause)
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFile;
|
||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity;
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector;
|
||||
import org.jetbrains.kotlin.cli.common.modules.ModuleChunk;
|
||||
import org.jetbrains.kotlin.cli.common.modules.ModuleXmlParser;
|
||||
@@ -104,16 +105,24 @@ public class CompileEnvironmentUtil {
|
||||
}
|
||||
|
||||
public static void writeToJar(
|
||||
File jarPath, boolean jarRuntime, boolean noReflect, boolean resetJarTimestamps, FqName mainClass, OutputFileCollection outputFiles
|
||||
File jarPath,
|
||||
boolean jarRuntime,
|
||||
boolean noReflect,
|
||||
boolean resetJarTimestamps,
|
||||
FqName mainClass,
|
||||
OutputFileCollection outputFiles,
|
||||
MessageCollector messageCollector
|
||||
) {
|
||||
FileOutputStream outputStream = null;
|
||||
try {
|
||||
// we should try to create the output dir first
|
||||
jarPath.getParentFile().mkdirs();
|
||||
outputStream = new FileOutputStream(jarPath);
|
||||
doWriteToJar(outputFiles, outputStream, mainClass, jarRuntime, noReflect, resetJarTimestamps);
|
||||
outputStream.close();
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
throw new CompileEnvironmentException("Invalid jar path " + jarPath, e);
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "Invalid jar path: " + jarPath, null);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw ExceptionUtilsKt.rethrow(e);
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ object KotlinToJVMBytecodeCompiler {
|
||||
val includeRuntime = configuration.get(JVMConfigurationKeys.INCLUDE_RUNTIME, false)
|
||||
val noReflect = configuration.get(JVMConfigurationKeys.NO_REFLECT, false)
|
||||
val resetJarTimestamps = !configuration.get(JVMConfigurationKeys.NO_RESET_JAR_TIMESTAMPS, false)
|
||||
CompileEnvironmentUtil.writeToJar(jarPath, includeRuntime, noReflect, resetJarTimestamps, mainClassFqName, outputFiles)
|
||||
CompileEnvironmentUtil.writeToJar(jarPath, includeRuntime, noReflect, resetJarTimestamps, mainClassFqName, outputFiles, messageCollector)
|
||||
if (reportOutputFiles) {
|
||||
val message = OutputMessageUtil.formatOutputMessage(outputFiles.asList().flatMap { it.sourceFiles }.distinct(), jarPath)
|
||||
messageCollector.report(OUTPUT, message)
|
||||
|
||||
Reference in New Issue
Block a user