I am a maven-plugin development beginner and I use IntelliJ IDEA to develop my plugins, and I always use remote debug to debug a maven-plugin. I set VM Options in the plugin's Run Configuration and set Maven Run COnfiguration in the test project as most of the maven plugin developers do.
However, if I modify some code of the maven plugin, I need to stop the debug process and re-install the maven-plugin, which is very time-consuming if my maven-plugin is large-scale. After that, I start "debug" in the maven-plugin and start "run" in the test project.
So I tried to use maven-plugin-testing-harness to write some test code for my plugin like this:
<dependency>
<groupId>org.apache.maven.plugin-testing</groupId>
<artifactId>maven-plugin-testing-harness</artifactId>
<version>3.3.0</version>
<scope>test</scope>
</dependency>
public class Maven3MojoTest extends AbstractMojoTestCase {
private File localRepoDir = new File("C:\\Users\\buriedpot\\.m2\\repository");
private static final String POM_FILE_NAME = "src/test/resources/A/pom.xml";
private static final String PROJ_DIR_NAME = "src/test/resources/A";
@Rule
public MojoRule rule = new MojoRule()
{
@Override
protected void before() throws Throwable
{
}
@Override
protected void after()
{
}
};
/**
* @throws Exception if any
*/
@Test
public void testSomething()
throws Exception
{
File pom = new File(POM_FILE_NAME);
Assert.assertNotNull( pom );
Assert.assertTrue( pom.exists() );
MavenProject project = rule.readMavenProject(new File(PROJ_DIR_NAME));
MavenSession session = rule.newMavenSession(project);
ArtifactRepository localRepository = createLocalArtifactRepository();
session.getRequest().setLocalRepository(localRepository);
DefaultRepositorySystemSession systemSession = MavenRepositorySystemUtils.newSession();
DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
locator.addService(TransporterFactory.class, FileTransporterFactory.class);
locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
RepositorySystem system = locator.getService(RepositorySystem.class);
LocalRepository local = new LocalRepository(localRepoDir);
systemSession.setLocalRepositoryManager(system.newLocalRepositoryManager(systemSession, local));
MojoExecution execution = newMojoExecution("maven3Mojo");
Maven3Mojo mojo = (Maven3Mojo) lookupConfiguredMojo(session, execution);
Assert.assertNotNull( mojo );
mojo.repoSession = systemSession;
mojo.execute();
}
/**
* Generate a local repository
* @return local repository object
*/
private ArtifactRepository createLocalArtifactRepository() {
return new MavenArtifactRepository("local",
localRepoDir.toURI().toString(),
new DefaultRepositoryLayout(),
new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE ),
new ArtifactRepositoryPolicy( true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE )
);
}
/** Do not need the MojoRule. */
@WithoutMojo
@Test
public void testSomethingWhichDoesNotNeedTheMojoAndProbablyShouldBeExtractedIntoANewClassOfItsOwn()
{
}
}
And then I expect to be able to run the specified test in debug mode to achieve a way to debug without re install my plugin. However, some of components in my Mojo are not be injected.
@Mojo(name = "maven3Mojo", defaultPhase = LifecyclePhase.VALIDATE)
public class Maven3Mojo extends AbstractMojo {
@Parameter(defaultValue = "${session}", readonly = true, required = true)
public MavenSession session;
@Component
public DependencyGraphBuilder dependencyGraphBuilder;
@Parameter(defaultValue = "${localRepository}", readonly = true)
public ArtifactRepository localRepository;
@Parameter(defaultValue = "${project}", readonly = true, required = true)
public MavenProject project;
@Parameter(defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true)
public List<ArtifactRepository> remoteRepositories;
@Parameter(defaultValue = "${repositorySystemSession}", readonly = true, required = true)
public RepositorySystemSession repoSession;
}
Although I referred to the answer maven-plugin-testing-harness session.getLocalRepository() returns null, the component "repoSession" still lack some critical attributes...
So it seems that harness test cannot correctly inject all needed component in Maven Mojo. So is there any other approaches can be used to debug without the heavy reinstall procedure?