As offered on the list, here is a summary of how we restructured the Maven 
modules in our
fork. The fork's groupId is com.toddysoft.db and its artifactIds start with 
"toddysoft-db-";
for Apache IoTDB the same scheme would use "iotdb-" (e.g. iotdb-core-datanode). 
Java packages
stay org.apache.iotdb.* in the fork.


1. The rules
------------

R1  artifactId = prefix + the module's directory path, segments joined with "-".
      core/datanode      -> toddysoft-db-core-datanode
      core/metrics/api   -> toddysoft-db-core-metrics-api
      rpc/runtime        -> toddysoft-db-rpc-runtime
    The root POM is <prefix>-parent; each group aggregator is <prefix>-<group>.

R2  Folder names say what a module is. They drop the project prefix (iotdb-), 
technology
    prefixes (thrift-) and suffixes the group already says (-api in the api 
group, client-
    in the client group).

R3  Six groups: api, client, core, rpc, services, examples. Test and packaging 
modules
    (architecture-test, code-coverage, distribution, integration-test, 
library-udf) stay
    at the top level.

R4  Every move is a whole module: no module was split or merged, and only one 
module
    changed its group (service-rpc, see below).

R5  Display names follow the path too: "ToddySoft DB: <Group>: <Leaf>",
    e.g. "ToddySoft DB: Core: DataNode", "ToddySoft DB: Core: Metrics: API".

R6  Not renamed: Java packages, versions, runtime names (pipe plugins such as
    iotdb-thrift-sink, configuration files, Docker host names), and package 
names published
    outside Maven (the PyPI package apache-iotdb, the AINode Python build).

Why one rule from path to artifactId:
- Today's names grew historically and mix styles. Several don't say what the 
module is:
  the DataNode is published as iotdb-server, the DataNode RPC definitions as 
iotdb-thrift,
  the session examples as client-example.
- Many artifactIds carry no project prefix at all (rest, mqtt, pipe-api, 
udf-api,
  node-commons, metrics-core, calc-commons, isession, service-rpc). In a 
distribution's
  lib/ folder or in a user's dependency tree, rest-<version>.jar or 
mqtt-<version>.jar
  doesn't say it belongs to IoTDB, and generic names can clash with other 
projects' jars.
- With one rule, a jar name tells you where the module lives, and a path tells 
you the
  jar name, with no lookup table. New modules have exactly one correct name.
- Whole-module moves keep the history: Java sources are not edited, so git 
detects every
  file as a rename. They also keep the translation between old and new layout a 
pure
  prefix mapping, which matters for anyone carrying changes across the rename.


2. The groups
-------------

iotdb-api              -> api       Plugin and extension APIs (UDF, trigger, 
pipe, external
                                    services). The iotdb- prefix is redundant 
inside the
                                    IoTDB repository.
iotdb-client           -> client    Client libraries. Same reason.
iotdb-core             -> core      Server-side modules. Same reason.
iotdb-protocol         -> rpc       These modules hold the service interfaces 
and message
                                    definitions (Thrift IDL plus generated 
code) that nodes
                                    use to call each other and that clients use 
to call the
                                    DataNode. "rpc" names the purpose, not the 
IDL
                                    technology, and is short in artifactIds. 
Rejected:
                                    "protocol" (suggests wire framing and 
serialization),
                                    "interfaces" (confused with Java 
interfaces), "idl"
                                    (names the technique), "contracts" (vague).
external-service-impl  -> services  The optional services (MQTT, REST) that 
implement
                                    api/external-service. "impl" says nothing 
about what
                                    they are.
example                -> examples  Plural, like the other group names.

Considered and rejected: moving the test and packaging modules into a build/ or 
tools/
group. It would change paths in CI files and documentation for no gain in 
clarity.


3. Every module
---------------

Format: old directory (old artifactId) -> new directory (new artifactId). 
Modules without a
note follow the rules mechanically. Notes marked * are deliberate choices 
beyond the rules.
All modules of upstream's build at the time are listed; the fork's own additions
(core/embedded, core/embedded-spring-boot) are left out.

Root
  . (iotdb-parent) -> . (toddysoft-db-parent)

