Search code examples
javamavenmaven-3maven-pluginnexus

Custom Maven plugin deployed on Nexus can't be used on a project on local machine unless the plugin is installed on local repo or set as a dependency


I have developed a custom Maven plugin and deployed it (mvn deploy) on a remote Nexus repository. The jar is correctly uploaded with a pom like this:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">     <modelVersion>4.0.0</modelVersion>

    <groupId>something</groupId>    
    <artifactId>xxx-maven-plugin</artifactId>
    <version>1.0.0-SNAPSHOT</version>   
    <packaging>maven-plugin</packaging>

The jar contains the necessary plugin.xml file so it looks good.

I have configured a project to use the plugin:

    <plugins>
        <plugin>
            <groupId>something</groupId>
            <artifactId>xxx-maven-plugin</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </plugin>
        ...

But when I run mvn xxx:mygoal it shows this error:

[ERROR] No plugin found for prefix 'xxx' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (/Users/myuser/.m2/repository), remote-repo (http://someremoterepo/nexus/content/groups/central/)] -> [Help 1]

The only thing to make it work is adding the plugin both as a plugin and as a dependency in the project:

    ...
        <dependency>
            <groupId>something</groupId>
            <artifactId>xxx-maven-plugin</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
    <plugins>
        <plugin>
            <groupId>something</groupId>
            <artifactId>xxx-maven-plugin</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </plugin>
        ...

Now it does find the plugin and executes it correctly. What am I doing wrong? I guess it shouldn't be necessary to have it defined both as a plugin and a dependency, the other third party plugins don't have that requirement.

UPDATE:

I have added this to my settings.xml file:

     <pluginGroup>something</pluginGroup>
  </pluginGroups>

Now the error is different:

[WARNING] The POM for something:xxx-maven-plugin:jar:1.0.0-SNAPSHOT is missing, no dependency information available
[WARNING] Failed to retrieve plugin descriptor for something:xxx-maven-plugin:1.0.0-SNAPSHOT: Plugin something:xxx-maven-plugin:1.0.0-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact something:xxx-maven-plugin:jar:1.0.0-SNAPSHOT
[WARNING] The POM for something:xxx-maven-plugin:jar:1.0.0-SNAPSHOT is missing, no dependency information available
...
[ERROR] Plugin something:xxx-maven-plugin:1.0.0-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact something:xxx-maven-plugin:jar:1.0.0-SNAPSHOT -> [Help 1]

It IS actually in the repo. Again if I explicitly add it as a dependency it does work. ???

UPDATE 2:

Using the Nexus GAV search interface I look for a plugin with artifactId spring-boot-maven-plugin and packaging maven-plugin and it finds it. Using packaging jar it also finds it.

Then I do the same with my plugin, when looking for packaging maven-plugin it finds it but it doesn't when using packaging jar.

UPDATE 3:

In my local repo there is a maven-metadata-central-mirror.xml file with this content:

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
  <plugins>
    <plugin>
      <name>something</name>
      <prefix>xxx</prefix>
      <artifactId>xxx-maven-plugin</artifactId>
    </plugin>
  </plugins>
</metadata>

FULL CONFIGURATION

Local settings.xml:

<?xml version="1.0" encoding="UTF-8"?>

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
   <localRepository>/Users/myuser/.m2/repository</localRepository>

  <pluginGroups>
     <pluginGroup>something</pluginGroup>
  </pluginGroups>

  <proxies>
  </proxies>

  <servers>
     <server>
       <id>someremoterepo</id>
       <username>xxxx</username>
       <password>yyyy</password>
     </server>
  </servers>

  <mirrors>
     <mirror>
       <id>someremoterepo</id>
       <name>Nexus Repo</name>
       <url>http://someremoterepo/nexus/content/groups/central/</url>
       <mirrorOf>*</mirrorOf>
     </mirror>
  </mirrors>

  <profiles>
     <profile>
       <id>myprofile</id>
       <activation>
       <activeByDefault>true</activeByDefault>
       </activation>
       <repositories>
         <repository>
           <id>central</id>
           <name>Central</name>
           <releases>
           <enabled>true</enabled>
           <checksumPolicy>warn</checksumPolicy>
           </releases>
           <snapshots>
           <enabled>true</enabled>
           <updatePolicy>never</updatePolicy>
           <checksumPolicy>fail</checksumPolicy>
           </snapshots>
           <url>http://someremoterepo/nexus/content/groups/central</url>
         </repository>
       </repositories>
     </profile>
  </profiles>
</settings>

Custom plugin pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>something</groupId>
    <artifactId>xxx-maven-plugin</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>maven-plugin</packaging>

    <name>xxx-maven-plugin</name>
    <description>xxx</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <kotlin.version>1.2.21</kotlin.version>
        <junit5.version>5.0.3</junit5.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-project</artifactId>
            <version>2.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-plugin-api</artifactId>
            <version>3.3.9</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>3.5.1</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jdk8</artifactId>
            <version>${kotlin.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-reflect</artifactId>
            <version>${kotlin.version}</version>
        </dependency>

        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit5.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit5.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>1.5.10.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.github.sbrannen</groupId>
            <artifactId>spring-test-junit5</artifactId>
            <version>1.0.2</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
        <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.8.0</version>
                <executions>
                    <execution>
                        <id>jacoco-initialize</id>
                        <phase>initialize</phase>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>kotlin-maven-plugin</artifactId>
                <groupId>org.jetbrains.kotlin</groupId>
                <version>${kotlin.version}</version>
                <configuration>
                    <args>
                        <arg>-Xjsr305=strict</arg>
                    </args>
                    <compilerPlugins>
                        <plugin>spring</plugin>
                    </compilerPlugins>
                    <jvmTarget>1.8</jvmTarget>
                </configuration>
                <executions>
                    <execution>
                        <id>compile</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>test-compile</id>
                        <phase>test-compile</phase>
                        <goals>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

    <distributionManagement>
        <repository>
            <id>someremoterepo-releases</id>
            <name>releases</name>
            <url>http://someremoterepo/nexus/content/repositories/releases/</url>
        </repository>
        <snapshotRepository>
            <id>someremoterepo-snapshots</id>
            <name>snapshots</name>
            <url>http://someremoterepo/nexus/content/repositories/snapshots/</url>
        </snapshotRepository>
    </distributionManagement>
</project>

Project that includes the plugin:

The only relevant bit is:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>agroup</groupId>
    <artifactId>some-project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    ...
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.10.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    ...
    <plugins>
        <plugin>
            <groupId>something</groupId>
            <artifactId>xxx-maven-plugin</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    ...

Solution

  • After a lot of struggling I finally fixed this, the solution was defining pluginRepositories in the settings.xml file. Now it resolves the plugin correctly without the need to add it as a dependency in the project pom:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
       <localRepository>/Users/myuser/.m2/repository</localRepository>
    
      <pluginGroups>
         <pluginGroup>something</pluginGroup>
      </pluginGroups>
    
      <proxies>
      </proxies>
    
      <servers>
         <server>
           <id>someremoterepo</id>
           <username>xxxx</username>
           <password>yyyy</password>
         </server>
      </servers>
    
      <mirrors>
         <mirror>
           <id>someremoterepo</id>
           <name>Nexus Repo</name>
           <url>http://someremoterepo/nexus/content/groups/central/</url>
           <mirrorOf>*</mirrorOf>
         </mirror>
      </mirrors>
    
      <profiles>
         <profile>
           <id>myprofile</id>
           <activation>
           <activeByDefault>true</activeByDefault>
           </activation>
           <repositories>
             <repository>
               <id>central</id>
               <name>Central</name>
               <releases>
               <enabled>true</enabled>
               <checksumPolicy>warn</checksumPolicy>
               </releases>
               <snapshots>
               <enabled>true</enabled>
               <updatePolicy>never</updatePolicy>
               <checksumPolicy>fail</checksumPolicy>
               </snapshots>
               <url>http://someremoterepo/nexus/content/groups/central</url>
             </repository>
           </repositories>
           <pluginRepositories>
             <pluginRepository>
               <id>central</id>
               <name>Central</name>
               <releases>
                 <enabled>true</enabled>
                 <checksumPolicy>warn</checksumPolicy>
               </releases>
               <snapshots>
                 <enabled>true</enabled>
                 <updatePolicy>never</updatePolicy>
                 <checksumPolicy>fail</checksumPolicy>
               </snapshots>
               <url>http://someremoterepo/nexus/content/groups/central</url>
             </pluginRepository>
           </pluginRepositories>
         </profile>
      </profiles>
    </settings>