Help with publishing library to jcenter/maven/etc?

I am trying to upload and opensource 2 libraries I’ve been working on (a billboarding effects library for lightning and lasers, as well as a utility library that goes with my level editor)

I went through the process with pbrTerrain shaders once about 5-6 years ago, however I ran into lots of mistakes trying to use the website’s interface and I made the process much more confusing and time consuming than it probably needed to be.

So I unfortunately don’t remember much about the process aside from being frustrated with a .pom file that kept getting an error for being invalid, until I changed something and it worked but I don’t remember what it was :sweat_smile:

I also think I was uploading my library to a site called jfrog that announced it was going to be discontinuing service shortly after I started using it, so I don’t know if anything I went through in that process is still relevant or not.


With all that being said, I could use some guidance getting started with this process again, and will likely need to ask some more questions along the way.

So I think the first important thing to ask is which free repository/website is best to upload my libraries to?

2 Likes

Do you own a domain? There are two ways to do it. Either with your domain as the groupId (e.g. com.example) or your hosting platform as the group id (e.g. com.github etc)

There are some instructions here: Central Sync with Nexus Smart Proxy - The Central Repository Documentation

The publishing section of this build.gradle is how i do all the signing and javadoc etc generation for publishing https://github.com/oneMillionWorlds/Tamarin/blob/main/build.gradle (i publish to maven central - well technically OSSRH). Note that my build.gradle has some complexities to get the published sources section right despite me using lombok, if you don’t use lombok you wont need that (but will instead need the commented out withSourcesJar() bit)

1 Like

which free repository/website is best to upload my libraries to?

Maven Central is the gold standard, but it’s also difficult to work with.

2 Likes

Here is the simplest example I have for publishing a library to maven:

…no buildSrc or anything fancy. I have multiproject builds that are slightly more complicated and can serve as examples, too. (They DO use buildSrc and standardize some things across projects.)

Hardest part is getting an account and stuff at sonatype or whatever (not hard, really and they are pretty quick about it).

Approving the uploads can be a bit confusing, too.

2 Likes

sgold is right that setting up to deploy to maven central is a pain but its a one time set up and it’s fairly easy to publish new versions after that (in fact I set it up as a github pipeline to be a one click job; possibly over the top but I kept forgetting to tag). As pspeed says there is some confusing stuff to do on https://s01.oss.sonatype.org/ to approve it. You “close” the staging repo and then “release” it. There is an explanation for why it’s “close” but I think its a confusing term. You also have to “refresh” the staging repo before you see anything in it (even on first load; sigh)

Getting the digital signing right was the hardest bit for me; its also the one bit that’s partially hidden in the repo I sent to you (for obvious reasons). So here is an obfuscated version of those hidden parts (for windows, linux is very similar):

C:\Users\richa\.gradle

signing.keyId=ABC12345
signing.password=signingKeyRingPassword
signing.secretKeyRingFile=C://Users//richa//somepath//secring.gpg

ossrhUsername=ossrhUsername
ossrhPassword=ossrhPassword

Note that the keyId is just the last 8 characters of the long id (I remember that being a source of pain for me), and the secretRing must be explicitly exported gpg --export-secret-keys -o secring.gpg

I think I used these instructions for signing set up.

1 Like

Hahah… oh, yeah… the signing key.

I have standardized this to be one command publish for any of my projects and I forgot about some of the initial setup of stuff like that they can be shared. (groupId specific and not project specific.)

Somewhere I kept notes.

1 Like
1 Like

It may be not indicated, but I started publishing my libraries explicitly using the maven-deploy plugin, they are very easy to customize when you have non-jar binaries (native binaries), in case you are interesed in utilizing this way:
https://maven.apache.org/plugins/maven-deploy-plugin/examples/deploying-sources-javadoc.html

You can find all the possible ways to publish to OSSRH here:
https://central.sonatype.org/publish/publish-manual/

And this is my code (feel free to use):

EDIT:
If you are going to use this way, you need to create your own keyring and provide the deploy plugin with it, use the gpg (GNU Privacy Guard) utility.

1 Like

Thanks for all the replies, I’ve been busy over the holidays and haven’t gotten to start working on this yet, but I’ve been reading through everything and I appreciate all of the tips and info. I’ll post back once I’ve made some more progress or if I run into any trouble. Merry Christmas and Happy Holidays :slightly_smiling_face:

3 Likes

So i tried making an account and am already having trouble.

To start, I am just trying to figure out the process of manually uploading my files using their online repository manager here : Nexus Repository Manager

But I cannot seem to find the option to create an account on this page (only to login) and the email / password credentials I created on the main Sonatype website do not appear to work to login on that web page.

I also tried downloading the nexus repository manager application they have, however it gave me a 1 year trial and I can’t find any information if its going to expect me to pay next year or if thats even the right thing I need for uploading… and even then, the .exe I download is not launching, and 2 seperate sets of obscure nexus install instructions I found while trying to google the problem didn’t work.

I recall similar issue using JFrog in the past where their website and documentation kept funneling me into trying their other obscure paid services and it made it very difficult to even know what parts of their website I should be using.

1 Like

My memory is a little rusty but you create a jira ticket to get your account set up (yes it’s weird)

You want to create a sonatype account at Sign up for Jira - Sonatype JIRA

Then create a jira ticket to set up your account Error - Sonatype JIRA

See Sonatype JIRA as an example