api
  iotdb-api (iotdb-api)                          -> api (toddysoft-db-api)
  iotdb-api/external-api (external-api)          -> api/external 
(toddysoft-db-api-external)
      Drops the -api suffix the group already says.
  iotdb-api/external-service-api (external-service-api)
                                                 -> api/external-service 
(toddysoft-db-api-external-service)
      Same.
  iotdb-api/pipe-api (pipe-api)                  -> api/pipe 
(toddysoft-db-api-pipe)
  iotdb-api/trigger-api (trigger-api)            -> api/trigger 
(toddysoft-db-api-trigger)
  iotdb-api/udf-api (udf-api)                    -> api/udf 
(toddysoft-db-api-udf)

client
  iotdb-client (iotdb-client)                    -> client (toddysoft-db-client)
  iotdb-client/cli (iotdb-cli)                   -> client/cli 
(toddysoft-db-client-cli)
  iotdb-client/client-cpp (client-cpp)           -> client/cpp 
(toddysoft-db-client-cpp)
      * The folder names the language; client- repeats the group.
  iotdb-client/client-py (iotdb-python-api)      -> client/python 
(toddysoft-db-client-python)
      * Same. The PyPI package name apache-iotdb is unchanged.
  iotdb-client/client-go (git submodule)         -> client/go
      Path move only, .gitmodules updated.
  iotdb-client/isession (isession)               -> client/session-api 
(toddysoft-db-client-session-api)
      * The interfaces and data types of the Session API; "isession" is not a 
readable
        module name.
  iotdb-client/jdbc (iotdb-jdbc)                 -> client/jdbc 
(toddysoft-db-client-jdbc)
  iotdb-client/session (iotdb-session)           -> client/session 
(toddysoft-db-client-session)
  iotdb-client/subscription (iotdb-subscription) -> client/subscription 
(toddysoft-db-client-subscription)

core
  iotdb-core (iotdb-core)                        -> core (toddysoft-db-core)
  iotdb-core/ainode (iotdb-ainode)               -> core/ainode 
(toddysoft-db-core-ainode)
  iotdb-core/antlr (iotdb-antlr)                 -> core/grammar-tree 
(toddysoft-db-core-grammar-tree)
      * The tree-model SQL grammar. "antlr" names the tool, not the content, 
and the
        repository now has two grammars.
  iotdb-core/relational-grammar (iotdb-relational-grammar)
                                                 -> core/grammar-table 
(toddysoft-db-core-grammar-table)
      * The table-model SQL grammar, named in parallel with grammar-tree.
  iotdb-core/calc-commons (calc-commons)         -> core/calc-commons 
(toddysoft-db-core-calc-commons)
  iotdb-core/confignode (iotdb-confignode)       -> core/confignode 
(toddysoft-db-core-confignode)
  iotdb-core/consensus (iotdb-consensus)         -> core/consensus 
(toddysoft-db-core-consensus)
  iotdb-core/datanode (iotdb-server)             -> core/datanode 
(toddysoft-db-core-datanode)
      * The artifactId now says DataNode. "iotdb-server" dates from before the
        ConfigNode/DataNode split and is ambiguous today.
  iotdb-core/metrics (iotdb-metrics)             -> core/metrics 
(toddysoft-db-core-metrics)
  iotdb-core/metrics/core (metrics-core)         -> core/metrics/core 
(toddysoft-db-core-metrics-core)
      * Kept as "core". Renaming it to "impl" would clash with its package
        org.apache.iotdb.metrics.core, and metrics/api already contains a 
package named impl.
  iotdb-core/metrics/interface (metrics-interface)
                                                 -> core/metrics/api 
(toddysoft-db-core-metrics-api)
      * "interface" is a Java keyword and reads oddly in names; "api" is the 
common term.
  iotdb-core/node-commons (node-commons)         -> core/node-commons 
(toddysoft-db-core-node-commons)

rpc
  iotdb-protocol (iotdb-protocol)                -> rpc (toddysoft-db-rpc)
  iotdb-protocol/thrift-ainode (iotdb-thrift-ainode)
                                                 -> rpc/ainode 
(toddysoft-db-rpc-ainode)
  iotdb-protocol/thrift-commons (iotdb-thrift-commons)
                                                 -> rpc/commons 
