Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;

public class BaseDevTest {

Expand Down Expand Up @@ -501,4 +504,14 @@ protected static void tagLog(String line) throws Exception {
writer.write(line + "\n");
writer.flush();
}

@Rule
public TestWatcher watchman = new TestWatcher() {
@Override
protected void failed(Throwable thr, Description description) {
try {
System.out.println("Failure log in " + logFile + ", tail of contents = " + getLogTail(logFile));
} catch (IOException e) {}
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public static void setUpBeforeClass() throws Exception {
}

@Test
public void purgeLocallyInstalledModule_DevMode_Test() throws Exception {
public void purgeUpstreamSourcePart_DevMode_Test() throws Exception {

// install everything to m2
runCommand("mvn install");
Expand All @@ -57,8 +57,7 @@ public void purgeLocallyInstalledModule_DevMode_Test() throws Exception {
// 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));
assertTrue(getLogTail(logFile), verifyLogMessageExists("package io.openliberty.guides.multimodules.lib does not exist", 25000));

assertFalse(getLogTail(logFile), targetClass.exists());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public static void setUpBeforeClass() throws Exception {
}

@Test
public void purgeLocallyInstalledModule_LibertyRun_Test() throws Exception {
public void purgeUpstreamSourcePart_LibertyRun_Test() throws Exception {

// install everything to m2
runCommand("mvn install");
Expand All @@ -57,8 +57,7 @@ public void purgeLocallyInstalledModule_LibertyRun_Test() throws Exception {
// 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));
assertTrue(getLogTail(logFile), verifyLogMessageExists("package io.openliberty.guides.multimodules.lib does not exist", 25000));

assertFalse(getLogTail(logFile), targetClass.exists());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -260,7 +262,7 @@ protected void setContainer(boolean container) {
}

protected List<File> 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<File> resourceDirs = new ArrayList<File>();
for (Resource resource : project.getResources()) {
Expand Down Expand Up @@ -604,7 +606,7 @@ public boolean updateArtifactPaths(ProjectModule projectModule, boolean redeploy
backupUpstreamProject = p;
}
}


// TODO rebuild the corresponding module if the compiler options have changed
JavaCompilerOptions oldCompilerOptions = getMavenCompilerOptions(backupUpstreamProject);
Expand Down Expand Up @@ -731,48 +733,68 @@ private void updateChildProjectArtifactPaths(File parentBuildFile, List<String>
}
}
}

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<String,Artifact> artifactMap = startingProject.getArtifactMap();
for (MavenProject p : upstreamMavenProjects) {
Artifact projArtifact = artifactMap.get(p.getGroupId() + ":" + p.getArtifactId());
if (projArtifact != null) {
updateArtifactPathToOutputDirectory(p, projArtifact);
}
}
}

@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
Expand All @@ -789,7 +811,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();
Expand Down Expand Up @@ -1173,13 +1195,10 @@ 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);
getOrCreateEarArtifact(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");
runCompileMojoLogWarning();
}
Expand Down Expand Up @@ -1320,10 +1339,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.");
}
}
}

Expand Down Expand Up @@ -1426,6 +1445,8 @@ protected void doExecute() throws Exception {
}
}



/**
* Use the following priority ordering for skip test flags: <br>
* 1. within Liberty Maven plugin’s configuration in a module <br>
Expand Down Expand Up @@ -1849,6 +1870,7 @@ private void runCompileMojo(String goal, MavenProject mavenProject) throws MojoE
*/
private void runCompileMojoLogWarning() throws MojoExecutionException {
runCompileMojo("compile", project);
updateArtifactPathToOutputDirectory(project);
}

/**
Expand All @@ -1858,6 +1880,7 @@ private void runCompileMojoLogWarning() throws MojoExecutionException {
*/
private void runCompileMojoLogWarning(MavenProject mavenProject) throws MojoExecutionException {
runCompileMojo("compile", mavenProject);
updateArtifactPathToOutputDirectory(mavenProject);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package io.openliberty.tools.maven.server;

import java.io.File;
import java.nio.file.Paths;
import java.util.List;

import org.apache.maven.execution.ProjectDependencyGraph;
Expand Down Expand Up @@ -77,17 +79,14 @@ protected void doExecute() throws Exception {
runMojo("org.apache.maven.plugins", "maven-resources-plugin", "resources");

if (hasDownstreamProjects && looseApplication) {
installEmptyEarIfNotFound(project);
getOrCreateEarArtifact(project);
}
} 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");
updateArtifactPathToOutputDirectory(project);
}

if (!looseApplication) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
Expand All @@ -51,7 +53,6 @@
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.versioning.ComparableVersion;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.execution.ProjectDependencyGraph;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginManagement;
import org.apache.maven.plugin.BuildPluginManager;
Expand Down Expand Up @@ -921,20 +922,19 @@ public static boolean isConfigCopied() {
}

/**
* If the ear artifact is not in .m2, install an empty ear as a workaround so that downstream modules can build.
* If the ear artifact is not in .m2, create an ear artifact as a workaround so that downstream modules can build.
* Only needed if using loose application.
*
* @param earProject
* @throws MojoExecutionException If the empty ear artifact could not be installed. Prompts the user to run a manual command as a workaround.
*/
protected void installEmptyEarIfNotFound(MavenProject earProject) throws MojoExecutionException {
protected void getOrCreateEarArtifact(MavenProject earProject) {
ArtifactItem existingEarItem = createArtifactItem(earProject.getGroupId(), earProject.getArtifactId(), earProject.getPackaging(), earProject.getVersion());
try {
Artifact existingEarArtifact = getArtifact(existingEarItem);
log.debug("EAR artifact already exists at " + existingEarArtifact.getFile());
} catch (MojoExecutionException e) {
log.debug("Installing empty EAR artifact to .m2 directory...");
installEmptyEAR(earProject);
updateArtifactPathToOutputDirectory(earProject);
}
}

Expand Down Expand Up @@ -989,4 +989,44 @@ protected void purgeLocalRepositoryArtifact() throws MojoExecutionException {
log.debug("configuration:\n" + config);
executeMojo(plugin, goal(goal), config, executionEnvironment(project, session, pluginManager));
}


/**
* Call {@link #updateArtifactPathToOutputDirectory(MavenProject,Artifact) updateArtifactPathToOutputDirectory(MavenProject mavenProject, Artifact artifactToUpdate)}
* with <code>artifactToUpdate</code> obtained from <code>mavenProject</code>
*
* @param mavenProject
*/
protected void updateArtifactPathToOutputDirectory(MavenProject mavenProject) {
updateArtifactPathToOutputDirectory(mavenProject, mavenProject.getArtifact());
}

/**
* Call <code>artifactToUpdate.setFile()</code> to build output directory (i.e. ".../target/classes")
* (or build directory ".../target" for EAR module) and also creates the directory if not present.
* Together these will help avoid the core Maven artifact resolution trying to resolve the artifact against the local .m2,
* fitting better into dev mode, "all-in-one" use cases.
*
* @param mavenProject
* @param artifactToUpdate
*/
protected void updateArtifactPathToOutputDirectory(MavenProject mavenProject, Artifact artifactToUpdate) {
Path outputDir = null;
if (artifactToUpdate.getType().equals("ear")) {
outputDir = Paths.get(mavenProject.getBuild().getDirectory());
} else {
outputDir = Paths.get(mavenProject.getBuild().getOutputDirectory());
}

try {
if (!Files.exists(outputDir)) {
Files.createDirectory(outputDir);
}
} catch(IOException ioe) {
// Since this is kind of a hack it seems to draw too much attention to issue a warning message here.
log.debug("Failure creating output directory: " + outputDir, ioe);
}

artifactToUpdate.setFile(outputDir.toFile());
}
}