Thorsten Schöning
Thorsten Schöning

Reputation: 3717

How to model non-Java dependencies not available in any repository using Maven?

The Apache project log4cxx is implemented in C++, but uses Maven for historical reasons to manage web site and stuff. Some of the unit tests even require Java with e.g. log4j and at least that dependency is modeled in pom.xml like the following:

<dependencies>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.14</version>
        <scope>test</scope>
    </dependency>

The good thing about this is that a page containing that dependency is automatically generated when building the web site. The bad thing about this approach is that it reads pretty much like those are ALL dependencies necessary at all, which is not the case. There are some additional ones to successfully build, like APR, and some shell tools like sed necessary to successfully run tests. It would be great to be able to maintain those dependency using the already available plugin as well.

For test purposes, I came up with the following:

<dependency>
    <groupId>apr</groupId>
    <artifactId>util</artifactId>
    <version>1.5.4</version>
    <scope>system</scope>
    <systemPath>${user.home}/Documents/Svn/Src/Libs/trunk/C/X-OS/APR/apr-util/1.5.4/build/RAD 10.2/libs/libapr-util/Win32/Debug/out/libapr-util.lib</systemPath>
    <type>lib</type>
</dependency>

This adds an additional dependency to the page and let's the build succeed in the end, but still prints the following error message on the shell:

[ERROR] Artifact: apr:util:lib:1.5.4 has no file.

That is interesting, because using ProcMon I can see that the configured file is accessed and I don't see any other APR-named file requested at all.

13:57:58,5662686    java.exe    8312    CloseFile   C:\Users\tschoening\Documents\Svn\Src\Libs\trunk\C\X-OS\APR\apr-util\1.5.4\build\RAD 10.2\libs\libapr-util\Win32\Debug\out\libapr-util.lib  SUCCESS 

Additionally, this only seems to work in case of using scope system, while I would like to model e.g. sed as being necessary for scope test instead. system is documented to be deprecated at all as well.

So, is there some way to model additional dependencies in a way that Maven only uses them to create the corresponding page? Would be great if one could tell Maven to not resolve some dependencies at all, but using provided or anything else than the above system didn't succeed.

Thanks!

Upvotes: 2

Views: 186

Answers (1)

Thorsten Sch&#246;ning
Thorsten Sch&#246;ning

Reputation: 3717

To make things complete, the easiest approach really seems to be using a project-local Maven-repo to model dependencies. One simply needs to add some repo and the dependencies of interest to the pom.xml:

<repositories>
    <!-- Apache APR -->
    <repository>
        <id>mvn_tmatesoft_com</id>
        <name>maven.tmatesoft.com</name>
        <url>https://maven.tmatesoft.com/content/repositories/releases</url>
    </repository>

    <!-- Local repos to model non-public dependencies for different purposes. -->
    <repository>
        <id>log4cxx_non_public_deps</id>
        <url>file:///${project.basedir}/src/mvn_repo</url>
    </repository>
</repositories>

The important thing is that ${project.basedir} supports any path where the project is placed at any deployment. Dependencies can be added as necessary:

<dependencies>
    <dependency>
        <groupId>org.apache.apr</groupId>
        <artifactId>apr</artifactId>
        <version>1.5.2</version>
        <scope>compile</scope>
        <type>pom</type>
    </dependency>
    <dependency>
        <groupId>org.apache.apr</groupId>
        <artifactId>apr-util</artifactId>
        <version>1.5.4</version>
        <scope>compile</scope>
        <type>pom</type>
    </dependency>

    <dependency>
        <groupId>org.apache.logging.log4cxx.deps</groupId>
        <artifactId>gzip</artifactId>
        <version>1.10.0</version>
        <scope>runtime</scope>
        <type>pom</type>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4cxx.deps</groupId>
        <artifactId>sed</artifactId>
        <version>4.8.0</version>
        <scope>test</scope>
        <type>pom</type>
    </dependency>

    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.14</version>
        <scope>test</scope>
    </dependency>
</dependencies>

Because non-public dependencies are satisfied by the local repo, one is free on naming groups and stuff like that in theory. The last important step is to actually provide the dependencies in the correct directory as well:

<?xml version="1.0" encoding="UTF-8"?>
<project    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
            xmlns="http://maven.apache.org/POM/4.0.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.apache.logging.log4cxx.deps</groupId>
    <artifactId>gzip</artifactId>
    <version>1.10.0</version>
    <packaging>zip</packaging>
</project>

src/mvn_repo/org/apache/logging/log4cxx/deps/gzip/1.10.0/gzip-1.10.0.pom

All those dependencies are than used by the Maven-dependency plugin.

https://github.com/apache/logging-log4cxx/pull/35 https://github.com/apache/logging-log4cxx/pull/35/commits/2a5c157896b26c4c6445b1644de8266d3d0b54b1

Upvotes: 1

Related Questions