Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accessing "META-INF/maven/plugin.xml" files during tests #76

Open
jmini opened this issue Mar 9, 2022 · 3 comments
Open

Accessing "META-INF/maven/plugin.xml" files during tests #76

jmini opened this issue Mar 9, 2022 · 3 comments
Milestone

Comments

@jmini
Copy link

jmini commented Mar 9, 2022

If I got this right, a maven plugin is nothing more than a regular jar with some additional metadata files in META-INF/maven/.

A jar built with the de.benediktritter.maven-plugin-development contains those file:

Screenshot of the example-maven-plugin-1.0.0-SNAPSHOT.jar content

Screenshot of a jar corresponding to the example-maven-plugin project.

The files are generated in the $buildDir/mavenPlugin/descriptor folder.

Usually when I have a task that generates files that needs to be present in the jar, I modify the source set to add the generated folder like this:

sourceSets.main.output.dir file("$buildDir/mavenPlugin/descriptor"), builtBy: generateMavenPluginDescriptor

While I was working on having functional tests for my maven plugin (see #41 - I will share the results soon) I noticed that the META-INF/maven/plugin.xml are not available during the test.

Adding this code to a test shows the problem:

System.out.println(getClass().getClassLoader());

if (getClass().getClassLoader() instanceof URLClassLoader) {
    Arrays.stream(((URLClassLoader) getClass().getClassLoader()).getURLs())
            .forEach(e -> System.out.println(e));
} else {
    System.out.println("XXXX Not a URLClassLoader");
}

During the test task the jar is not present on the classpath, only the folder containing the *.class files.

Output:

sun.misc.Launcher$AppClassLoader@2a139a55
file:/<user home>/.gradle/caches/7.3/workerMain/gradle-worker.jar
file:/<path to>/example-maven-plugin/build/classes/java/test/
file:/<path to>/example-maven-plugin/build/classes/java/main/
...
file:/<user home>/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/2973d150c0dc1fefe998f834810d68f278ea58ec/junit-4.12.jar
... and a lot of other jars from the gradle cache (corresponding to my test runtime classpath)

I was wondering if this is intended?

@britter
Copy link
Member

britter commented Mar 9, 2022

Hey @jmini thank you for the report. I remember trying to do this but but there is a fundamental issue here that I'm not sure how to work around: The Maven plugin tools need to consume both the source files (to scan JavaDoc) and the compiled classes (to find annotations). For that reason the generate task consumes both the sources and the sourceset output as an inputs. Because of that it can not add something to the sourceset because that would result in a cycle. I can review this again and try to work around it, but I'm not sure it's possible.

As a workaround I think it should be possible to make the test tasks consume the jar instead of the classes folder. I can't tell how to do that from the top of my head, but I think it should be possible.

@jmini
Copy link
Author

jmini commented Mar 9, 2022

As a workaround I think it should be possible to make the test tasks consume the jar instead of the classes folder.

This would be great. I have a dependency to the jar task anyway. Because for functional tests, Maven (through the takari code) needs to know all the jars and all the pom files of the projects under test.


Currently my workaround is to add $buildDir/mavenPlugin/descriptor to the test source set.
It is wired, but working since once in the classpath it does not matters how it was added.

Following code has to find the MOJO xml file:

Enumeration<URL> resources = getClass().getClassLoader().getResources("META-INF/maven/plugin.xml");

Source in Maven30xRuntime.java

Otherwise the tests are failing with:

java.lang.AssertionError: The MojoDescriptor for the goal <name> cannot be null.
	at org.junit.Assert.fail(Assert.java:88)
	at org.junit.Assert.assertTrue(Assert.java:41)
	at org.junit.Assert.assertNotNull(Assert.java:712)
	at io.takari.maven.testing.Maven30xRuntime.newMojoExecution(Maven30xRuntime.java:234)
	at io.takari.maven.testing.TestMavenRuntime.newMojoExecution(TestMavenRuntime.java:234)
	at io.takari.maven.testing.TestMavenRuntime.executeMojo(TestMavenRuntime.java:244)
	at io.takari.maven.testing.TestMavenRuntime.executeMojo(TestMavenRuntime.java:240)

@britter
Copy link
Member

britter commented Mar 9, 2022

If I can't make this work by adding it to the source set I think it's possible to add it to the testRuntimeClasspath from my plugin. I will look into it after I'm done with #73.

jmini added a commit to jmini/props2yaml that referenced this issue Mar 9, 2022
@britter britter modified the milestones: 0.3.2, 0.4.0, 0.4.1 Mar 11, 2022
@britter britter modified the milestones: 0.4.1, 0.4.2 Jan 20, 2023
@britter britter modified the milestones: 0.4.2, 0.4.3 Jun 5, 2023
@britter britter modified the milestones: 0.4.3, 1.x Feb 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants