Skip to content

Distribution Flavors

Petrus Pradella edited this page Jun 17, 2026 · 6 revisions

Distribution Flavors

What this page covers: the three published flavors — everydatabase-core, everydatabase-standalone, everydatabase-libby — what each one puts on your classpath, the standalone relocation map, why the MySQL driver is excluded from the fat jar (GPL), how libby's loadAll and granular bundles work, and how to override or exclude dependencies. Same code, same API everywhere — they differ only in how the dependency set reaches your classpath. For the actual version numbers, see Dependency Versions & Overrides.

📌 Note — pick exactly one flavor. All three carry the same dependency set by default (HikariCP, Jackson databind + yaml, the MongoDB driver, H2, and the MySQL + PostgreSQL JDBC drivers), with one licensing-driven exception: the fat jar does not bundle the GPL MySQL driver.


The 30-second decision

repositories {
    maven { url 'https://maven.petrus.dev/public' }
    mavenCentral()
}

dependencies {
    // RECOMMENDED — full deps as normal POM dependencies; override any version yourself:
    implementation 'br.com.finalcraft.everydatabase:everydatabase-core:1.0.1'

    // OR fat jar — bundled + relocated, zero transitive deps (MySQL driver NOT bundled — GPL):
    //implementation 'br.com.finalcraft.everydatabase:everydatabase-standalone:1.0.1'

    // OR runtime download — tiny jar, the same set is fetched at runtime via Libby:
    //implementation 'br.com.finalcraft.everydatabase:everydatabase-libby:1.0.1'
}

🧭 Decisioncore when you control your own build and want to override versions the normal way (the default for almost everyone). standalone when you need a single drop-in jar that can't clash with anything else on a shared classpath (Bukkit/Paper plugins on a host with other plugins). libby when you want the smallest possible artifact and don't mind a one-time runtime download on first launch.


everydatabase-core — the recommended flavor

The library with every backend dependency declared as an ordinary POM dependency. It works out of the box, and you keep full control through standard dependency management. The POM scopes encode the API boundary:

Scope Dependencies Why
api (compile) jackson-databind, mongodb-driver-sync their types appear in public signatures (JacksonJsonCodec(Class, ObjectMapper), MongoMigration)
implementation jackson-dataformat-yaml, HikariCP internal machinery
runtimeOnly H2, mysql-connector-j, postgresql JDBC drivers — needed at runtime, not at compile time

The published everydatabase-core POM therefore carries the full runtime set — that's the point: it's the recommended flavor, and you downgrade or upgrade any of them via normal dependency management.

📌 Noteslf4j-api is compileOnly by design: the library must be shadeable without dragging a logging framework. Its runtime presence is probed reflectively (see Logging & Diagnostics). Don't promote it to implementation.

Overriding a version

Gradle picks the highest version by default; declare your own to change it. Append !! to force a downgrade. In Maven, your nearest declaration always wins.

dependencies {
    implementation 'br.com.finalcraft.everydatabase:everydatabase-core:1.0.1'

    implementation 'com.fasterxml.jackson.core:jackson-databind:2.17.2'   // upgrade Jackson
    runtimeOnly    'com.mysql:mysql-connector-j:8.4.0!!'                  // force-downgrade the MySQL driver
}

Excluding what you don't use

// Only target SQL? Drop the Mongo driver entirely:
implementation('br.com.finalcraft.everydatabase:everydatabase-core:1.0.1') {
    exclude group: 'org.mongodb'
}

⚠️ Gotcha — the H2 and HikariCP defaults are pinned to the last Java-8-compatible lines (H2 1.4.200, HikariCP 4.x). On Java 11+ you may override to H2 2.x / HikariCP 5.x, but H2 1.x and 2.x have incompatible database file formats — never swap the major over an existing embedded-file database. The exact numbers and override recipes live on Dependency Versions & Overrides.


everydatabase-standalone — the fat jar

One self-contained jar: the library plus the whole default set, shaded and relocated under br.com.finalcraft.everydatabase.libs.* so it can never clash with other versions on your classpath. Its POM declares zero dependencies — drop it in and go. The trade-off: bundled versions can't be overridden (pick core if you need that).

The relocation map

Original package Relocated to
com.zaxxer.hikari br.com.finalcraft.everydatabase.libs.hikari
com.mongodb br.com.finalcraft.everydatabase.libs.mongodb
org.bson br.com.finalcraft.everydatabase.libs.bson
com.fasterxml.jackson br.com.finalcraft.everydatabase.libs.jackson
com.fasterxml.jackson.annotation not relocated — kept at original coordinates (see below)
org.yaml.snakeyaml br.com.finalcraft.everydatabase.libs.snakeyaml
org.h2 br.com.finalcraft.everydatabase.libs.h2
org.postgresql br.com.finalcraft.everydatabase.libs.postgresql
org.checkerframework br.com.finalcraft.everydatabase.libs.checkerframework (pgjdbc transitive)
org.slf4j not relocated — bundled at original coordinates for linkage only

