3

I'm using Maven and I would like to execute a plugin without repeating some of the required dependencies:

<build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>sql-maven-plugin</artifactId> <version>1.5</version> <dependencies> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.3.168</version> </dependency> <!-- ^^^ unnecessary duplication, IMO, because the project already imports the dependency below --> </dependencies> <!-- ... --> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.3.168</version> </dependency> </dependencies> 

In the above example, I would like to omit the com.h2database:h2 dependency, because I have already specified that in the project. Can this be done? How?

4
  • Hi, Lukas. It's a small world. I'm writing the Flyway lesson for the database module in my course, and I had the same question for org.flywaydb:flyway-maven-plugin:5.0.7: if the project already uses, for example, org.postgresql:postgresql:42.2.2 in the main project (as it likely would), why do I need to specify it again for the Flyway schema migration plugin? Let me know if you find an answer. For now I'm going to indicate in the lesson that the dependency must be listed in both places. Cheers! Commented Apr 10, 2018 at 17:13
  • @GarretWilson: Hi there :) As far as I know, the Flyway plugin (just like the jOOQ plugin) can access the project's classpath to discover JDBC drivers. This question here is about the sql-maven-plugin, which doesn't do this. Out of the box, Maven doesn't support this kind of dependency "inheritance" mechanism. I think you best create a new question... Commented Apr 10, 2018 at 18:30
  • Oh, so you're saying I don't need to specify the JDBC driver in the Flyway plugin dependency section, if the project already has the JDBC driver in the main dependencies? Commented Apr 11, 2018 at 14:52
  • @GarretWilson: Exactly. See this example: github.com/jOOQ/jOOQ/blob/version-3.10.6/jOOQ-examples/… Commented Apr 11, 2018 at 19:33

2 Answers 2

4

You can do that by using the pluginManagement block in your parent like this:

<pluginManagement> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>sql-maven-plugin</artifactId> <version>1.5</version> <dependencies> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.3.168</version> </dependency> </dependencies> </plugin> </plugins> </pluginManagement> 

Within your childs you only need to use the execution like this:

 <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>sql-maven-plugin</artifactId> <executions> <execution> .... </execution> </executions> </plugin> </plugins> </build> 

This will solve your problem to maintain the supplemental classpath dependencies (h2) only a single place.

Sign up to request clarification or add additional context in comments.

6 Comments

OK, that would help if I had 10 modules all using the same plugin. But my setup is more like I have one module that depends on H2, and then, there are 3 plugins also using the same H2 dependency...
Do you mean a dependency which is used by other modules which are not plugins ? If yes you could use dependencyManagement.
I've updated the question. I mean that the plugin is called from a project which already declared the H2 dependency. I'd like to call the plugin without redeclaring that dependency (within that particular project)
These are two different things. declaring a dependency and using a dependency as classpath element for a plugin.
So it's not possible?
|
0

While plugins don't automatically inherit dependencies from the modules / projects that include them (see khmarbaise's answer), it is still possible for a plugin author to implement their plugin in a way for the module / project classpath to be available to the plugin as well. The Flyway migration plugin or the jOOQ code generator do that, for instance.

One example how this can be done inside the plugin is this:

@Mojo public class Plugin extends AbstractMojo { @Parameter(property = "project", required = true, readonly = true) private MavenProject project; @Override public void execute() throws MojoExecutionException { ClassLoader oldCL = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(getClassLoader()); // Plugin logic } finally { Thread.currentThread().setContextClassLoader(oldCL); } } @SuppressWarnings("unchecked") private ClassLoader getClassLoader() throws MojoExecutionException { try { List<String> classpathElements = project.getRuntimeClasspathElements(); URL urls[] = new URL[classpathElements.size()]; for (int i = 0; i < urls.length; i++) urls[i] = new File(classpathElements.get(i)).toURI().toURL(); return new URLClassLoader(urls, getClass().getClassLoader()); } catch (Exception e) { throw new MojoExecutionException("Couldn't create a classloader.", e); } } } 

1 Comment

Very cool. A colleague removed a redundant dependency on the JOOQ plugin and I said it would definitely not work because project dependencies don't inherit to plugins... and then it did. :-)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.