Using a source repository directly as a dependency in Maven, similar to how Composer or npm handle it, is not a standard or officially supported feature. Maven is fundamentally designed to work with compiled artifacts (JARs, WARs, etc.) that are stored in a repository, such as a local Maven cache, a remote corporate repository like Nexus or Artifactory, or a public one like Maven Central.
The core of Maven's dependency resolution mechanism relies on the pom.xml to specify an artifact's GAV coordinates (GroupId, ArtifactId, Version), which Maven then uses to find and download the pre-built .jar file. It does not have a built-in mechanism to clone a Git repository, build the project from source, and then include it as a dependency.
Alternatives and Recommended Solutions
Given your constraints and the goal of avoiding hardcoded tokens, here are the most common and robust solutions:
1. Maven Profile with SSH
You can configure a Maven profile to pull dependencies over SSH. This is a common solution for private repositories.
Configure SSH: First, ensure your GitLab server allows SSH for package registry access. Many self-hosted GitLab instances can be configured to do this, though it's not the default.
Settings.xml: Configure your ~/.m2/settings.xml to use the SSH protocol. You would define a server and then a repository within your pom.xml that uses the ssh:// protocol.
XML
<settings>
<servers>
<server>
<id>gitlab-maven</id>
<username>git</username>
<privateKey>${user.home}/.ssh/id_rsa</privateKey>
</server>
</servers>
</settings>
XML
<project>
...
<repositories>
<repository>
<id>gitlab-maven</id>
<url>ssh://[email protected]:22/group/core.git</url>
</repository>
</repositories>
...
</project>
This approach requires you to configure the pom.xml and settings.xml correctly, but it's a solid way to use SSH keys for authentication, eliminating the need for hardcoded tokens.
2. Local File System Dependency
For local development, you can use the file:// protocol to reference the project on your local file system. This isn't scalable for a team but can be a temporary fix for your local build issues.
XML
<project>
...
<repositories>
<repository>
<id>local-core-repo</id>
<url>file://${project.basedir}/../core/target</url>
</repository>
</repositories>
...
</project>
This method is fragile and not recommended for production or multi-developer environments, as it creates a direct dependency on the local file path.
3. Maven Multi-Module Project (Recommended for your use case)
This is the most common and robust solution for your specific problem. If core is a child of a common project, you can structure your projects in a way that Maven automatically builds core before api and web.
Create a Parent POM: Create a parent pom.xml that lives in a root directory. This parent POM defines the core, api, and web projects as modules.
Define Modules: The parent pom.xml will look something like this:
XML
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.yourcompany</groupId>
<artifactId>parent-project</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>core</module>
<module>api</module>
<module>web</module>
</modules>
</project>
- Update Dependencies: In the
api and web projects, you can simply declare a dependency on core. Maven will automatically resolve this dependency from the local modules.
XML
<project>
...
<dependencies>
<dependency>
<groupId>com.yourcompany</groupId>
<artifactId>core</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
This approach handles the build order automatically. When you run mvn install from the parent directory, Maven will first build and install the core module to your local repository, then proceed to build api and web, resolving the core dependency from the local repository. This is the idiomatic Maven way to handle a shared library within a multi-project setup.
Given your description, the Maven Multi-Module Project is the most suitable and idiomatic solution for a shared internal library. It centralizes the build process and solves the dependency problem without relying on external repositories or custom configurations.