user1615664
user1615664

Reputation: 621

I cannot package maven-plugin-api into uber jar using maven-shade-plugin

My pom.xml looks as follows:

  <!-- Use shade plugin for uber jar -->
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.4.2</version>
    <configuration>
    <filters>
     <filter>
       <artifact>maven-plugin-api</artifact>
       <includes>
         <include>org/apache/maven/**</include>
       </includes>
     </filter>
     </filters>
      <shadedArtifactAttached>false</shadedArtifactAttached>
      <transformers>
        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
          <mainClass>com.abc.def.ver.main.Main</mainClass>
        </transformer>
      </transformers>
      <createDependencyReducedPom>false</createDependencyReducedPom>
    </configuration>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>shade</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

But when my jar is created I get the following error while running main:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/maven/plugin/descriptor/PluginDescriptor
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Class.java:2688)
        at java.lang.Class.privateGetMethodRecursive(Class.java:3035)
        at java.lang.Class.getMethod0(Class.java:3005)
        at java.lang.Class.getMethod(Class.java:1771)
        at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: org.apache.maven.plugin.descriptor.PluginDescriptor
        at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 7 more

I also have dependency as

<dependency>
  <groupId>org.apache.maven</groupId>
  <artifactId>maven-plugin-api</artifactId>
  <version>3.2.5</version>
  <scope>provided</scope>
</dependency>

in my pom.

  1. How does it work? I don't have maven-plugin-api in my local repository. Is it taking it from my Maven (application) lib folder to run it because normally it runs perfectly. And if it is taking from my maven folder I have maven-3.3.1 and the specified version is 3.2.5.

  2. How can I make it work?

Upvotes: 0

Views: 547

Answers (2)

Tunaki
Tunaki

Reputation: 137084

By default, the maven-shade-plugin will ignore all provided dependencies. As such, the maven-plugin-api dependency, which has a provided scope, will not be kept.

This is expected: provided dependencies are supposed to be made available at runtime by the container. There are two solutions:

  • Remove the provided scope from the dependency declaration. It will be then included inside the uber jar.
  • Keep the provided scope but make the maven-plugin-api artifact available at runtime by adding it to the classpath when your application is launched.

Upvotes: 1

Rob
Rob

Reputation: 6497

When you say <scope>provided</scope> you are saying that the related artifact does not need to be included, because it will "magically" be available in the classpath.

See Difference between maven scope compile and provided for JAR packaging for more information.

Upvotes: 1

Related Questions