Share properties between maven plugin and the calling maven project pom - java

I have created a Maven Plugin P, which I want to use as a dependency in another Maven project A. I am providing some parameters to that the plugin P from the pom of Maven project A.
I want to set some properties in plugin P based on parameters provided by project A and want them to be referenced in pom of project A. How can I do that ?
I have tried setting properties for MavenProject in the plugin P. How can I refer them in the pom for project A?
Project A pom snippet:
<plugin>
<groupId>sample.plugin</groupId>
<artifactId>sample-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
<executions>
<execution>
<goals>
<goal>testing</goal>
</goals>
<configuration>
<param1>value1</param1>
<param2>value2</param2>
</configuration>
</execution>
</executions>
</plugin>
Plugin P code snippet
#Mojo( name = "testing")
public class TestMojo extends AbstractMojo
{
.
.
#Parameter(property = "param1")
private String param1;
#Parameter(property = "param2")
private String param2;
#Parameter(defaultValue = "${project}")
private org.apache.maven.project.MavenProject project;
public void execute() throws MojoExecutionException
{
if(param1.equalsIgnoreCase("value1")){
project.getProperties().setProperty("PROP1","val1");
} else{
project.getProperties().setProperty("PROP1","val3");
}
if(param2.equalsIgnoreCase("value2")){
project.getProperties().setProperty("PROP2","val2");
} else{
project.getProperties().setProperty("PROP2","val3");
}
}
}
I expect the PROP1 and PROP2 to be used in project A

Found the solution, if we add ${project} A as a parameter to the plugin configuration, we can add properties to it, which can be referred in project A pom.
Ex:
<plugin>
<groupId>sample.plugin</groupId>
<artifactId>sample-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
<executions>
<execution>
<goals>
<goal>testing</goal>
</goals>
<configuration>
<param1>value1</param1>
<param2>value2</param2>
<project>${project}</project>
</configuration>
</execution>
</executions>
</plugin>
in Plugin one can use this Maven project
project.getProperties.setProperty("projectProperty",propertyValue);

If i'm understanding this question correctly, try adding:
<dependencies>
<dependency>
<groupId>sample.plugin</groupId>
<artifactId>sample-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
at the bottom of Plugin P's pom.xml file, right before the end of </project>
I am not entirely sure this will even work as I have limited knowledge of Maven, but please let me know.
Best of luck to you.

Related

maven plugin api: #Paramerter using setters doesn't work