“I also tried downloading the nexus repository manager application they have, however it gave me a 1 year trial and I can’t find any information if its going to expect me to pay next year or if thats even the right thing I need for uploading”

This is the wrong road (possibly thats for a private repo?). You don’t need to pay anything ever

2 Likes

Her are my notes from when I set things up a while back. I’ve cleaned out my PII (hopefully all of it this time) but everything else is intact:


2022-04-03
--------------
Keeping track of my maven central notes:

I'm following this tutorial:
https://madhead.me/posts/no-bullshit-maven-publish/

I've submitted the Jira to try to activate com.simsilica
...which may already be active.

Used cygwin to snag gpg2

=====================================================
C:\temp>gpg2 --full-generate-key
gpg (GnuPG) 2.2.34-unknown; Copyright (C) 2022 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
  (14) Existing key from card
Your selection? 1
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: My Name
Email address: myuser@mydomain.com
Comment:
You selected this USER-ID:
    "My Name <myuser@mydomain.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: /home/myuser/.gnupg/trustdb.gpg: trustdb created
gpg: directory '/home/myuser/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/myuser/.gnupg/openpgp-revocs.d/blahblahblahblah.rev
'
public and secret key created and signed.

pub   rsa4096 2022-04-03 [SC]
      MYBIGLONGKEYSTRING
uid                      My Name <myuser@mydomain.com>
sub   rsa4096 2022-04-03 [E]
=============================================================

C:\temp>gpg2 --armor --export MYBIGLONGKEYSTRING > key.pgp

C:\temp>more key .pgp
more: stat of key failed: No such file or directory
more: stat of .pgp failed: No such file or directory

C:\temp>more key.pgp
-----BEGIN PGP PUBLIC KEY BLOCK-----
blah blah blah
-----END PGP PUBLIC KEY BLOCK-----

Submitted the public key to:
https://keys.openpgp.org/
    You uploaded the key MYBIGLONGKEYSTRING.

    This key is now published with only non-identity information. (What does this mean?)

    To make the key available for search by email address, you can verify it belongs to you:
    Verification Pending

    myuser@mydomain.com

    Note: Some providers delay emails for up to 15 minutes to prevent spam. Please be patient.
>> And I verified.

https://keyserver.ubuntu.com/
{"inserted":["rsa4096/MYBIGLONGKEYSTRING"],"updated":null,"ignored":null}

=============================================================

Sonatype got back to me and said my com.simsilica group ID should be fine
and I'm all approved.


Next is to get SimMath setup to build with new gradle 7.4.2 which I have
downloaded and used to replace my regular gradle.


....lots of build.gradle tweaks later...
gradle install will install to the local repo.
gradle publish will publish to sonatype.
...-SNAPSHOT releases will go to one repo.
real releases will go to the staging repo.

I can then login to:
https://oss.sonatype.org/#stagingRepositories

...and confirm everything is ok and the "Close" it which starts the
rule-check process.  When that finished, I can "release" it.



Useful links:
===============
https://central.sonatype.org/publish/publish-guide/#deployment
https://central.sonatype.org/publish/release/#locate-and-examine-your-staging-repository

https://madhead.me/posts/no-bullshit-maven-publish/

https://docs.gradle.org/current/userguide/userguide.html
https://docs.gradle.org/current/samples/sample_building_java_libraries.html
https://docs.gradle.org/current/samples/sample_publishing_java_libraries.html
https://docs.gradle.org/current/userguide/publishing_maven.html

https://docs.gradle.org/current/userguide/building_java_projects.html#building_java_projects
https://docs.gradle.org/current/userguide/toolchains.html#toolchains
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.JavaCompile.html
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.compile.CompileOptions.html
https://docs.gradle.org/current/userguide/signing_plugin.html
https://docs.gradle.org/current/userguide/java_plugin.html



After doing a multiproject build, here are some other good links:
====================================================================
https://docs.gradle.org/current/userguide/sharing_build_logic_between_subprojects.html
https://docs.gradle.org/current/samples/sample_convention_plugins.html
https://docs.gradle.org/current/samples/sample_publishing_convention_plugins.html
https://docs.gradle.org/current/userguide/publishing_maven.html
https://docs.gradle.org/current/userguide/declaring_dependencies.html

I haven't used this one yet, but it talks about ways to do resource-only
projects or dependencies:
https://stackoverflow.com/questions/20136214/gradle-common-resource-dependency-for-multiple-java-projects

And for what it’s worth, once all of that was setup, here is my general process for a release of one of my libraries:


These are the general steps for releasing a lirbary:
-----------------------------------------------------

1) check for open pull requests.

2) make sure that the local codebase is up to date.
    svn update or git pull

3) check for local changes not committed
    svn stat or git status

4) make sure any dependencies are public

5) update the version in build.gradle
   update the version in release-notes.md
   
6) gradle install

7) gradle publish

8) sonatype:
    login to:
    https://oss.sonatype.org/#stagingRepositories

    Confirm everything is ok and click "Close" in the top
    section.
    ...that will start the rule check process.
    
    Once the rule check process finishes, "release" it.

9) Commit the build file and release note changes.

10) Make the github release and upload the artifacts

11) Update the web site/javadoc if necessary. 
    
12) roll the build versions for future dev

2 Likes

I used this guide to navigate my way around, and whenever I miss something, I return back to it.

2 Likes