Skip to content

Building bb4 Projects

Barry G Becker edited this page Aug 3, 2026 · 89 revisions

These are detailed instructions on how to build and release bb4 projects. If you want to create a new bb4 project, see bb4-project-template.

Prerequisites

If you have not already done so, install the following:

  • Java SE Development Kit (JDK) 21 (not the JRE). All bb4 projects now build with a Java 21 toolchain, enforced by the com.barrybecker4.bb4.base Gradle plugin — Gradle will fetch/select a matching JDK automatically via toolchains, but having a JDK 21 installed locally makes IDE setup simpler. After installing, set JAVA_HOME.
  • Git — accept the installer defaults. Consider creating your own GitHub account if you plan to contribute.
  • An IDE like IntelliJ IDEA or Cursor

You do not need to install Gradle — every repo includes the Gradle wrapper (currently Gradle 8.14.x), which downloads the correct version automatically.

Building

  1. Clone the repo, e.g.:
    git clone https://github.com/bb4/bb4-common.git
    
    Substitute the repo name for whichever bb4 project you're building.
  2. Run ./gradlew build at the root (gradlew build on Windows). This compiles and tests everything.
  3. Run ./gradlew tasks to see what's available. Non-library projects expose tasks to run applications directly (see bb4-simulations/bb4-puzzles/bb4-games for examples with many runnable apps per repo).
  4. To work in IntelliJ, just open the repo's root folder (or its build.gradle/build.gradle.kts file) directly — IntelliJ's Gradle import handles the rest. If prompted about an unregistered Git root, click "configure" and add it.

How the build system works

Since early 2026, bb4 projects use published Gradle convention plugins from bb4-gradle instead of the old model (a JAR of apply from Groovy scripts). You apply plugin IDs directly in build.gradle:

Plugin ID Purpose
com.barrybecker4.bb4.base Java 21 toolchain, shared repositories, Central Portal credential wiring
com.barrybecker4.bb4.scala-library java-library + Scala (3.x by default), bb4 source layout, test deps (JUnit 5, ScalaTest)
com.barrybecker4.bb4.publish maven-publish + signing, Central Portal publishing, sources/javadoc/scaladoc jars, optional jarMap multi-artifact mode
com.barrybecker4.bb4.application application plugin, run task, website deploy tasks

A typical downstream build.gradle:

plugins {
    id 'com.barrybecker4.bb4.scala-library' version '2.0.0'
    id 'com.barrybecker4.bb4.publish' version '2.0.0'        // if this module publishes
    id 'com.barrybecker4.bb4.application' version '2.0.0'    // optional, for runnable apps
}

group = 'com.barrybecker4'
version = '2.1-SNAPSHOT'

dependencies {
    implementation 'com.barrybecker4:bb4-common:2.0.0'
}

Source layout expected by bb4.scala-library:

  • Java: source/, tests in test/
  • Scala: scala-source/, tests in scala-test/