A few of these placements are deliberate, not incidental:

  • H2 and PostgreSQL drivers are bundled and discoverable. The merged META-INF/services/java.sql.Driver lists both relocated drivers, so DriverManager finds them normally. Because they're relocated, a host that ships its own driver version never class-clashes with the bundled ones.

  • Jackson annotations stay at their original coordinates. com.fasterxml.jackson.annotation (@JsonProperty, @JsonIgnore, @JsonCreator, @JsonFormat, …) is bundled unrelocated: annotations are matched by class identity, so the bundled (relocated) mapper honors the real annotations on your entities — no relocated imports needed.

    ⚠️ Gotcha — only the annotations are exempt. The databind-internal annotations (@JsonSerialize, @JsonDeserialize) remain relocated, and any public overload that accepts a Jackson type expects the relocated type in this flavor — e.g. JacksonJsonCodec(Class, ObjectMapper) wants br.com.finalcraft.everydatabase.libs.jackson...ObjectMapper. Use the single-arg JacksonJsonCodec(Class) and you'll never notice.

  • org.slf4j is bundled but not relocated. HikariCP hard-requires org.slf4j.Logger at class-init. On parent-first plugin classloaders (Bukkit/Paper) the host's SLF4J wins whenever it ships one, so log auto-detection keeps routing to the host. The bundled copy only provides linkage on hosts without SLF4J (logging falls back to a no-op). See Logging & Diagnostics.

The GPL MySQL exclusion

The fat jar bundles the whole default set except the MySQL/MariaDB driver. This is a licensing decision, not a size one:

🧭 Decisionmysql-connector-j is GPLv2 (with the Universal FOSS Exception). Redistributing it inside this jar would impose GPL terms on the artifact. Everything actually bundled is Apache-2.0 / BSD / MIT / MPL+EPL — safe to redistribute. So the MySQL driver stays a POM-metadata dependency in core (no redistribution) and a runtime download in libby (the end user fetches it from Maven Central — also not redistribution by this project).

Need MySQL/MariaDB with the standalone flavor? Add the driver yourself. It loads unrelocated and can't clash, since there is no bundled copy:

implementation 'br.com.finalcraft.everydatabase:everydatabase-standalone:1.0.1'
runtimeOnly    'com.mysql:mysql-connector-j:9.4.0'

everydatabase-libby — runtime download

everydatabase-core plus a small coordinator (package br.com.finalcraft.everydatabase.libby) that downloads the canonical, non-relocated libraries at runtime via Libby. Your jar stays tiny, and the POM depends on core with the transitive set excluded, so nothing heavy enters your build-time graph either.

📌 Note — Libby does not resolve transitive dependencies, so EveryDatabaseDependencies enumerates the full flat dependency tree of everydatabase-core explicitly. The versions there must stay in sync with the project's version catalog (gradle/libs.versions.toml).

Bootstrap it in your plugin's onLoad (or earliest bootstrap), before touching any storage class:

import br.com.finalcraft.everydatabase.libby.DependencyManager;
import br.com.finalcraft.everydatabase.libby.EveryDatabaseDependencies;

@Override
public void onLoad() {
    DependencyManager manager = new DependencyManager("MyPlugin", getDataFolder(), "libs");
    EveryDatabaseDependencies.loadAll(manager);   // HikariCP, Jackson, Mongo driver, H2 + both JDBC drivers
    // ... Storages.createH2(...), Storages.createMongo(...), etc. now work
}

loadAll vs the granular bundles

loadAll(manager) covers every backend: the Jackson JSON + YAML stacks, the SQL pool stack (HikariCP + slf4j-api), the embedded H2 engine, the MongoDB driver, and the JDBC drivers for MySQL/MariaDB and PostgreSQL. Slimmer setups can compose narrower bundles instead — re-listing a jar across bundles is harmless (already-downloaded files are reused, already-added classpath URLs ignored):

Bundle Loads
loadAll(manager) everything below, combined
loadJacksonJson(manager) jackson-core, jackson-annotations, jackson-databind — what JacksonJsonCodec needs
loadJacksonYaml(manager) the JSON stack plus jackson-dataformat-yaml + snakeyaml
loadSql(manager) HikariCP + slf4j-api (the shared SQL pool stack)
loadH2(manager) the SQL pool stack plus the H2 engine (driver built in)
loadMongo(manager) mongodb-driver-sync + -core + bson + bson-record-codec
loadMySqlDriver(manager) just com.mysql:mysql-connector-j
loadPostgresDriver(manager) just org.postgresql:postgresql
// Example slim setup: SQL-only against PostgreSQL, no Mongo, no YAML.
EveryDatabaseDependencies.loadJacksonJson(manager);   // codec
EveryDatabaseDependencies.loadSql(manager);           // HikariCP + slf4j-api
EveryDatabaseDependencies.loadPostgresDriver(manager);

📌 Noteeverydatabase-libby itself depends on net.byteflux:libby-core, resolved from https://repo.alessiodp.com/releases/. Add that repository to your build alongside the Maven repo above.

⚠️ Gotcha — the JDBC drivers ship in loadAll by default. If you compose granular bundles instead (e.g. loadSql), the driver is not included — pull it explicitly with loadMySqlDriver / loadPostgresDriver, or rely on a host-provided driver. loadSql gives you the pool, not the driver.


At a glance

core standalone libby
Deps reach you via normal POM bundled in the jar runtime download
Override versions? ✅ (dependency mgmt) ❌ (baked in) ✅ (edit the bundle calls)
Transitive footprint in your build full none none
MySQL/MariaDB driver POM dep (overridable) not bundled — add yourself in loadAll (or loadMySqlDriver)
Relocated to …libs.* no yes no
Needs a first-run download no no yes
Best for most projects shared classpaths / plugins smallest artifact

📌 Note — relocation in standalone means a relocation mistake would break consumers silently. The module's StandaloneSmokeTest runs against the shaded jar onlyClass.forName relocation checks, an H2 round-trip, and proof that real @JsonProperty annotations are honored by the relocated databind. The libby flavor's LibbySmokeTest exercises the coordinator with a recording fake (no network). See Running the Tests.


See also

Clone this wiki locally