From 0ea80c2e194e2247257699db44b531c1c2b7d6cb Mon Sep 17 00:00:00 2001 From: Eric Lau Date: Mon, 19 Jul 2021 15:07:38 -0400 Subject: [PATCH] Purge locally installed upstream modules when using loose app (#1207) * Purge module from local repo before build * Add ITs for upstream installed module * Run dependency plugin for current project --- .../src/it/dev-it/.vscode/launch.json | 15 ++++ .../wasdev/wlp/test/dev/it/BaseDevTest.java | 44 +++++++---- .../wlp/test/dev/it/BaseMultiModuleTest.java | 15 ++++ .../dev/it/MultiModuleM2InstalledTest.java | 74 +++++++++++++++++++ .../dev/it/MultiModuleRunM2InstalledTest.java | 74 +++++++++++++++++++ .../tools/maven/server/DevMojo.java | 2 + .../tools/maven/server/RunServerMojo.java | 4 + .../maven/server/StartDebugMojoSupport.java | 26 ++++++- 8 files changed, 236 insertions(+), 18 deletions(-) create mode 100644 liberty-maven-plugin/src/it/dev-it/.vscode/launch.json create mode 100644 liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/MultiModuleM2InstalledTest.java create mode 100644 liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/MultiModuleRunM2InstalledTest.java diff --git a/liberty-maven-plugin/src/it/dev-it/.vscode/launch.json b/liberty-maven-plugin/src/it/dev-it/.vscode/launch.json new file mode 100644 index 000000000..e593e700b --- /dev/null +++ b/liberty-maven-plugin/src/it/dev-it/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "java", + "name": "Attach", + "request": "attach", + "hostName": "localhost", + "port": 8000 + } + ] +} \ No newline at end of file diff --git a/liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/BaseDevTest.java b/liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/BaseDevTest.java index db081dcdf..ba8858ee0 100644 --- a/liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/BaseDevTest.java +++ b/liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/BaseDevTest.java @@ -127,6 +127,10 @@ protected static void startProcess(String params, boolean isDevMode) throws IOEx } protected static void startProcess(String params, boolean isDevMode, String mavenPluginCommand) throws IOException, InterruptedException, FileNotFoundException { + startProcess(params, isDevMode, mavenPluginCommand, true); + } + + protected static void startProcess(String params, boolean isDevMode, String mavenPluginCommand, boolean verifyServerStart) throws IOException, InterruptedException, FileNotFoundException { // run dev mode on project String goal; if(isDevMode) { @@ -153,20 +157,22 @@ protected static void startProcess(String params, boolean isDevMode, String mave writer = new BufferedWriter(new OutputStreamWriter(stdin)); - // check that the server has started - Thread.sleep(5000); - assertTrue(getLogTail(), verifyLogMessageExists("CWWKF0011I", 120000)); - if (isDevMode) { - assertTrue(verifyLogMessageExists("Liberty is running in dev mode.", 60000)); - } + if (verifyServerStart) { + // check that the server has started + Thread.sleep(5000); + assertTrue(getLogTail(), verifyLogMessageExists("CWWKF0011I", 120000)); + if (isDevMode) { + assertTrue(verifyLogMessageExists("Liberty is running in dev mode.", 60000)); + } - // verify that the target directory was created - if (customLibertyModule == null) { - targetDir = new File(tempProj, "target"); - } else { - targetDir = new File(new File(tempProj, customLibertyModule), "target"); + // verify that the target directory was created + if (customLibertyModule == null) { + targetDir = new File(tempProj, "target"); + } else { + targetDir = new File(new File(tempProj, customLibertyModule), "target"); + } + assertTrue(targetDir.exists()); } - assertTrue(targetDir.exists()); } protected static String getLogTail() throws IOException { @@ -207,7 +213,11 @@ protected static void cleanUpAfterClass() throws Exception { } protected static void cleanUpAfterClass(boolean isDevMode) throws Exception { - stopProcess(isDevMode); + cleanUpAfterClass(isDevMode, true); + } + + protected static void cleanUpAfterClass(boolean isDevMode, boolean checkForShutdownMessage) throws Exception { + stopProcess(isDevMode, checkForShutdownMessage); if (tempProj != null && tempProj.exists()) { FileUtils.deleteDirectory(tempProj); @@ -225,7 +235,7 @@ protected static void clearLogFile() throws Exception { } } - private static void stopProcess(boolean isDevMode) throws IOException, InterruptedException, FileNotFoundException, IllegalThreadStateException { + private static void stopProcess(boolean isDevMode, boolean checkForShutdownMessage) throws IOException, InterruptedException, FileNotFoundException, IllegalThreadStateException { // shut down dev mode if (writer != null) { if(isDevMode) { @@ -240,8 +250,10 @@ private static void stopProcess(boolean isDevMode) throws IOException, Interrupt process.waitFor(120, TimeUnit.SECONDS); process.exitValue(); - // test that dev mode has stopped running - assertTrue(verifyLogMessageExists("CWWKE0036I", 20000)); + // test that the server has shut down + if (checkForShutdownMessage) { + assertTrue(verifyLogMessageExists("CWWKE0036I", 20000)); + } } } diff --git a/liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/BaseMultiModuleTest.java b/liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/BaseMultiModuleTest.java index 3b9688ba9..6a880388c 100644 --- a/liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/BaseMultiModuleTest.java +++ b/liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/BaseMultiModuleTest.java @@ -171,6 +171,21 @@ protected static File getTargetFileForModule(String srcFilePath, String targetFi return targetClass; } + protected static void runCommand(String commandLineString) throws Exception { + StringBuilder command = new StringBuilder(commandLineString); + ProcessBuilder builder = buildProcess(command.toString()); + + builder.redirectOutput(logFile); + builder.redirectError(logFile); + if (customPomModule != null) { + builder.directory(new File(tempProj, customPomModule)); + } + Process process = builder.start(); + assertTrue(process.isAlive()); + process.waitFor(120, TimeUnit.SECONDS); + assertEquals(0, process.exitValue()); + } + protected static void modifyFileForModule(String srcFilePath, String str, String replacement) throws IOException { File srcClass = new File(tempProj, srcFilePath); assertTrue(srcClass.exists()); diff --git a/liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/MultiModuleM2InstalledTest.java b/liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/MultiModuleM2InstalledTest.java new file mode 100644 index 000000000..846acc825 --- /dev/null +++ b/liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/MultiModuleM2InstalledTest.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * (c) Copyright IBM Corporation 2021. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ +package net.wasdev.wlp.test.dev.it; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; + +import org.apache.maven.shared.utils.io.FileUtils; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class MultiModuleM2InstalledTest extends BaseMultiModuleTest { + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + setUpMultiModule("typeA", "ear", null); + } + + @Test + public void purgeLocallyInstalledModule_DevMode_Test() throws Exception { + + // install everything to m2 + runCommand("mvn install"); + + // ensure class was compiled + File targetClass = new File(tempProj, "jar/target/classes/io/openliberty/guides/multimodules/lib/Converter.class"); + assertTrue(targetClass.exists()); + + // delete the source file + File srcClass = new File(tempProj, "jar/src/main/java/io/openliberty/guides/multimodules/lib/Converter.java"); + assertTrue(srcClass.delete()); + + // clean targets + runCommand("mvn clean"); + + // dev mode should purge the jar module from m2, so that the war module will show a failure due to the missing dependency. + // i.e. it should not find the jar dependency from m2 + startProcess(null, true, "mvn io.openliberty.tools:liberty-maven-plugin:"+System.getProperty("mavenPluginVersion")+":", false); + + // TODO when https://github.com/OpenLiberty/ci.maven/issues/1203 is fixed, check for compilation error instead + assertTrue(getLogTail(logFile), verifyLogMessageExists("Could not resolve dependencies for project", 5000)); + + assertFalse(getLogTail(logFile), targetClass.exists()); + } + + @AfterClass + public static void cleanUpAfterClass() throws Exception { + // use a run-style cleanup (e.g. kill the process), and skip checking for server + // shutdown since dev mode should not have fully started + BaseDevTest.cleanUpAfterClass(false, false); + } + +} + diff --git a/liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/MultiModuleRunM2InstalledTest.java b/liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/MultiModuleRunM2InstalledTest.java new file mode 100644 index 000000000..5038ba8d0 --- /dev/null +++ b/liberty-maven-plugin/src/it/dev-it/src/test/java/net/wasdev/wlp/test/dev/it/MultiModuleRunM2InstalledTest.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * (c) Copyright IBM Corporation 2021. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *******************************************************************************/ +package net.wasdev.wlp.test.dev.it; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; + +import org.apache.maven.shared.utils.io.FileUtils; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class MultiModuleRunM2InstalledTest extends BaseMultiModuleTest { + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + setUpMultiModule("typeA", "ear", null); + } + + @Test + public void purgeLocallyInstalledModule_LibertyRun_Test() throws Exception { + + // install everything to m2 + runCommand("mvn install"); + + // ensure class was compiled + File targetClass = new File(tempProj, "jar/target/classes/io/openliberty/guides/multimodules/lib/Converter.class"); + assertTrue(targetClass.exists()); + + // delete the source file + File srcClass = new File(tempProj, "jar/src/main/java/io/openliberty/guides/multimodules/lib/Converter.java"); + assertTrue(srcClass.delete()); + + // clean targets + runCommand("mvn clean"); + + // run goal should purge the jar module from m2, so that the war module will show a failure due to the missing dependency. + // i.e. it should not find the jar dependency from m2 + startProcess(null, false, "mvn io.openliberty.tools:liberty-maven-plugin:"+System.getProperty("mavenPluginVersion")+":", false); + + // TODO when https://github.com/OpenLiberty/ci.maven/issues/1203 is fixed, check for compilation error instead + assertTrue(getLogTail(logFile), verifyLogMessageExists("Could not resolve dependencies for project", 5000)); + + assertFalse(getLogTail(logFile), targetClass.exists()); + } + + @AfterClass + public static void cleanUpAfterClass() throws Exception { + // use a run-style cleanup (e.g. kill the process), and skip checking for server + // shutdown since server should not have fully started + BaseDevTest.cleanUpAfterClass(false, false); + } + +} + diff --git a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/DevMojo.java b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/DevMojo.java index cfb20f281..dcad5bdbf 100644 --- a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/DevMojo.java +++ b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/DevMojo.java @@ -817,6 +817,8 @@ protected void doExecute() throws Exception { } else if (project.getPackaging().equals("pom")) { log.debug("Skipping compile/resources on module with pom packaging type"); } else { + purgeLocalRepositoryArtifact(); + runMojo("org.apache.maven.plugins", "maven-resources-plugin", "resources"); runCompileMojoLogWarning(); } diff --git a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/RunServerMojo.java b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/RunServerMojo.java index 08e352b7e..b817fd96a 100644 --- a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/RunServerMojo.java +++ b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/RunServerMojo.java @@ -82,6 +82,10 @@ protected void doExecute() throws Exception { } else if (projectPackaging.equals("pom")) { log.debug("Skipping compile/resources on module with pom packaging type"); } else { + if (hasDownstreamProjects && looseApplication) { + purgeLocalRepositoryArtifact(); + } + runMojo("org.apache.maven.plugins", "maven-resources-plugin", "resources"); runMojo("org.apache.maven.plugins", "maven-compiler-plugin", "compile"); } diff --git a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/StartDebugMojoSupport.java b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/StartDebugMojoSupport.java index e07e2ea94..85721b193 100644 --- a/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/StartDebugMojoSupport.java +++ b/liberty-maven-plugin/src/main/java/io/openliberty/tools/maven/server/StartDebugMojoSupport.java @@ -31,8 +31,6 @@ import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; -import java.nio.file.Files; -import java.nio.file.Path; import java.text.MessageFormat; import java.util.ArrayList; import java.util.EnumSet; @@ -49,7 +47,9 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; +import org.apache.maven.Maven; import org.apache.maven.artifact.Artifact; +import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.ProjectDependencyGraph; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginManagement; @@ -964,6 +964,28 @@ private void installEmptyEAR(MavenProject earProject) throws MojoExecutionExcept } } + /** + * Purge the installed artifact for the current project from the local .m2 + * repository, so that any downstream modules (when using loose application) + * will not rely on the installed artifact for their compilation. + * + * @throws MojoExecutionException If an exception occurred while running + * dependency:purge-local-repository + */ + protected void purgeLocalRepositoryArtifact() throws MojoExecutionException { + Plugin plugin = getPlugin("org.apache.maven.plugins", "maven-dependency-plugin"); + String goal = "purge-local-repository"; + Xpp3Dom config = ExecuteMojoUtil.getPluginGoalConfig(plugin, goal, log); + config = Xpp3Dom.mergeXpp3Dom(configuration( + element(name("reResolve"), "false"), + element(name("actTransitively"), "false"), + element(name("manualIncludes"), project.getGroupId()+":"+project.getArtifactId()) + ), config); + log.info("Running maven-dependency-plugin:" + goal); + log.debug("configuration:\n" + config); + executeMojo(plugin, goal(goal), config, executionEnvironment(project, session, pluginManager)); + } + /** * Returns whether potentialTopModule is a multi module project that has potentialSubModule as one of its sub-modules. */