How to add resources to the classpath of Maven plugins? - maven

I've got a Maven plugin that depends on slf4j for logging. The default behavior is too chatty for my liking but I can't figure out how to add my logback.xml to the plugin's classpath.
<plugin>
<dependencies>
</dependencies>
</plugin>
allows you to add dependencies to the plugin's classpath, but how do you add local (resource) directories?

You have to wrap your logback.xml into a proper Maven artifact (i.e. a jar) and install it to local repository or deploy to your shared repository, or use systemPath in your dependency declaration to point to a jar placed somewhere inside of your project, which is highly not recommended.
The reason for this is reusability of your build. Think how others would be able to reproduce it.

You don't. You must package them up as an artifact and add it as a dependency.

Related

Execute Maven plugin with custom classpath entry

I would like to call a maven plugin with a custom entry on its classpath. This is usually possible by adding <dependencies> inside the <plugin> tag. The problem is, what I would like to add to the classpath is not a maven artifact, but some random folder in my project (the reasons for this are quite obscure, I need a resource file to be present of the classpath, but I must not copy it to the /target/classes due to IDE shenanigans).
Is there any way to specify truly arbitrary classpath entries for a maven plugin?

Maven looks for jar that isn't present in the repository

I have a repository set up on Artifactory for my Maven projects. I have declared this repo in the <repositories> tag of my settings.xml for one of the projects, I have created a dependency on some other prooject (Say projectA) in my POM for a snapshot version. For this projectA, there is only POM artifact on the Artifactory and not a jar. Still when I compile my POM, Maven tries to download the jar for this project and fails saying it couldn't find it.
I shall paste the exact POM, error, settings.xml and repo view soon. Any idea what could be wrong?
If you would like to have a dependency of pom type, you need to explicitly declare it. For example:
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>my-artifact</artifactId>
<version>1.0</version>
<type>pom</type>
</dependency>
If type is not specified, Maven would use the default value which is jar.
Edit from OP: Just a caution, I use IntelliJ and even though I had the settings right in place, it was using some old (probably cached) settings.xml. I ran from commandline and it picked up the right one.

Maven/Spring: How to add external jar to classpath without installing it as maven dependency?

The common ways of including external non-maven jar in the classpath of your Maven project is to either use "addjar-maven-plugin" (which I have not been able to get to compile maven with) or "mvn install:install-file" and then adding a dependency section for the external JAR. This approach essentially installs client JAR in your repo and makes it available in classpath for maven. But is there a better way to do this (or) are the options mentioned above the only ones available? I just want the external JAR to be added to classpath for component scanning by Spring but do not want the JAR itself to be added to my repo as it is client's JAR? I hope this is a valid case (if not, kindly explain)
Thanks,
Paddy
You can create lib folder under your project's src folder and reference this folder as maven repository.
<repository>
<id>local</id>
<url>file://${basedir}/src/lib</url>
</repository>
Then you should add dependency to your jar in your pom.xml
<dependency>
<groupId>com.company</groupId>
<artifactId>dependency</artifactId>
<version>1.0</version>
</dependency>
After that your should rename jar file and place it on following path src/lib/com/company/dependency/1.0/dependency-1.0.jar . This path depends on how you want to reference your jar.

mojo-executor support for plugin dependencies?

I'm using the mojo-executor library to call a number of Maven plugins from within another Maven plugin.
However, I can't find any way to specify dependencies on the plugins as I'm invoking them. This is an issue for the maven-assembly-plugin, where I need to add an assembly descriptor file as a dependency. Adding the dependency at another level doesn't seem to get the descriptor file onto the plugin's classpath.
Any idea if this is possible, or if mojo-executor could be improved to provide this functionality? Thanks.
The mojo-executor will execute the mojo in an environment without any classpaths.
You need to manually add the dependency.
Dependency dep = new Dependency();
dep.setGroupId("groupId");
dep.setArtifactId("artifactId");
dep.setVersion("0.0.1-SNAPSHOT");
Plugin assembly = MojoExecutor.plugin(
"org.apache.maven.plugins",
"maven-assembly-plugin",
"2.3");
assembly.addDependency(dep)
MojoExecutor.executeMojo(assembly,
MojoExecutor.goal("single"),
...
)
You know that it's possible to define dependencies for plugins as well:
<plugin>
<groupId>com.soebes.maven.plugins.mlv</groupId>
<artifactId>maven-license-verifier-plugin</artifactId>
<version>0.4</version>
<dependencies>
<dependency>
<groupId>com.company.licenses</groupId>
<artifactId>allprojects</artifactId>
<version>1.0</version>
</dependency
</dependencies>
<configuration>
<!-- Optional you can put your configurations here -->
</configuration>
</plugin>
This will put the dependency on the classpath of the plugin. That might solve your problem.
Maybe you need to place a requiresDependencyResolution parameter at the #Mojo annotation of our Maven plugin's goal class. Something like this:
#Mojo(name = "your-goal", defaultPhase = LifecyclePhase.xxx,
requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME
)
public class YourGoalMojo...
This is necessary for YOUR Maven plugin to have dependencies resolved and available before/to its execution. The mojo-executor project's README page mentions this just after its maven-dependency-plugin based example:
https://github.com/TimMoore/mojo-executor/blob/master/README.md
Further information about the #Mojo annotation parameterization can be found here:
http://maven.apache.org/developers/mojo-api-specification.html

Instruct Maven to use Ivy's generated classpath

We are adding new code to an existing project that uses a custom build system developed with Ant and Ivy for dependency management.
Our new team is used to Maven and its features like testing execution, cobertura reports, etc.
Our question is: is it viable to add a pom.xml matching the current project structure, but instruct Maven to load its classpath from the "lib" dir already filled by Ivy?
In other words: we want to use Maven without its dependency management.
One really dirty approach would be to generate one big jar from the libdir and config the pom.xml to include just that... but we believe there should be cleaner approach.
Any idea or recommendation?
Note: we are not interested in generating a pom.xml with dependencies from the Ivy config, we just want Maven to rely on Ivy's generated classpath. No need to discriminate between test/runtime/compile classpath.
This is our final setup to solve this:
For each Ivy legacy project, use ivy:makepom and manual inspection to figure out the dependencies that we need to send to the new projects (Maven-based). This is a one-time process for each project.
Modify the legacy build system in a way that, every time a project is built, the identified dependencies are also exported to a mvn repo. Because de build machine holds the internal repo, we just use mvn install.
In the new maven projects, declare each dependency in the pom.xml and make sure the build system runs maven builds after the legacy builds.
Thank you all for your help!
One possibility is to use the system scope to define your dependencies in maven. This allows maven to use the jars downloaded by ivy for its dependencies.
e.g.
<dependencies>
<dependency>
<groupId>group.id</groupId>
<artifactId>artifact</artifactId>
<version>a.b.c</version>
<scope>system</scope>
<systemPath>${basedir}/lib/artifact-a.b.c.jar</systemPath>
</dependency>
...
</dependencies>
Maybe the makepom task will be helpful, it creates a pom from the ivy file.
Example from that page:
<ivy:makepom ivyfile="${basedir}/path/to/ivy.xml" pomfile="${basedir}/path/to/module.pom" conf="default,runtime">
<mapping conf="default" scope="compile"/>
<mapping conf="runtime" scope="runtime"/>
<dependency group="com.acme" artifact="acme-logging" version="1.0" optional="true"/>
</ivy:makepom>

Resources