(Java and Scala can coexist in the same module — both directory pairs can be present at once, which matters if you're mid-migration on a repo like bb4-games.)

Full plugin details, options, and the dependency-version policy live in the bb4-gradle README — that's the source of truth for build tooling; this page focuses on the workflow.

Releasing New Versions

Since mid-2025, Sonatype OSSRH is retired. All publishing goes through the Central Publisher Portal (central.sonatype.com), using a Portal User Token, not old OSSRH credentials.

One-time setup, if you have publishing authorization:

  1. Sign in at central.sonatype.com, go to Profile → User Token, and generate a Portal User Token.
  2. Add it to ~/.gradle/gradle.properties (never commit this file):
    ossrhToken=<token username>
    ossrhTokenPassword=<token password>
  3. GPG signing config is unchanged from before — if you released previously, your existing key setup should still work.

Per-repo release flow, done bottom-up through the dependency hierarchy (most upstream repo — bb4-gradle itself — first):

  1. Drop the -SNAPSHOT suffix from version in build.gradle.
  2. For downstream repos, bump the plugins { ... version '...' } lines and any implementation 'com.barrybecker4:bb4-xxx:...' lines to already-released versions of whatever's earlier in the dependency order.
  3. ./gradlew clean build locally first.
  4. ./gradlew publish (equivalent to the old publishArtifacts).
  5. Manually promote the upload — as of the current Central Portal flow, the deployment does not appear automatically after step 4. From the same machine/IP you just published from:
    TOKEN_USER=$(grep -E '^ossrhToken=' "$HOME/.gradle/gradle.properties" | cut -d= -f2-)
    TOKEN_PASS=$(grep -E '^ossrhTokenPassword=' "$HOME/.gradle/gradle.properties" | cut -d= -f2-)
    AUTH=$(printf '%s:%s' "$TOKEN_USER" "$TOKEN_PASS" | base64 | tr -d '\n')
    curl -sS -w "\nHTTP:%{http_code}\n" -X POST \
    "https://ossrh-staging-api.central.sonatype.com/manual/upload/defaultRepository/com.barrybecker4?publishing_type=user_managed" \
    -H "Authorization: Bearer ${AUTH}" \
    -H "accept: */*" \
    -d ''
    Expect HTTP:200.
  6. Refresh central.sonatype.com/publishing. Once the deployment shows status VALIDATED, click Publish.
  7. Wait roughly 2–10 minutes, then confirm the artifact is live by searching search.maven.org for com.barrybecker4:<artifact>:<version>. Unlike a SNAPSHOT, a published release cannot be changed or removed.
  8. Bump the version back up with -SNAPSHOT (e.g. 2.1-SNAPSHOT) so development can continue, commit, and push.

While using SNAPSHOTs day to day (before a real release), the same ./gradlew publish works against Central's snapshot repository, no manual promotion step needed. To pick up a freshly published SNAPSHOT in a downstream repo: ./gradlew clean build --refresh-dependencies (add idea if you want IntelliJ project files regenerated too), or click "refresh" in IntelliJ's Gradle panel.

Troubleshooting:

  • 401 Unauthorized — you're using an old pre-2025 OSSRH token; regenerate a Portal User Token.
  • 403 Forbidden (snapshot publishing only) — "Enable SNAPSHOTs" isn't turned on for the com.barrybecker4 namespace at central.sonatype.com → Publishing → Namespaces.
  • 405 — something in ~/.gradle/gradle.properties still points at the retired oss.sonatype.org/s01.oss.sonatype.org hosts; remove those entries.

Full details: bb4-gradle/docs/publishing-sonatype.md.

Deploying to a Website

From 2000–2016, projects were deployed to barrybecker4.org using applets and Java Web Start. Both are long gone from modern browsers/JDKs, so deployment is now static: HTML + a zip per project, built with the Gradle deploy task from the com.barrybecker4.bb4.application plugin. Users download the zip, unzip it, and run a command — more friction than a single click, but it works with no browser plugins.

  • Non-library bb4 projects can run ./gradlew deploy to produce a dist/bb4-<project> directory.
  • Use FileZilla (or similar) to FTP the output to your website docroot.
  • Because InfinityFree hosting caps file size at 10MB, larger zips go into a GitHub Release instead, linked from the generated index.html.

Dependency hierarchy

(bb4-gradle)

 bb4-math      __bb4-common____
         \   /                 \
         bb4-ui             bb4-sound     bb4-A-star
           /  \                /\              \
          /    \______________/__\______________\____________________
      bb4-optimization       /    /    \         \    \              \
        /          \        /    /      \         \  bb4-adventure   bb4-aikido-app
  bb4-imageproc     \      /    /        \         \
    |         bb4-experimentation         \         \    bb4-expression
    |                         /            \         \     /
    |                   bb4-puzzles    bb4-games     bb4-simulations

  bb4-shortest-paths → depends on bb4-common, bb4-math
  bb4-Q-learning      → standalone, no bb4 library dependencies
  bb4-discrete-optimization → depends on bb4-common, bb4-math, bb4-optimization, bb4-shortest-paths
                              (also pulls in Google OR-Tools and scala-parallel-collections)

All modules are open-source on GitHub (https://github.com/bb4). Pure library projects: bb4-common, bb4-math, bb4-expression, bb4-ui, bb4-sound, bb4-A-star, bb4-optimization, bb4-imageproc, bb4-Q-learning, bb4-shortest-paths.

bb4-games is currently the only repo still written in Java rather than Scala; a port is in progress.

Additional notes

  • If you have publishing authorization (rare), see Releasing New Versions above for credentials — everything now goes through the Central Publisher Portal, not the old Sonatype Nexus UI.

  • If deploying to barrybecker4.org, follow the readme in the bb4-website project.

  • IntelliJ troubleshooting:

    • After changing Gradle config, ./gradlew cleanIdea idea refreshes IntelliJ's project files if it doesn't pick up changes automatically.
    • Under Project Structure, confirm the Project SDK points at a JDK 21 install — this usually happens automatically via Gradle toolchains.
    • Runnable classes can be run/debugged directly from IntelliJ by right-clicking them.
  • Linux tips:

    • Install a JDK 21 build (e.g. Temurin). As root, extract to somewhere like /usr/local/java and set JAVA_HOME/PATH in ~/.bashrc:
      export JAVA_HOME=/usr/local/java/jdk-21
      export PATH=$HOME/.local/bin:$HOME/bin:$JAVA_HOME/bin:$PATH
      
    • If a script won't execute, chmod +x <filename>.
    • Under Cygwin, you may need dos2unix gradlew before it will run.
  • Jenkins tips: it's possible to run CI/CD via Jenkins to auto-build/deploy on check-in. On Windows, Jenkins runs as C:\Windows\System32\config\systemprofile, so .gradle/gradle.properties containing publish credentials needs to live under that profile, not your own user's home.

  • Contact barrybecker4gmail.com with questions or comments.

Clone this wiki locally