I am writing a custom maven-plugin for my project. Following the instructions mentioned here
https://maven.apache.org/guides/plugin/guide-java-plugin-development.html#using-setters I added a #Parameter using setters as shown below.
#Parameter(property = "destinationDirectory", defaultValue = "${project.build.directory}/generated-resources")
private String _destinationDirectory;
private Path dstDirRoot;
public void setDestinationDirectory(String destinationDirectory) {
Path dstDir = Paths.get(destinationDirectory);
if (dstDir.isAbsolute()) {
this._destinationDirectory = dstDir.toString();
} else {
this._destinationDirectory = Paths.get(baseDir, dstDir.toString()).toString();
}
dstDirRoot = Paths.get(this._destinationDirectory);
}
Pom.xml entries on the usage side
<plugin>
<groupId>com.me.maven</groupId>
<artifactId>my-maven-plugin</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<goals>
<goal>run</goal>
</goals>
<phase>generate-resources</phase>
</execution>
</executions>
<configuration>
<destinationDirectory>${project.build.directory}/myDir</destinationDirectory>
</configuration>
</plugin>
Now, I was expecting that during the plugin execution, it would call setDestinationDirectory method. But it doesn't. #Parameter(property="...") doesn't seem to have any impact.
Is this a bug? Or am I missing something?
From maven-plugin-plugin version 3.7.0 you can simply add #Parameter annotation on public setter methods.
You code can looks like:
#Parameter(...)
public void setDestinationDirectory(String destinationDirectory) {
...
}
You also need to define version of maven-plugin-plugin and maven-plugin-annotations dependency in your pom.xml - both should have the same version.
<project>
<properties>
<maven-plugin-tools.version>3.7.1</maven-plugin-tools.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<scope>provided</scope>
<version>${maven-plugin-tools.version</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>${maven-plugin-tools.version}</version>
<executions>
<execution>
<id>help-mojo</id>
<goals>
<goal>helpmojo</goal>
</goals>
</execution>
</executions>
</plugin>
</pluginManagement>
</build>
</project>
If I remember correctly, when the annotation has property = destinationDirectory, it will read a system property from system properties (e.g. -D) or pom properties, unless a configuration section is specified in the XML.
mvn generate-resources -DdestinationDirectory=/path/to/dir
If a configuration is specified in the XML, which is the case in your example, the name of the configuration will match either the name of the variable or the specified alias, if any. You can try the following options and check if it solves the issue:
Setting an alias:
#Parameter(alias = "destinationDirectory", defaultValue = "${project.build.directory}/generated-resources")
private String _destinationDirectory;
Renaming the variable:
#Parameter(defaultValue = "${project.build.directory}/generated-resources")
private String destinationDirectory;
It's usually a good practice to keep the name of the configuration and the variables consistent, for easier maintenance.

Versions Maven Plugin rules that are inheritable

When running mvn versions:display-dependency-updates for the Version Maven Plugin I see lots of things like this:
[INFO] org.slf4j:slf4j-api ........................... 1.7.36 -> 2.0.0-alpha7
But just because I'm not using the alpha version of a later version doesn't mean I'm not using the latest available release version. Another Stack Overflow answer indicated that I can set up a rules.xml file to ignore versions like *.-alpha*, putting something like this in my POM:
<configuration>
<rulesUri>file:///${project.basedir}/rules.xml</rulesUri>
</configuration>
My question: is this rules.xml file inheritable? If I put it in a separate project in a parent POM of <packaging>pom</packaging>, published to Maven Central, will the child POMs pick it up? Or will the child projects look for a rules.xml file in the child project directory?
I want to configure the versions-maven-plugin in the parent POM (as I do already) and run mvn versions:display-dependency-updates on any child POM or descendant POM. How can I set up the ignore rules in the parent POM so that these version ignore rules will be picked up when I check for dependency updates in a child POM? (Is there no way to include the rule within the POM itself?)
Or will the child projects look for a rules.xml file in the child project directory?
Yes, if you define the rules.xml file via ${project.basedir} it will resolve to the current local base directory of the child project. I've verified this with a simple parent-child pom setup. So that will not work, unless you duplicate the rules file in every project.
If you wish to include the plugin configuration and ruleset in the parent pom without duplicating the rules file, you have two options:
If you have your ruleset xml file hosted at, for example, http://www.mycompany.com/maven-version-rules.xml then the following configuration in your corporate pom would ensure that all projects use this rule set.
<configuration>
<rulesUri>http://www.mycompany.com/maven-version-rules.xml</rulesUri>
</configuration>
or
You can provide your ruleset xml file also within a jar, if you want to distribute your ruleset xml as Maven artifact. Therefore you have to declare the containing jar as direct dependency of the versions-maven-plugin and to use classpath as protocol.
<configuration>
<rulesUri>classpath:///package/foo/bar/rules.xml</rulesUri>
</configuration>
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>version-rules</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
Source:
https://www.mojohaus.org/versions-maven-plugin/version-rules.html
The configuration in the pom only has rudimentary includes and excludes filters. Those will allow you to exclude any dependency as a whole, but not specific update versions. As far as i can tell from the available documentation there is no way to define version rules in any other way.
See
https://www.mojohaus.org/versions-maven-plugin/examples/advancing-dependency-versions.html
Update 09-2022
In the github ticket we found in the comments we can see the following update:
It looks like a feature like this has recently been implemented by #369. Please see #318 where it's possible to provide inclusion and exclusion filters for determining which dependency patterns will be considered. Thanks to that, you can rule out patterns such as .*-beta. or .*_ALPHA, albeit not using regexp, but simple asterisk wildcards.
This will land in today's release (2.12.0).
This will add the following features:
Version 2.12.0 will introduce new arguments: dependencyIncluded, dependencyExcludes, dependencyManagementIncludes, dependencyManagementExcludes.
With the following example configuration in pom.xml given:
<profile>
<id>display-dependency-updates</id>
<build>
<plugins>
<plugin>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>display-dependency-updates</goal>
</goals>
<configuration>
<dependencyIncludes>org.apache.maven.*:doxia*</dependencyIncludes>
<dependencyManagementIncludes>com.puppy*:*</dependencyManagementIncludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
This will also be implemented for filtering plugin and pluginManagement, but that will probably be added in a later release:
So, I've just added the missing plugin- and plugin management filtering which works likewise. I really doubt it will land into today's release though.
Pasting my answer here from Github, because I think it might benefit others.
Provided you have a directory called rules-test in your project containing the rules template file:
<ruleset comparisonMethod="maven"
xmlns="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://mojo.codehaus.org/versions-maven-plugin/rule/2.0.0
https://www.mojohaus.org/versions-maven-plugin/xsd/rule-2.0.0.xsd">
<ignoreVersions>
<ignoreVersion type="regex">${ignoredVersions}</ignoreVersion>
</ignoreVersions>
</ruleset>
Then, in your main project, create the following profile:
<profile>
<id>rules-test</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>rules-test</directory>
<filtering>true</filtering>
</resource>
</resources>
<outputDirectory>${project.basedir}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.12.0</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>display-dependency-updates</goal>
</goals>
<configuration>
<rulesUri>file://${project.basedir}/compiled-rules.xml</rulesUri>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
If you then execute the following Maven target:
mvn -P rules-test "-DignoredVersions=.*-(M\d*|.*-SNAPSHOT)" clean validate
then you will get a dependencies report using the filter in the -DignoredVersions argument (filtering out both *-M* and *-SNAPSHOT).
And if you put your ignoredVerions property in your project instead of passing it as a -D argument, then it will be inheritable!

Maven plugin jsonschema2pojo returns ClassNotFoundException

I need to generate java pojos from JSON schema. I'm trying to use jsonschema2pojo maven plugin for this purpose. I wrote custom rule factory and I want to use it for pojos generation.
Here is my jsonschema2pojo plugin configuration:
<plugin>
<dependencies>
<dependency>
<groupId>my.group.id</groupId>
<artifactId>my-artifact-id</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<groupId>org.jsonschema2pojo</groupId>
<artifactId>jsonschema2pojo-maven-plugin</artifactId>
<version>1.1.1</version>
<executions>
<execution>
<id>generateClassesFromSchema</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<sourceDirectory>${basedir}/src/main/resources/schemas</sourceDirectory>
<targetPackage>my.target.package</targetPackage>
<includeHashcodeAndEquals>false</includeHashcodeAndEquals>
<customRuleFactory>path.to.rule.factory.MyCustomRuleFactory</customRuleFactory>
</configuration>
</plugin>
MyCustomRuleFactory.java is the part of my project, dependency for which is inside plugin element. But when a do mvn clean install I get thi following:
Failed to execute goal org.jsonschema2pojo:jsonschema2pojo-maven-plugin:1.1.1:generate (generateClassesFromSchema) on project my-artifact-id: Execution generateClassesFromSchema of goal org.jsonschema2pojo:jsonschema2pojo-maven-plugin:1.1.1:generate failed: java.lang.ClassNotFoundException: path.to.rule.factory.MyCustomRuleFactory
What am I doing wrong?
Thanks for any suggestion!
As I understand in the tag "customRuleFactory" must be full class name. Are you sure you didn't add path?
path.to.rule.factory.MyCustomRuleFactory
May be correct rule.factory.MyCustomRuleFactory

How to resolve maven expression in source code in Intellij

I'm usin templating-maven-plugin to in order to filter main sources, so it injects some value directly in java code while project building. And it works well while I'm using only maven but when it comes to run the project in InteillIj it doesn't resolve meven exporession in the code like "${someParam}";
Using properties file it isn't a solution for me
Example
public class TestObject {
String surname = "${someParam}";
public void print(){
System.out.println("My name is " + surname);
}
}
POM CONFIG
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>templating-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>filter-src</id>
<phase>process-resources</phase>
<goals>
<goal>filter-sources</goal><!--filter main sources -->
</goals>
</execution>
</executions>
</plugin>
So when I do mvn clean install -DsomeParam=TEST it works well but when I run it in intellij even with run config -DsomeParam=TEST it prints My name is ${someParam}

Maven mojo plugin to load class from hosting project

I have a custom plugin that loads classes, e.g.
Class<?> clazz = Class.forName(NAME_OF_CLASS_FROM_HOST_DEPENDENCIES);
NAME_OF_CLASS_FROM_HOST_DEPENDENCIES - is the class that exists in the dependencies of project, where this plugin is used.
in hosting project pom, I call plugin like this:
<plugin>
<groupId>com.plugins</groupId>
<artifactId>the_plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<id>do</id>
<phase>process-classes</phase>
<goals>
<goal>do</goal>
</goals>
</execution>
</executions>
</plugin>
Getting ClassNotFoundException
it's important , those dependencies defined in pom as
<scope>provided</scope>
Ended up with following.
List<URL> listUrl = new ArrayList<URL>();
Set<Artifact> deps = project.getDependencyArtifacts();
for (Artifact artifact : deps) {
final URL url = artifact.getFile().toURI().toURL();
listUrl.add(url);
}
newClassLoader = new URLClassLoader(listUrl.toArray(new URL[listUrl.size()]), Thread.currentThread().getContextClassLoader());

Categories

Resources