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 607a8dce6..41d87b822 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 @@ -25,6 +25,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.nio.file.Paths; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; @@ -40,6 +41,7 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DependencyResolutionRequiredException; import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.ProjectDependencyGraph; @@ -68,9 +70,9 @@ import io.openliberty.tools.common.plugins.util.JavaCompilerOptions; import io.openliberty.tools.common.plugins.util.PluginExecutionException; import io.openliberty.tools.common.plugins.util.PluginScenarioException; +import io.openliberty.tools.common.plugins.util.ProjectModule; import io.openliberty.tools.common.plugins.util.ServerFeatureUtil; import io.openliberty.tools.common.plugins.util.ServerStatusUtil; -import io.openliberty.tools.common.plugins.util.ProjectModule; import io.openliberty.tools.maven.BasicSupport; import io.openliberty.tools.maven.applications.DeployMojoSupport; import io.openliberty.tools.maven.applications.LooseWarApplication; @@ -260,7 +262,7 @@ protected void setContainer(boolean container) { } protected List getResourceDirectories(MavenProject project, File outputDir) { - // Let's just add resources directories unconditionally, the dev util already checks the directories actually exist + // Let's just add resources directories unconditionally, the dev util already checks the directories actually exist // before adding them to the watch list. If we avoid checking here we allow for creating them later on. List resourceDirs = new ArrayList(); for (Resource resource : project.getResources()) { @@ -598,13 +600,13 @@ public boolean updateArtifactPaths(ProjectModule projectModule, boolean redeploy buildFile = this.buildFile; } MavenProject upstreamProject = getMavenProject(buildFile); + MavenProject backupUpstreamProject = upstreamProject; for (MavenProject p : upstreamMavenProjects) { if (buildFile != null && p.getFile().getCanonicalPath().equals(buildFile.getCanonicalPath())) { backupUpstreamProject = p; } } - // TODO rebuild the corresponding module if the compiler options have changed JavaCompilerOptions oldCompilerOptions = getMavenCompilerOptions(backupUpstreamProject); @@ -717,11 +719,13 @@ private void updateChildProjectArtifactPaths(File parentBuildFile, List testArtifacts = projectModule.getTestArtifacts(); project = getMavenProject(projectModule.getBuildFile()); } + if (compileArtifacts != null && testArtifacts != null && project != null) { compileArtifacts.clear(); testArtifacts.clear(); // TODO if a dependency is deleted from a parent project, it will still be in // the child projects classpath elements + compileClasspathElements.addAll(project.getCompileClasspathElements()); testClasspathElements.addAll(project.getTestClasspathElements()); compileArtifacts.addAll(compileClasspathElements); @@ -731,48 +735,71 @@ private void updateChildProjectArtifactPaths(File parentBuildFile, List } } } + + private MavenProject getMavenProject(File buildFile) throws ProjectBuildingException { ProjectBuildingResult build = mavenProjectBuilder.build(buildFile, session.getProjectBuildingRequest().setResolveDependencies(true)); - return build.getProject(); + MavenProject builtProject = build.getProject(); + updateUpstreamProjectsArtifactPathToOutputDirectory(builtProject); + return builtProject; } + /** + * From the project we're running dev mode from, get the artifact representing each of the upstream modules + * and make sure the artifact File is associated to the build output (target/classes, not the .m2 repo). + * + * Because of the way we dynamically build new model objects we need to do this from a given model's perspective. + * + * @param startingProject + */ + private void updateUpstreamProjectsArtifactPathToOutputDirectory(MavenProject startingProject){ + Map artifactMap = startingProject.getArtifactMap(); + for (MavenProject p : upstreamMavenProjects) { + Artifact projArtifact = artifactMap.get(p.getGroupId() + ":" + p.getArtifactId()); + if (projArtifact != null) { + File outputDir = Paths.get(p.getBuild().getOutputDirectory()).toFile(); + projArtifact.setFile(outputDir); + } + } + } + @Override protected void updateLooseApp() throws PluginExecutionException { - // Only perform operations if we are a war type application - if (project.getPackaging().equals("war")) { - // Check if we are using an exploded loose app - if (LooseWarApplication.isExploded(project)) { - if (!isExplodedLooseWarApp) { - // The project was previously running with a "non-exploded" loose app. - // Update this flag and redeploy as an exploded loose app. - isExplodedLooseWarApp = true; - - // Validate maven-war-plugin version - Plugin warPlugin = getPlugin("org.apache.maven.plugins", "maven-war-plugin"); - if (!validatePluginVersion(warPlugin.getVersion(), "3.3.1")) { - log.warn("Exploded WAR functionality is enabled. Please use maven-war-plugin version 3.3.1 or greater for best results."); - } - - redeployApp(); - } else { - try { - runExplodedMojo(); - } catch (MojoExecutionException e) { - log.error("Failed to run war:exploded goal", e); - } - } - } else { - if (isExplodedLooseWarApp) { - // Dev mode was previously running with an exploded loose war app. The app - // must have been updated to remove any exploded war capabilities - // (filtering, overlay, etc). Update this flag and redeploy. - isExplodedLooseWarApp = false; - redeployApp(); - } - } - } + // Only perform operations if we are a war type application + if (project.getPackaging().equals("war")) { + // Check if we are using an exploded loose app + if (LooseWarApplication.isExploded(project)) { + if (!isExplodedLooseWarApp) { + // The project was previously running with a "non-exploded" loose app. + // Update this flag and redeploy as an exploded loose app. + isExplodedLooseWarApp = true; + + // Validate maven-war-plugin version + Plugin warPlugin = getPlugin("org.apache.maven.plugins", "maven-war-plugin"); + if (!validatePluginVersion(warPlugin.getVersion(), "3.3.1")) { + log.warn("Exploded WAR functionality is enabled. Please use maven-war-plugin version 3.3.1 or greater for best results."); + } + + redeployApp(); + } else { + try { + runExplodedMojo(); + } catch (MojoExecutionException e) { + log.error("Failed to run war:exploded goal", e); + } + } + } else { + if (isExplodedLooseWarApp) { + // Dev mode was previously running with an exploded loose war app. The app + // must have been updated to remove any exploded war capabilities + // (filtering, overlay, etc). Update this flag and redeploy. + isExplodedLooseWarApp = false; + redeployApp(); + } + } + } } @Override @@ -789,7 +816,7 @@ protected void resourceDirectoryCreated() throws IOException { @Override protected void resourceModifiedOrCreated(File fileChanged, File resourceParent, File outputDirectory) throws IOException { - if (project.getPackaging().equals("war") && LooseWarApplication.isExploded(project)) { + if (project.getPackaging().equals("war") && LooseWarApplication.isExploded(project)) { try { runMojo("org.apache.maven.plugins", "maven-resources-plugin", "resources"); runExplodedMojo(); @@ -1132,6 +1159,7 @@ public File getLooseApplicationFile() { return getLooseAppConfigFile(project, container); } + } private boolean isUsingBoost() { @@ -1173,14 +1201,12 @@ protected void doExecute() throws Exception { if (isEar) { runMojo("org.apache.maven.plugins", "maven-ear-plugin", "generate-application-xml"); runMojo("org.apache.maven.plugins", "maven-resources-plugin", "resources"); - installEmptyEarIfNotFound(project); } 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"); + updateArtifactPathToOutputDirectory(project); runCompileMojoLogWarning(); } return; @@ -1320,10 +1346,10 @@ protected void doExecute() throws Exception { // Validate maven-war-plugin version if (isExplodedLooseWarApp) { - Plugin warPlugin = getPlugin("org.apache.maven.plugins", "maven-war-plugin"); - if (!validatePluginVersion(warPlugin.getVersion(), "3.3.2")) { - log.warn("Exploded WAR functionality is enabled. Please use maven-war-plugin version 3.3.2 or greater for best results."); - } + Plugin warPlugin = getPlugin("org.apache.maven.plugins", "maven-war-plugin"); + if (!validatePluginVersion(warPlugin.getVersion(), "3.3.2")) { + log.warn("Exploded WAR functionality is enabled. Please use maven-war-plugin version 3.3.2 or greater for best results."); + } } } @@ -1426,6 +1452,17 @@ protected void doExecute() throws Exception { } } + /** + * Call Artifact.setFile() to build output directory (i.e. ".../target/classes") + * to ensure the local .m2 repository location is not used. + * + * @param project + */ + private static void updateArtifactPathToOutputDirectory(MavenProject mavenProject) { + File outputDir = Paths.get(mavenProject.getBuild().getOutputDirectory()).toFile(); + mavenProject.getArtifact().setFile(outputDir); + } + /** * Use the following priority ordering for skip test flags:
* 1. within Liberty Maven plugin’s configuration in a module