diff --git a/libraries/tools/kotlin-maven-plugin/pom.xml b/libraries/tools/kotlin-maven-plugin/pom.xml
index d89bd2fe19f..ccf40c08717 100644
--- a/libraries/tools/kotlin-maven-plugin/pom.xml
+++ b/libraries/tools/kotlin-maven-plugin/pom.xml
@@ -46,6 +46,17 @@
2.4.4
test
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.5.1
+
+
+ org.apache.maven.plugin-testing
+ maven-plugin-testing-harness
+ 3.3.0
+ test
+
diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompilationFailureException.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompilationFailureException.java
new file mode 100644
index 00000000000..f74ba8ec0d2
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompilationFailureException.java
@@ -0,0 +1,22 @@
+package org.jetbrains.kotlin.maven;
+
+import org.apache.maven.plugin.compiler.CompilationFailureException;
+import org.codehaus.plexus.compiler.CompilerMessage;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+
+public class KotlinCompilationFailureException extends CompilationFailureException {
+ private List compilerMessages;
+
+ public KotlinCompilationFailureException(@NotNull List compilerMessages) {
+ super(compilerMessages);
+ this.compilerMessages = Collections.unmodifiableList(compilerMessages);
+ }
+
+ public List getCompilerMessages() {
+ return compilerMessages;
+ }
+}
+
diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java
index fb42191f8e1..f77427a5317 100644
--- a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java
+++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.cli.common.CLICompiler;
import org.jetbrains.kotlin.cli.common.ExitCode;
import org.jetbrains.kotlin.cli.common.KotlinVersion;
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments;
-import org.jetbrains.kotlin.cli.common.messages.MessageCollector;
import org.jetbrains.kotlin.config.Services;
import java.io.File;
@@ -133,16 +132,12 @@ public abstract class KotlinCompileMojoBase e
configureCompilerArguments(arguments, compiler);
printCompilerArgumentsIfDebugEnabled(arguments, compiler);
- MessageCollector messageCollector = new MavenPluginLogMessageCollector(getLog());
+ MavenPluginLogMessageCollector messageCollector = new MavenPluginLogMessageCollector(getLog());
ExitCode exitCode = compiler.exec(messageCollector, Services.EMPTY, arguments);
- switch (exitCode) {
- case COMPILATION_ERROR:
- throw new MojoExecutionException("Compilation error. See log for more details");
- case INTERNAL_ERROR:
- throw new MojoExecutionException("Internal compiler error. See log for more details");
- default:
+ if (exitCode != ExitCode.OK) {
+ messageCollector.throwKotlinCompilerException();
}
}
diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/MavenPluginLogMessageCollector.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/MavenPluginLogMessageCollector.java
index 6a7a5078c02..8304175aab4 100644
--- a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/MavenPluginLogMessageCollector.java
+++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/MavenPluginLogMessageCollector.java
@@ -16,23 +16,38 @@
package org.jetbrains.kotlin.maven;
+import com.intellij.openapi.util.Pair;
+import kotlin.collections.CollectionsKt;
+import kotlin.jvm.functions.Function1;
import org.apache.maven.plugin.logging.Log;
+import org.codehaus.plexus.compiler.CompilerMessage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation;
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity;
import org.jetbrains.kotlin.cli.common.messages.MessageCollector;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
public class MavenPluginLogMessageCollector implements MessageCollector {
private final Log log;
- private boolean hasErrors = false;
+ private final ArrayList> collectedErrors = new ArrayList>();
public MavenPluginLogMessageCollector(Log log) {
- this.log = log;
+ this.log = checkNotNull(log, "log shouldn't be null");
}
@Override
public boolean hasErrors() {
- return hasErrors;
+ return !collectedErrors.isEmpty();
+ }
+
+ @NotNull
+ public List> getCollectedErrors() {
+ return Collections.unmodifiableList(collectedErrors);
}
@Override
@@ -45,7 +60,7 @@ public class MavenPluginLogMessageCollector implements MessageCollector {
if (CompilerMessageSeverity.VERBOSE.contains(severity)) {
log.debug(text);
} else if (CompilerMessageSeverity.ERRORS.contains(severity)) {
- hasErrors = true;
+ collectedErrors.add(new Pair(location, message));
log.error(text);
} else if (severity == CompilerMessageSeverity.INFO) {
log.info(text);
@@ -53,4 +68,35 @@ public class MavenPluginLogMessageCollector implements MessageCollector {
log.warn(text);
}
}
+
+ public void throwKotlinCompilerException() throws KotlinCompilationFailureException {
+ throw new KotlinCompilationFailureException(
+ CollectionsKt.map(getCollectedErrors(), new Function1, CompilerMessage>() {
+ @Override
+ public CompilerMessage invoke(Pair pair) {
+ CompilerMessageLocation location = pair.getFirst();
+ String message = pair.getSecond();
+ String lineContent = location.getLineContent();
+ int lineContentLength = lineContent == null ? 0 : lineContent.length();
+
+ return new CompilerMessage(
+ location.getPath(),
+ CompilerMessage.Kind.ERROR,
+ fixLocation(location.getLine()),
+ fixLocation(location.getColumn()),
+ fixLocation(location.getLine()),
+ Math.min(fixLocation(location.getColumn()), lineContentLength),
+ message
+ );
+ }
+ })
+ );
+ }
+
+ private static int fixLocation(int n) {
+ if (n < 0) {
+ return 0;
+ }
+ return n;
+ }
}
diff --git a/libraries/tools/kotlin-maven-plugin/src/test/java/org/jetbrains/kotlin/maven/KotlinCompilationFailureExceptionTest.java b/libraries/tools/kotlin-maven-plugin/src/test/java/org/jetbrains/kotlin/maven/KotlinCompilationFailureExceptionTest.java
new file mode 100644
index 00000000000..252577d593b
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin/src/test/java/org/jetbrains/kotlin/maven/KotlinCompilationFailureExceptionTest.java
@@ -0,0 +1,64 @@
+package org.jetbrains.kotlin.maven;
+
+import org.apache.maven.plugin.testing.SilentLog;
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation;
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+public class KotlinCompilationFailureExceptionTest {
+
+ @Test
+ public void testNoLocation() throws Exception {
+ MavenPluginLogMessageCollector collector = new MavenPluginLogMessageCollector(new SilentLog());
+ collector.report(CompilerMessageSeverity.ERROR, "Something went wrong", CompilerMessageLocation.NO_LOCATION);
+
+ try {
+ collector.throwKotlinCompilerException();
+ fail();
+ } catch (KotlinCompilationFailureException e) {
+ assertEquals("Something went wrong", e.getLongMessage().trim());
+ }
+ }
+
+ @Test
+ public void testLocationNoLineNoColumn() throws Exception {
+ MavenPluginLogMessageCollector collector = new MavenPluginLogMessageCollector(new SilentLog());
+ collector.report(CompilerMessageSeverity.ERROR, "Error in file", CompilerMessageLocation.create("myfile.txt", -1, -1, "nothing"));
+
+ try {
+ collector.throwKotlinCompilerException();
+ fail();
+ } catch (KotlinCompilationFailureException e) {
+ assertEquals("myfile.txt: Error in file", e.getLongMessage().trim());
+ }
+ }
+
+ @Test
+ public void testLocationNoColumn() throws Exception {
+ MavenPluginLogMessageCollector collector = new MavenPluginLogMessageCollector(new SilentLog());
+ collector.report(CompilerMessageSeverity.ERROR, "Error in file", CompilerMessageLocation.create("myfile.txt", 777, -1, "nothing"));
+
+ try {
+ collector.throwKotlinCompilerException();
+ fail();
+ } catch (KotlinCompilationFailureException e) {
+ assertEquals("myfile.txt:[777] Error in file", e.getLongMessage().trim());
+ }
+ }
+
+ @Test
+ public void testLocationWithLocation() throws Exception {
+ MavenPluginLogMessageCollector collector = new MavenPluginLogMessageCollector(new SilentLog());
+ collector.report(CompilerMessageSeverity.ERROR, "Error in file", CompilerMessageLocation.create("myfile.txt", 777, 9, "nothing"));
+
+ try {
+ collector.throwKotlinCompilerException();
+ fail();
+ } catch (KotlinCompilationFailureException e) {
+ assertEquals("myfile.txt:[777,9] Error in file", e.getLongMessage().trim());
+ }
+ }
+}