How Including a Bintray Maven Repository in JCenter Works Under the Hood
The inner workings of Bintray’s Maven repositories, and especially their inclusion into JCenter, are a bit nebulous and scarcely documented. Depending on your artifact structure, you might find your packages incompletely published in JCenter. Here’s an explanation to help you fix this.
Introduction to Bintray Packages
Bintray allows you to create multiple Maven repositories, the default repository is simply called maven. At its core, such a repository is the same as any other Maven repository, a directory tree whose structure and files follow a specific pattern specified by Maven. To manage a repository, Bintray adds an artificial and sometimes complicated layer around the files: packages to group a software module and its artifacts, and versions to group artifacts from a specific release. This process is straightforward when manually uploading artifacts through the website, as the files are directly uploaded into a version, and thus are automatically assigned to the correct package.
It gets more complicated when artifacts are uploaded automatically through the API with the help of a tool like Maven, or a Gradle plugin. A plain Maven artifact is identified by a tuple of groupId
, artifactId
, and version
(e.g., org.apache.commons
, commons-collections4
, 4.0
), while a Bintray package is only identified by its package name. If the artifactId
and package name are the same, the artifact is automatically assigned to the package and its corresponding version; otherwise, a new package named after the artifact ID is created, which then needs to be manually merged into the appropriate package (e.g., artifacts videoplayer-java
and videoplayer-android
need to be merged manually into package videoplayer
). A package can contain multiple artifacts of arbitrary group and artifact IDs.
So why do packages exist at all? They are a way to assign common metadata to logically grouped software artifacts, e.g., description, license information, and icon, and how the packages are presented to users on the website. This concept can be ignored if the repository is just used as intended by Maven, but it must be considered when distributing software through the JCenter repository.
Including a Package in JCenter
To include a software package in JCenter, you need to group all artifacts into a package and make a request for inclusion. If everything goes well, your software will be available in the JCenter repository a few hours later. This is a manual process handled by Bintray staff, and what they actually do is allow-list a path into the Maven repository, which they call path prefix. According to support staff, JCenter is currently designed to support only one path per package, and by default it includes the artifactId
(which is a little odd as it is common practice to put multiple artifacts into a group). JCenter is thus not aware of Bintray packages, and packages consisting of multiple artifacts will likely be incompletely included.
Typical Issues and Solutions
Given a Maven repository with the following two artifacts grouped into Bintray package myfoo
:
com.example.myfoo
(groupId
)myfoo
(artifactId
)myfoo-api
(artifactId
)
Missing artifacts
What might happen is that only the path com/example/myfoo/myfoo
is included, and artifact myfoo-api
is missing from JCenter (or the other way round). To fix this, make another request for inclusion and explicitly mention that both paths */myfoo
and */myfoo-api
should be included. You might however find the inclusions disappearing some time after uploading a new version, in which case you need to contact the very helpful support and kindly ask for approval of your package by groupId
(instead of artifactId
s).
Multiple groups
If the package consists of multiple group IDs, it is recommended to split them into separate packages and separately request their inclusion.
Renaming groups
Related is the case of renaming/rebranding group IDs, e.g., from com.example.myfoo
to org.example.mybar
. To include renamed artifacts into JCenter, Bintray support suggests creating a new package and requesting its inclusion. I found it effective to create a new package named mypackage-new
, and after inclusion, rename the old package from mypackage
to mypackage-legacy
and the new one from mypackage-new
to mypackage
. This way, the package name and URL in the JCenter library stay the same and always point to the newest version of your software package.