(toddysoft-db-rpc-commons)
  iotdb-protocol/thrift-confignode (iotdb-thrift-confignode)
                                                 -> rpc/confignode 
(toddysoft-db-rpc-confignode)
  iotdb-protocol/thrift-consensus (iotdb-thrift-consensus)
                                                 -> rpc/consensus 
(toddysoft-db-rpc-consensus)
  iotdb-protocol/thrift-datanode (iotdb-thrift)  -> rpc/datanode 
(toddysoft-db-rpc-datanode)
      * The old artifactId never said "datanode", although this module holds 
the client and
        DataNode-internal service interfaces.
  iotdb-client/service-rpc (service-rpc)         -> rpc/runtime 
(toddysoft-db-rpc-runtime)
      * The only change of group. It is the shared RPC runtime (status codes, 
RpcUtils,
        transports, connection exceptions). Clients and servers both use it, 
and it depends
        only on the rpc definitions, so it belongs with them rather than in 
client.

services
  external-service-impl (external-service-impl)  -> services 
(toddysoft-db-services)
  external-service-impl/mqtt (mqtt)              -> services/mqtt 
(toddysoft-db-services-mqtt)
  external-service-impl/rest (rest)              -> services/rest 
(toddysoft-db-services-rest)
  external-service-impl/rest-openapi (rest-openapi)
                                                 -> services/rest-openapi 
(toddysoft-db-services-rest-openapi)
      The bare artifactIds mqtt, rest and rest-openapi were the clearest case 
of jar names
      that don't identify the project (e.g. 
mqtt-<version>-jar-with-dependencies.jar).

examples
  example (iotdb-examples)                       -> examples 
(toddysoft-db-examples)
  example/jdbc (jdbc-example)                    -> examples/jdbc 
(toddysoft-db-examples-jdbc)
  example/mqtt (mqtt-example)                    -> examples/mqtt 
(toddysoft-db-examples-mqtt)
  example/mqtt-customize (customize-mqtt-example)
                                                 -> examples/mqtt-customize 
(toddysoft-db-examples-mqtt-customize)
  example/pipe-count-point-processor (pipe-count-point-processor-example)
                                                 -> 
examples/pipe-count-point-processor 
(toddysoft-db-examples-pipe-count-point-processor)
  example/rest-java-example (rest-java-example)  -> examples/rest 
(toddysoft-db-examples-rest)
      * Drops "-java-example", which the group already says.
  example/schema (schema-example)                -> examples/schema 
(toddysoft-db-examples-schema)
  example/session (client-example)               -> examples/session 
(toddysoft-db-examples-session)
      * The old artifactId said "client", the folder said "session".
  example/subscription (subscription-example)    -> examples/subscription 
(toddysoft-db-examples-subscription)
  example/trigger (trigger-example)              -> examples/trigger 
(toddysoft-db-examples-trigger)
  example/udf (udf-example)                      -> examples/udf 
(toddysoft-db-examples-udf)
  The non-Maven folders in example/ (client-cpp-example, odbc, pipe-opc-ua-sink,
  rest-client-c-example) moved with the group unchanged.

Top-level test and packaging modules (folders unchanged, artifactIds prefixed)
  architecture-test (iotdb-architecture-test)    -> 
toddysoft-db-architecture-test
  code-coverage (iotdb-code-coverage)            -> toddysoft-db-code-coverage
  distribution (iotdb-distribution)              -> toddysoft-db-distribution
  integration-test (integration-test)            -> 
toddysoft-db-integration-test
  library-udf (library-udf)                      -> toddysoft-db-library-udf

Derived names
  Distribution archives  apache-iotdb-<version>-<variant>-bin.zip -> 
toddysoft-db-<version>-<variant>-bin.zip
                         (for IoTDB itself these would of course stay 
apache-iotdb-...)
  Jars in lib/           <old artifactId>-<version>.jar -> <new 
artifactId>-<version>.jar


4. What to watch out for (from doing it)
-----------------------------------------

- It cannot be a global text replace. Several runtime names look like module 
names but
  must not change: the pipe plugins iotdb-thrift-sink / iotdb-thrift-connector, 
the PyPI
  package apache-iotdb, the AINode Python packaging apache-iotdb-ainode-..., 
