Bael 7201 (#15792)
* BAEL-7201: Maven compilation example * BAEL-7201: Disable the tests * BAEL-7201: Created MavenAdapter and moved repeated code * BAEL-7201: Project creation and tests * BAEL-7201: A couple of renames and refactors * BAEL-7201: Extract constants * BAEL-7201: Cleaned the POM * BAEL-7201: Remove unnecessary access modifiers
This commit is contained in:
parent
772649421b
commit
9d23ecb95b
|
@ -8,6 +8,36 @@
|
|||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>maven-exec-plugin</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.shared</groupId>
|
||||
<artifactId>maven-invoker</artifactId>
|
||||
<version>${apache.maven.invoker.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-embedder</artifactId>
|
||||
<version>${apache.maven.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit.jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
@ -38,6 +68,9 @@
|
|||
<properties>
|
||||
<maven-compiler-plugin.version>3.12.1</maven-compiler-plugin.version>
|
||||
<exec-maven-plugin.version>3.1.0</exec-maven-plugin.version>
|
||||
<junit.jupiter.version>5.10.0</junit.jupiter.version>
|
||||
<apache.maven.version>3.9.6</apache.maven.version>
|
||||
<apache.maven.invoker.version>3.2.0</apache.maven.invoker.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.learningplatform;
|
||||
|
||||
public enum JavaVersion {
|
||||
|
||||
JAVA_8("1.8"), JAVA_9("9"), JAVA_17("17");
|
||||
|
||||
private final String version;
|
||||
|
||||
|
||||
JavaVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.learningplatform;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public interface Maven {
|
||||
String POM_XML = "pom.xml";
|
||||
String COMPILE_GOAL = "compile";
|
||||
String USE_CUSTOM_POM = "-f";
|
||||
int OK = 0;
|
||||
String MVN = "mvn";
|
||||
|
||||
void compile(Path projectFolder);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.learningplatform;
|
||||
|
||||
public class MavenCompilationException extends RuntimeException {
|
||||
|
||||
public MavenCompilationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public MavenCompilationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.baeldung.learningplatform;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import org.apache.maven.cli.MavenCli;
|
||||
|
||||
public class MavenEmbedder implements Maven {
|
||||
|
||||
public static final String MVN_HOME = "maven.multiModuleProjectDirectory";
|
||||
|
||||
@Override
|
||||
public void compile(Path projectFolder) {
|
||||
MavenCli cli = new MavenCli();
|
||||
System.setProperty(MVN_HOME, projectFolder.toString());
|
||||
cli.doMain(new String[]{COMPILE_GOAL}, projectFolder.toString(), null, null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.baeldung.learningplatform;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public abstract class MavenExecutorAdapter implements Maven {
|
||||
|
||||
@Override
|
||||
public void compile(Path projectFolder) {
|
||||
int exitCode;
|
||||
try {
|
||||
exitCode = execute(projectFolder, COMPILE_GOAL);
|
||||
} catch (InterruptedException e) {
|
||||
throw new MavenCompilationException("Interrupted during compilation", e);
|
||||
} catch (IOException e) {
|
||||
throw new MavenCompilationException("Incorrect execution", e);
|
||||
}
|
||||
if (exitCode != OK) {
|
||||
throw new MavenCompilationException("Failure during compilation: " + exitCode);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract int execute(Path projectFolder, String compileGoal)
|
||||
throws InterruptedException, IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.baeldung.learningplatform;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import org.apache.maven.shared.invoker.DefaultInvocationRequest;
|
||||
import org.apache.maven.shared.invoker.DefaultInvoker;
|
||||
import org.apache.maven.shared.invoker.InvocationRequest;
|
||||
import org.apache.maven.shared.invoker.InvocationResult;
|
||||
import org.apache.maven.shared.invoker.Invoker;
|
||||
import org.apache.maven.shared.invoker.MavenInvocationException;
|
||||
|
||||
public class MavenInvoker implements Maven {
|
||||
|
||||
@Override
|
||||
public void compile(Path projectFolder) {
|
||||
InvocationRequest request = new DefaultInvocationRequest();
|
||||
request.setPomFile(projectFolder.resolve(POM_XML).toFile());
|
||||
request.setGoals(Collections.singletonList(Maven.COMPILE_GOAL));
|
||||
Invoker invoker = new DefaultInvoker();
|
||||
try {
|
||||
InvocationResult result = invoker.execute(request);
|
||||
if (result.getExitCode() != 0) {
|
||||
throw new MavenCompilationException("Build failed", result.getExecutionException());
|
||||
}
|
||||
} catch (MavenInvocationException e) {
|
||||
throw new MavenCompilationException("Exception during Maven invocation", e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.learningplatform;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class MavenProcessBuilder extends MavenExecutorAdapter {
|
||||
private static final ProcessBuilder PROCESS_BUILDER = new ProcessBuilder();
|
||||
|
||||
protected int execute(Path projectFolder, String compileGoal) throws IOException, InterruptedException {
|
||||
Process process = PROCESS_BUILDER
|
||||
.command(MVN, USE_CUSTOM_POM, projectFolder.resolve(POM_XML).toString(), compileGoal)
|
||||
.start();
|
||||
return process.waitFor();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.learningplatform;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class MavenRuntimeExec extends MavenExecutorAdapter {
|
||||
@Override
|
||||
protected int execute(Path projectFolder, String compileGoal) throws InterruptedException, IOException {
|
||||
String[] arguments = {MVN, USE_CUSTOM_POM, projectFolder.resolve(POM_XML).toString(), COMPILE_GOAL};
|
||||
Process process = Runtime.getRuntime().exec(arguments);
|
||||
return process.waitFor();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
package com.baeldung.learningplatform;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.maven.model.Build;
|
||||
import org.apache.maven.model.Dependency;
|
||||
import org.apache.maven.model.Model;
|
||||
import org.apache.maven.model.Plugin;
|
||||
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
|
||||
import org.codehaus.plexus.util.xml.Xpp3Dom;
|
||||
|
||||
public class ProjectBuilder {
|
||||
|
||||
private static final String PACKAGE = "package ";
|
||||
private static final String POM_XML = "pom.xml";
|
||||
private static final String SRC_TEST = "src/test/";
|
||||
private static final String SRC_MAIN_JAVA = "src/main/java/";
|
||||
private static final String PACKAGE_DELIMITER = ".";
|
||||
private static final String MAIN_JAVA = "Main.java";
|
||||
private final List<Dependency> dependencies = new ArrayList<>();
|
||||
private JavaVersion javaVersion = JavaVersion.JAVA_8;
|
||||
|
||||
public ProjectBuilder addDependency(String groupId, String artifactId, String version) {
|
||||
Dependency dependency = new Dependency();
|
||||
dependency.setGroupId(groupId);
|
||||
dependency.setArtifactId(artifactId);
|
||||
dependency.setVersion(version);
|
||||
dependencies.add(dependency);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProjectBuilder setJavaVersion(JavaVersion version) {
|
||||
this.javaVersion = version;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void build(String userName, Path projectPath, String packageName) throws IOException {
|
||||
Model model = new Model();
|
||||
configureModel(userName, model);
|
||||
dependencies.forEach(model::addDependency);
|
||||
Build build = configureJavaVersion();
|
||||
model.setBuild(build);
|
||||
MavenXpp3Writer writer = new MavenXpp3Writer();
|
||||
writer.write(new FileWriter(projectPath.resolve(POM_XML).toFile()), model);
|
||||
generateFolders(projectPath, SRC_TEST);
|
||||
|
||||
Path generatedPackage = generateFolders(projectPath,
|
||||
SRC_MAIN_JAVA +
|
||||
packageName.replace(PACKAGE_DELIMITER, FileSystems.getDefault().getSeparator()));
|
||||
String generatedClass = generateMainClass(PACKAGE + packageName);
|
||||
Files.writeString(generatedPackage.resolve(MAIN_JAVA), generatedClass);
|
||||
}
|
||||
|
||||
private static void configureModel(String userName, Model model) {
|
||||
model.setModelVersion("4.0.0");
|
||||
model.setArtifactId("com." + userName.toLowerCase());
|
||||
model.setGroupId("learning-project");
|
||||
model.setVersion("0.0.1-SNAPSHOT");
|
||||
}
|
||||
|
||||
private static String generateMainClass(String packageName) {
|
||||
return packageName + ";\n" +
|
||||
"\n" +
|
||||
"public class Main {\n" +
|
||||
" public static void main(String[] args){\n" +
|
||||
" System.out.println(\"Hello World!\");\n" +
|
||||
" }\n" +
|
||||
"}\n";
|
||||
}
|
||||
|
||||
private static Path generateFolders(Path sourceFolder, String packageName) throws IOException {
|
||||
return Files.createDirectories(sourceFolder.resolve(packageName));
|
||||
}
|
||||
|
||||
private Build configureJavaVersion() {
|
||||
Plugin plugin = new Plugin();
|
||||
plugin.setGroupId("org.apache.maven.plugins");
|
||||
plugin.setArtifactId("maven-compiler-plugin");
|
||||
plugin.setVersion("3.8.1");
|
||||
|
||||
Xpp3Dom configuration = new Xpp3Dom("configuration");
|
||||
Xpp3Dom source = new Xpp3Dom("source");
|
||||
source.setValue(javaVersion.getVersion());
|
||||
Xpp3Dom target = new Xpp3Dom("target");
|
||||
target.setValue(javaVersion.getVersion());
|
||||
configuration.addChild(source);
|
||||
configuration.addChild(target);
|
||||
|
||||
plugin.setConfiguration(configuration);
|
||||
|
||||
Build build = new Build();
|
||||
build.addPlugin(plugin);
|
||||
return build;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.baeldung.learningplatform;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
|
||||
public class FileUtil {
|
||||
|
||||
private FileUtil() {
|
||||
}
|
||||
|
||||
public static void removeDirectoryRecursively(Path folder) throws IOException {
|
||||
if (Files.exists(folder)) {
|
||||
Files.walkFileTree(folder, new SimpleFileVisitor<>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
Files.delete(file);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
||||
Files.delete(dir);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.baeldung.learningplatform;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
class MavenRuntimeExecUnitTest {
|
||||
|
||||
private static final String PACKAGE_NAME = "com.baeldung.generatedcode";
|
||||
private static final String USER_NAME = "john_doe";
|
||||
@TempDir
|
||||
private Path tempDir;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws IOException {
|
||||
ProjectBuilder projectBuilder = new ProjectBuilder();
|
||||
projectBuilder.build(USER_NAME, tempDir, PACKAGE_NAME);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource
|
||||
void givenMavenInterface_whenCompileMavenProject_thenCreateTargetDirectory(Maven maven) {
|
||||
maven.compile(tempDir);
|
||||
assertTrue(Files.exists(tempDir));
|
||||
}
|
||||
|
||||
static Stream<Maven> givenMavenInterface_whenCompileMavenProject_thenCreateTargetDirectory() {
|
||||
return Stream.of(
|
||||
new MavenRuntimeExec(),
|
||||
new MavenProcessBuilder(),
|
||||
new MavenEmbedder(),
|
||||
new MavenInvoker());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package com.baeldung.learningplatform;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public interface ProjectsPaths {
|
||||
|
||||
public static final Path PROJECT_DIR = Paths.get("src/test/resources/learning-project/");
|
||||
public static final Path PROJECT_POM_XML = PROJECT_DIR.resolve("pom.xml");
|
||||
public static final Path PROJECT_TARGET = PROJECT_DIR.resolve("target");
|
||||
}
|
Loading…
Reference in New Issue