1

It could sound dumb. But is there a way to edit or update the default-bindings file of maven?

/META-INF/plexus/default-bindings.xml

Why would I want to do that?


Background -

  • I am using latest maven version 3.3.9 on my machine as a home directory within intelliJ.

  • I have a module named testng-test without any external plugin specified. Take a look at the pom.xml for the module :

    <artifactId>testng</artifactId>
    
    <dependencies>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.9.13.6</version>
        </dependency>
    </dependencies>
    
  • And another module named junit-test with similar pom.xml but different dependency as follows :

    <artifactId>junit</artifactId>
    
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
    
  • I have added two empty classes within these modules(no @Test methods or classes still).


Activity -

  • Now when I try to build each of these modules using mvn clean install, the module junit-test builds successfully, but the module testng-test fails with following logs :

[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ testng ---

[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ testng ---

[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ testng ---

[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ testng ---

[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ testng ---

and then it would run into SurefireReflectionException -

Running TestNG6 org.apache.maven.surefire.util.SurefireReflectionException: java.lang.reflect.InvocationTargetException; nested exception is java.lang.reflect.InvocationTargetException: null java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189) at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165) at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75) Caused by: org.apache.maven.surefire.testset.TestSetFailedException: Unknown TestNG version 6.9.13.6


Tried -

To what I have noticed, if I explicitly update the plugin version for maven-surefire-plugin to 2.19.1 in the <plugins> property, things would just work fine.

But what if I would not want to explicitly override the plugin versions for the projects, in such case how do I go around using the latest bindings(atleast those would fix) for my project?

Looking into the default bindings, I could see in the source code that the bindings are in the default-bindings.xml file for maven, but I am unable to find it inside my installed maven folder either to be possible to edit and update.

So is there a way I can choose the default bindings to pick up (by default) the plugin versions I would want to specify for any maven module on my project list to execute with?

Naman
  • 27,789
  • 26
  • 218
  • 353
  • What's wrong with specifying the plugin version in the POM? You can put it inside a common parent POM, so that all its child inherit from it. – Tunaki Dec 02 '16 at 09:27
  • @Tunaki consider multiple projects and editing multiple POMs in such case. I agree that specifying plugin version solves it. But what if I want to do it(change the plugin(default) version) for all my existing projects? – Naman Dec 02 '16 at 09:31
  • Then make all your projects have a parent, or import a BOM. That's the way to lock down a plugin version. – Tunaki Dec 02 '16 at 09:36
  • @Tunaki Using BOM is more of maintaining dependency versioning. Also to the same conclusion, that would require me changing the pom of multiple existing projects anyway to make sure the changes are reflected. In case I would be forced to follow that, I would prefer overriding plugin version independently on project level instead of creating a parent for all of them with my current implementation. – Naman Dec 02 '16 at 09:47
  • 2
    What you're suggesting is probably harder than updating 'all' the poms. You'll have to change this file on every machine that wants to build your software, including CI nodes, and on all future developers' machines too. All of them, missing not even one, forever. The ones you do miss will not be able to build your software -- and they'll probably just do the obvious and easy thing and fix the problem in a common parent pom or bom. – Software Engineer Dec 22 '16 at 00:02

2 Answers2

2

That file is inside the jar:

${MAVEN}/lib/maven-core-3.3.9.jar

So:

${MAVEN}/lib/maven-core-3.3.9/META-INF/plexus/default-bindings.xml
Moses Davidowitz
  • 982
  • 11
  • 28
Albin. Com.
  • 191
  • 1
  • 4
1

Looks like you want to override the version the override the version of maven-surefire-plugin wihtout modifying any project' specific pom.xml file . To achieve this you need to extend your local installation of maven. Maven have concept of super pom and pom (without parent) is extended from it implicitly.

Since you neither have parent pom nor want to modify all of project's pom, only option left seems to override the default super pom. I am not sure if overriding binding can help too or not. But you should be able to override the super pom by following steps to meet your needs.

1) Create a super pom file (pom-4.0.0.xml) by copying the default pom file (directory content for maven 3.x version):

\---org
    \---apache
        \---maven
            \---model
                    pom-4.0.0.xml 

2) Add entry for maven-surefire-plugin with required version as shown in sniped below.

 ...
<pluginManagement>
 ...
 <plugins>
  <plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19</version>
  </plugin> 
  </plugins>
</pluginManagement>
...

3) Create a jar, say mycompany.superpom.jar packaging your pom file.

jar -cf mycompany.superpom.jar .

4) Place the jar under $MAVEN_HOME\lib\ext directory.

5) You should be done. All your project will be using maven-surefire-plugin with specified version.

Hope this helps.

Community
  • 1
  • 1
skadya
  • 4,330
  • 19
  • 27
  • Could you please detail the Step 1 and 4 mentioned above with an example possibly. They are a little unclear at the moment. – Naman Feb 05 '17 at 07:03
  • Assuming maven is installed at: D:\TOOLS\apache-maven-3.3.9 and Current Working Directory is: D:\TOOLS Commands: 1. Create a new empty directory extract the default pom.xml file in it. mkdir mycompany.superpom & cd mycompany.superpom & jar xf ..\apache-maven-3.3.9\lib\maven-model-builder-3.3.9.jar org/apache/maven/model/pom-4.0.0.xml 2. Modify pom-4.0.0.xml file to add entry for maven-surefire-plugin 3. Package modified pom.xml file in a jar jar -cf mycompany.superpom.jar . 4. Copy the jar in MAVEN Ext directory copy mycompany.superpom.jar ..\apache-maven-3.3.9\lib\ext – skadya Feb 05 '17 at 17:25
  • What if I've done that but Maven is still not using the version of maven-dependency-plugin I want? – Sloloem Nov 19 '20 at 18:08