diff --git a/README.md b/README.md index 6348d7b..0abac6a 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ for details. ## Plugin goals - `prepare-agent` - adds the AppMap Java agent to the JVM +- `validate-config` - Validates the config file is present and redable ## Plugin configuration @@ -114,6 +115,12 @@ Example: ## Troubleshooting +**After I add the appmap plugin config in the POM my project won't build** + It's likely the configuration file is not present or is not redable, try + using the validate-config file goal of the maven plugin to check whether + you have a configuration problem or not, run: + `mvn com.appland:appmap-maven-plugin:validate-config` + **I have no `target/appmap` directory** It's likely that the agent is not running. Double check the `prepare-agent` goal is being run. If the JVM is being forked at any point, make sure the diff --git a/build.gradle b/build.gradle index 061a991..7aa6550 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,6 @@ buildscript { ext { mavenVersion = "$mavenVersionCore" } - } plugins { @@ -50,23 +49,23 @@ configurations { } dependencies { + implementation 'com.appland:appmap-agent:1.0.3' + implementation 'org.apache.maven:maven-plugin-api:3.6.1' - compileOnly 'org.apache.maven.plugin-tools:maven-plugin-annotations:3.6.0' + compile 'org.apache.maven.plugin-tools:maven-plugin-annotations:3.6.0' implementation 'org.apache.maven:maven-core:3.5.4' implementation 'org.apache.commons:commons-lang3:3.10' testImplementation 'junit:junit:4.13.1' + testImplementation "org.apache.maven.plugin-testing:maven-plugin-testing-harness:3.3.0" + compile 'org.apache.maven:maven-compat:3.6.3' + compile 'commons-io:commons-io:2.6' + + compile "org.eclipse.sisu:org.eclipse.sisu.plexus:0.3.3" // as per https://stackoverflow.com/a/64726155 mavenEmbedder 'org.apache.maven:maven-embedder:3.6.3' mavenEmbedder 'org.apache.maven:maven-compat:3.6.3' - mavenEmbedder 'org.apache.maven.resolver:maven-resolver-connector-basic:1.4.1' - mavenEmbedder 'org.apache.maven.resolver:maven-resolver-transport-http:1.4.1' - mavenEmbedder 'org.slf4j:slf4j-simple:1.7.30' -// mavenEmbedder 'org.apache.maven.wagon:wagon-http:3.4.1' -// mavenEmbedder 'org.apache.maven.wagon:wagon-provider-api:3.4.1' - - implementation 'com.appland:appmap-agent:1.0.4' } //group = paramGroupId @@ -129,6 +128,7 @@ task generatePluginDescriptor(type: JavaExec, dependsOn: compileJava) { appendNode('directory', directory) appendNode('outputDirectory', outputDirectory) } + asNode().appendNode('version', paramVersion) } .writeTo(pomFile) diff --git a/pom.xml b/pom.xml index caea657..7be5256 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.appland appmap-maven-plugin maven-plugin - 0.5.0-SNAPSHOT + 1.1.2 Appland Java Recorder Maven Plugin This maven plugin helps you automatically generate an Appland AppMap using the Java Recorder. @@ -21,7 +21,7 @@ com.appland appmap-agent - 0.5.0 + 1.0.3 @@ -46,6 +46,23 @@ 4.13.1 test + + + org.apache.maven.plugin-testing + maven-plugin-testing-harness + 3.3.0 + test + + + org.apache.maven + maven-compat + 3.6.3 + + + commons-io + commons-io + 2.6 + diff --git a/src/main/java/com/appland/appmap/AppMapAgentMojo.java b/src/main/java/com/appland/appmap/AppMapAgentMojo.java index 1a032ba..b0c1a7c 100644 --- a/src/main/java/com/appland/appmap/AppMapAgentMojo.java +++ b/src/main/java/com/appland/appmap/AppMapAgentMojo.java @@ -8,6 +8,7 @@ import org.apache.maven.project.MavenProject; import java.io.File; +import java.nio.file.Files; import java.util.*; import static java.lang.String.format; @@ -17,24 +18,28 @@ public abstract class AppMapAgentMojo extends AbstractMojo { static final String APPMAP_AGENT_ARTIFACT_NAME = "com.appland:appmap-agent"; static final String SUREFIRE_ARG_LINE = "argLine"; static final List DEBUG_FLAGS = Arrays.asList("hooks", "locals", "http"); + public static final String DEFAULT_CONFIG_FILE = "appmap.yml"; + public static final String DEFAULT_OUTPUT_DIRECTORY = "target/appmap"; + public static final String DEFAULT_DEBUG_FILE = "target/appmap/agent.log"; + public static final int DEFAULT_EVENT_VALUE_SIZE = 1024; @Parameter(property = "skip") protected boolean skip = false; @Parameter(property = "project.outputDirectory") - protected File outputDirectory = new File("target/appmap"); + protected File outputDirectory = new File(DEFAULT_OUTPUT_DIRECTORY); @Parameter(property = "project.configFile") - protected File configFile = new File("appmap.yml"); + protected File configFile = new File(DEFAULT_CONFIG_FILE); @Parameter(property = "project.debug") protected String debug = "info"; @Parameter(property = "project.debugFile") - protected File debugFile = new File("target/appmap/agent.log"); + protected File debugFile = new File(DEFAULT_DEBUG_FILE); @Parameter(property = "project.eventValueSize") - protected Integer eventValueSize = 1024; + protected Integer eventValueSize = DEFAULT_EVENT_VALUE_SIZE; @Parameter(property = "plugin.artifactMap") protected Map pluginArtifactMap; @@ -44,7 +49,9 @@ public abstract class AppMapAgentMojo extends AbstractMojo { public abstract void execute() throws MojoExecutionException; - protected void skipMojo() { + protected void skipMojo(String reason) { + skip = true; + getLog().info(reason); } protected void loadAppMapJavaAgent() { @@ -131,4 +138,8 @@ protected File getAppMapAgentJar() { public MavenProject getProject() { return project; } + + protected boolean isConfigFileValid() { + return configFile.exists() && Files.isReadable(configFile.toPath()); + } } diff --git a/src/main/java/com/appland/appmap/LoadJavaAppMapAgentMojo.java b/src/main/java/com/appland/appmap/LoadJavaAppMapAgentMojo.java index 2a6e872..7153a2c 100644 --- a/src/main/java/com/appland/appmap/LoadJavaAppMapAgentMojo.java +++ b/src/main/java/com/appland/appmap/LoadJavaAppMapAgentMojo.java @@ -5,28 +5,36 @@ import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; +import java.io.FileNotFoundException; +import java.nio.file.Files; + /** - * Goal that adds appmap.jar to JVM execution as javaagent, - * right before the test execution begins. + * Goal that adds appmap.jar to JVM execution as javaagent, right before the test execution begins. */ @Mojo(name = "prepare-agent", defaultPhase = LifecyclePhase.TEST_COMPILE) public class LoadJavaAppMapAgentMojo extends AppMapAgentMojo { @Override - public void execute() - throws MojoExecutionException { + public void execute() throws MojoExecutionException { try { if (skip) { - getLog().info("Skipping AppLand AppMap execution because property skip is set."); - skipMojo(); + skipMojo("Skipping AppLand AppMap execution because property skip is set."); return; + } else if (!isConfigFileValid()) { + skipMojo( + "Skipping AppLand AppMap execution because the config file: " + + configFile.getPath() + + " does not exist or is not readable" + ); + throw new FileNotFoundException(configFile.getPath()); } else { - getLog().info("Initializing AppLand AppMap Java Recorder." ); + getLog().info("Initializing AppLand AppMap Java Recorder."); loadAppMapJavaAgent(); } } catch (Exception e) { getLog().error("Error initializing AppLand AppMap Java Recorder"); - e.printStackTrace(); + throw new MojoExecutionException("Error initializing AppLand AppMap Java Recorder", e); } } + } diff --git a/src/main/java/com/appland/appmap/ValidateConfigMojo.java b/src/main/java/com/appland/appmap/ValidateConfigMojo.java new file mode 100644 index 0000000..dead076 --- /dev/null +++ b/src/main/java/com/appland/appmap/ValidateConfigMojo.java @@ -0,0 +1,30 @@ +package com.appland.appmap; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; + +import java.io.FileNotFoundException; + +@Mojo(name = "validate-config", defaultPhase = LifecyclePhase.TEST_COMPILE) +public class ValidateConfigMojo extends AppMapAgentMojo { + + @Override + public void execute() throws MojoExecutionException { + try { + if (!isConfigFileValid()) { + skipMojo( + "Skipping AppLand AppMap execution because the config file: " + + configFile.getPath() + + " does not exist or is not readable" + ); + throw new FileNotFoundException(configFile.getPath()); + } else { + getLog().info("Appland AppMap Configuration file found."); + } + } catch (Exception e) { + getLog().error("Error executing AppLand AppMap Java Recorder"); + throw new MojoExecutionException("Error initializing AppLand AppMap Java Recorder", e); + } + } +} diff --git a/src/test/java/com/appland/appmap/GoalLoadTest.java b/src/test/java/com/appland/appmap/GoalLoadTest.java new file mode 100644 index 0000000..205d3cd --- /dev/null +++ b/src/test/java/com/appland/appmap/GoalLoadTest.java @@ -0,0 +1,23 @@ +package com.appland.appmap; + +import org.apache.maven.plugin.testing.AbstractMojoTestCase; +import org.junit.Test; + +import java.io.File; + +public class GoalLoadTest extends AbstractMojoTestCase { + + @Test + public void testPrepareAgentGoalIsLoadedCorrectly() throws Exception { + File pluginPom = new File("build/resources/test/test-project2/pom.xml"); + LoadJavaAppMapAgentMojo mojo = (LoadJavaAppMapAgentMojo) lookupMojo("prepare-agent", pluginPom); + assertNotNull(mojo); + } + + @Test + public void testValidateConfigGoalIsLoadedCorrectly() throws Exception { + File pluginPom = new File("build/resources/test/test-project2/pom.xml"); + ValidateConfigMojo mojo = (ValidateConfigMojo) lookupMojo("validate-config", pluginPom); + assertNotNull(mojo); + } +} diff --git a/src/test/java/com/appland/appmap/PluginLoadTest.java b/src/test/java/com/appland/appmap/PluginLoadTest.java new file mode 100644 index 0000000..73b8514 --- /dev/null +++ b/src/test/java/com/appland/appmap/PluginLoadTest.java @@ -0,0 +1,82 @@ +package com.appland.appmap; + +import org.apache.maven.plugin.Mojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.testing.MojoRule; +import org.junit.Rule; +import org.junit.Test; + +import java.io.File; +import java.io.FileNotFoundException; + +import static org.junit.Assert.*; + +public class PluginLoadTest { + + @Rule + public MojoRule rule = new MojoRule() { + @Override + protected void before() throws Throwable { + } + + @Override + protected void after() { + } + }; + + @Test + public void testMojoCanBeInstantiated() + throws Exception { + + Mojo mojo = rule.configureMojo( + new LoadJavaAppMapAgentMojo(), + "appmap-maven-plugin", + new File("build/resources/test/test-project/pom.xml") + ); + assertNotNull(mojo); + } + + @Test + public void testMojoIsLoaded() throws Exception { + LoadJavaAppMapAgentMojo mojo = (LoadJavaAppMapAgentMojo) + rule.configureMojo( + new LoadJavaAppMapAgentMojo(), + "appmap-maven-plugin", + new File("build/resources/test/test-project/pom.xml") + ); + assertNotNull(mojo); + } + + @Test + public void testMojoFailsWithMissingDefaultConfigFile() throws Exception { + LoadJavaAppMapAgentMojo mojo = (LoadJavaAppMapAgentMojo) + rule.configureMojo( + new LoadJavaAppMapAgentMojo(), + "appmap-maven-plugin", + new File("build/resources/test/test-project/pom.xml") + ); + assertNotNull(mojo); + Exception exception = assertThrows( + MojoExecutionException.class, + () -> rule.executeMojo(new File("build/resources/test/test-project/"), "prepare-agent") + ); + assertTrue(exception.getCause() instanceof FileNotFoundException); + } + + @Test + public void testMojoFailsWithNotExistingConfigFile() throws Exception { + LoadJavaAppMapAgentMojo mojo = (LoadJavaAppMapAgentMojo) + rule.configureMojo( + new LoadJavaAppMapAgentMojo(), + "appmap-maven-plugin", + new File("build/resources/test/test-project/nonexistent_config_file_pom.xml") + ); + assertNotNull(mojo); + Exception exception = assertThrows( + MojoExecutionException.class, + () -> rule.executeMojo(new File("build/resources/test/test-project/"), "prepare-agent") + ); + assertTrue(exception.getCause() instanceof FileNotFoundException); + } + +} diff --git a/src/test/resources/test-project/nonexistent_config_file_pom.xml b/src/test/resources/test-project/nonexistent_config_file_pom.xml new file mode 100644 index 0000000..131952b --- /dev/null +++ b/src/test/resources/test-project/nonexistent_config_file_pom.xml @@ -0,0 +1,30 @@ + + 4.0.0 + + com.github.gino0631 + appmap-maven-plugin-test + 1.0-SNAPSHOT + jar + + Appmap Plugin Test + + + + + com.appland + appmap-maven-plugin + + appmap.yml + + + + process-test-classes + + prepare-agent + + + + + + + \ No newline at end of file diff --git a/src/test/resources/test-project/pom.xml b/src/test/resources/test-project/pom.xml new file mode 100644 index 0000000..1086459 --- /dev/null +++ b/src/test/resources/test-project/pom.xml @@ -0,0 +1,30 @@ + + 4.0.0 + + com.github.gino0631 + appmap-maven-plugin-test + 1.0-SNAPSHOT + jar + + Appmap Plugin Test + + + + + com.appland + appmap-maven-plugin + + + + + + process-test-classes + + prepare-agent + + + + + + + \ No newline at end of file diff --git a/src/test/resources/test-project2/appmap.yml b/src/test/resources/test-project2/appmap.yml new file mode 100644 index 0000000..aa5ca80 --- /dev/null +++ b/src/test/resources/test-project2/appmap.yml @@ -0,0 +1,3 @@ +name: SampleFiles +packages: +- path: com.appland.appmap.sample diff --git a/src/test/resources/test-project2/pom.xml b/src/test/resources/test-project2/pom.xml new file mode 100644 index 0000000..ac0d90a --- /dev/null +++ b/src/test/resources/test-project2/pom.xml @@ -0,0 +1,31 @@ + + 4.0.0 + + com.github.gino0631 + appmap-maven-plugin-test + 1.0-SNAPSHOT + jar + + Appmap Plugin Test + + + + + com.appland + appmap-maven-plugin + + src/test/resources/test-project2/appmap.yml + + + + process-test-classes + + validate-config + prepare-agent + + + + + + + \ No newline at end of file