the Docker
  service and host names iotdb-confignode / iotdb-datanode, configuration file 
names
  (iotdb-system.properties), and binary test fixtures such as udf-example.jar.
- Module names are referenced far beyond the POMs: distribution and IT assembly
  descriptors, Dockerfiles, CI workflows, the C++ client's CMake paths to the 
.thrift files,
  the coverage scripts, README/AGENTS files, and IT framework code. One 
example: the IT
  framework found the DataNode jar with startsWith("iotdb-server").
- Apache RAT excludes are relative to the module being checked, so an exclude 
like
  **/client-cpp/test/fixtures/** has to be adapted to the new folder name as 
well.
- Client artifacts are public API. iotdb-session, iotdb-jdbc, isession, 
service-rpc and
  the thrift artifacts are used by applications from Maven Central. Our fork 
could rename
  them without relocation POMs; for Apache IoTDB, renaming them would need 
relocation POMs
  for at least a few releases, or those artifactIds would have to keep their 
names.
- We did it in one commit (moves and edits together) directly on top of an 
upstream sync,
  so the build was never broken in between, and kept a machine-readable 
old-to-new mapping
  for later syncs.

So that was just the structural changes I did ... I'm happy to whip up a PR for 
javax-> jakarta, if the project is interested.
Thanks to Claude whipping up a PR from a structurally totally different 
codebase is still possible ;-)

Chris





Yuan Tian <[email protected]> schrieb am Mittwoch, 4. November 2026 um 
00:56:

> Hi Chris,
> 
> Thanks for sharing your work. I think several of these changes could be
> valuable to the IoTDB community.
> 
> For the migration from javax to Jakarta, I think this is worth exploring,
> especially to make it easier to integrate IoTDB into Spring applications.
> Could you share which modules and APIs are affected, as well as any
> compatibility considerations for existing users?
> 
> Regarding direct calls within the same JVM, the current IoTDB Edge already
> runs the ConfigNode and DataNode in the same JVM, although some
> communication between them still uses RPC. The DataNode also maintains
> caches for partition information and table schemas, so I would expect the
> amount of ConfigNode communication to be relatively limited in a stable
> single-node deployment with one ConfigNode and one DataNode.
> 
> It would be helpful to see some performance numbers for the direct-call
> approach. For example, which RPC paths did you replace, and how much
> improvement did you observe for representative workloads? It would also be
> useful to understand whether the changes affect any existing behavior or
> consistency guarantees.
> 
> For the directory and module restructuring, could you clarify whether these
> changes are mainly intended to support the direct-call approach, or whether
> they also have independent benefits? If possible, it would be helpful to
> discuss or review the changes separately.
> 
> I am particularly interested in reducing the use of singletons, as I
> believe this could help improve unit test isolation and make dependencies
> easier to replace. I would be happy to participate in this work as well. It
> would be great to learn more about your approach and see a representative
> example of the changes.
> 
> 
> Best regards,
> 
> ------------------------
> 
> Yuan Tian
> 
> 
> 
> On Sun, Nov 1, 2026 at 6:51 PM Christofer Dutz via dev <[email protected]>
> wrote:
> 
> > Hi all,
> >
> > so in the next time I'll be finally working on getting IoTDB into shape so
> > I can integrate it into my vision of an idustrial edge gateway.
> > I've so-far migrated to Java 17 (which IoTDB now also is back on par) ...
> > I've migrated from the javax to the jakarta namespace, so I can integrate
> > IoTDB into Spring applications.
> > I've introduced a "direct call if single-node and all nodes running inside
> > the same JVM".
> >
> > Now I'm currently cleaning up on the directory structure, location where
> > modules are located and their artifact-ids.
> >
> > The next big thing I have on my todo list is: "Getting rid of the
> > Singletons"
> >
> > Just wanted to know if there's any interest in any of this upstream? I
> > don't want my stuff to be a "hostile fork" and I'm happy to pass upstream
> > what I have.
> > Doesn't have to be PRs, could also post summaries of findings. But I guess
> > that's all extra work. So if there's no interest, I guess I'd rather invest
> > this into doing other things ;-)
> >
> > Chris
>

Reply via email to