Maven repository on Bitbucket

There are number of cases when standalone repository management tool like Nexus is an overkill and all you need is a simple service for providing a few maven libraries. I use Bitbucket private Git repositories for such cases several years. Setup is pretty easy and all you have to do is to modify ~/.m2/settings.xml like below:

<profiles>
    <profile>
        <id>some-project</id>
	    <activation>
	        <activeByDefault>true</activeByDefault>
	    </activation>
        <repositories>
            <repository>
                <id>some-project-maven-repo</id>
                <url>https://api.bitbucket.org/1.0/repositories/username/git-repo/raw/releases</url>
            </repository>
        </repositories>
    </profile>
</profiles>

<servers>
    <server>
        <id>some-project-maven-repo</id>
        <username>user@exitcode.net</username>
        <password>normal_or_app_password</password>
    </server>
</servers>

This configuration uses access through Bitbucket REST API v1.0 where:

  • username is a your Bitbucker username or team name
  • git-repo name of the Git repository created for hosting maven libraries
  • releases name of the Git branch the libraries are stored in
  • user@exitcode.net is an email of the user that have an access to Git project (if you use App password to protect main Bitbucket password, you must use username instead of email)

This works pretty well as Bitbucket Cloud API 1.0 challenges authentication using HTTP 401 Unauthorized header while accessing secured content like private repository, when no credentials are given. Once challenged, Maven Wagon HTTP provider sends proper credentials stored in settings.xml to the server in form of Authorization header.

API 2.0

However, Bitbucket announced recently that Cloud API 1.0 is deprecated as of June 30 and what’s worse, all version 1.0 APIs will be removed permanently on 31 December 2018. So, all users are forced to switch to API 2.0. To access the same Git repository with maven artifacts you have to use following configuration:

<profiles>
    <profile>
        <id>some-project</id>
	    <activation>
	        <activeByDefault>true</activeByDefault>
	    </activation>
        <repositories>
            <repository>
                <id>some-project-maven-repo</id>
                <url>https://api.bitbucket.org/2.0/repositories/username/git-repo/src/releases</url>
            </repository>
        </repositories>
    </profile>
</profiles>

<servers>
    <server>
        <id>some-project-maven-repo</id>
        <configuration>
            <httpHeaders>
                <property>
                    <name>Authorization</name>
                    <value>Basic dXNlckBleGl0Y29kZS5uZXQ6cGFzc3dvcmQ=</value>
                </property>
            </httpHeaders>
        </configuration>
    </server>
</servers>

The tricky part is the authentication. You have probably noticed that Authorization header with basic authentication credentials (value user:password encoded in base64) is passed to the server directly. This is because API 2.0 no longer challenges authentication and throws directly HTTP 403 Forbidden if it did not find credentials stored in request. With this configuration Maven Wagon HTTP provider (actually underlying Apache Http Client) won’t wait for authentication challenge that never come and sends credentials immediately.

Maven HTTP communication logs

While I was debugging whats going on under the hood, I discovered that Maven Wagon HTTP Provider bundles entire Apache HTTP Client with other Apache libraries like commons into one fat jar. This is crucial information if you want to enable trace logs of the HTTP client because bundled client is placed in different java package than the original! So, if you want to enable trace logs of the HTTP communication that maven makes, add following line into ${MAVEN_HOME}/conf/logging/simplelogger.properties (create it if not exists):

org.slf4j.simpleLogger.log.org.apache.maven.wagon=TRACE

Foremost, I started with information that Maven since v3.0.4 uses Apache Http Client 4, so I was trying to enable HTTP trace logs on logger org.apache.http as described in official documentation. That did not work so I decompiled wagon-http-2.9-shaded.jar from maven 3.5.4 installation where I found this bundled client and after going through some sources I eventually enabled tracing on the right logger.