# ion-java: a Java implementation of the Ion data notation

> ion-java is the Java implementation of Amazon's Ion data notation, published to Maven Central under com.amazon.ion and built with Gradle against a submodule of conformance test data. The interesting decision for a user is not the parser but the in-memory model, since the maintainers now recommend a separate Kotlin library over the classic IonValue tree.

**amazon-ion/ion-java** —  Java streaming parser/serializer for Ion. 

- Repository: https://github.com/amazon-ion/ion-java
- Website: https://amazon-ion.github.io/ion-docs/
- Stars: 878 · Forks: 134
- Language: Java
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/amazon-ion-ion-java

## What ion-java actually implements

Ion is a data notation, and ion-java is its Java implementation. The README describes the project in one line and links to the notation's documentation at amazon-ion.github.io/ion-docs, so the format itself is specified elsewhere and this repository is the reference binding for the JVM.

The description calls it a streaming parser and serializer for Ion, and that phrase carries the important design decision. A streaming parser reads a byte sequence and hands back values one at a time, so a document that does not fit in memory can still be processed. The serializer side writes the same notation back out. Any application that needs to speak Ion over a wire, in a file or between services ends up needing both directions, and this library is the Java answer to that need.

The repository is Apache-2.0 licensed, and the licence handling is thorough enough to be worth noting: the tree contains LICENSE, NOTICE and THIRD_PARTY_LICENSES.md, plus a CODE_OF_CONDUCT.md and a CONTRIBUTING.md. A NOTICE file and a third-party licence inventory are what you find in a library intended for redistribution inside larger products, and reading them is a normal part of a dependency review.

At the top level the source lives under src/, alongside a dedicated ion-java-cli directory and two test driver scripts, with the Gradle build files build.gradle.kts and settings.gradle.kts and a project.version file that holds the version number.

## Building from source: the ion-tests submodule and a Gradle publish to the local repository

The build has one wrinkle that catches people out. The repository contains a git submodule called ion-tests holding the test data used by the unit tests, so a plain clone leaves you without it. The README gives the recursive clone as the easy path:

```bash
$ git clone --recursive https://github.com/amazon-ion/ion-java.git ion-java
```

If the repository is already on disk, the submodule can be initialised separately:

```bash
$ git submodule init
$ git submodule update
```

The submodule resolves to the tip of a branch of the ion-tests repository, and which branch is decided by the .gitmodules file in ion-java. After that, the library is built and installed into the local Maven repository with a single Gradle task:

```bash
$ ./gradlew publishToMavenLocal
```

The wrapper scripts gradlew and gradlew.bat are checked in, so the build does not assume a particular Gradle version is installed on the machine. The gradle/ directory and gradle.properties hold the rest of the build configuration, and config/ holds the tooling configuration.

Pulling upstream changes later has the same two-step shape, because a plain pull does not touch the submodule:

```bash
$ git submodule update --remote
```

That fetches the submodule from the branch currently named in .gitmodules, which is the behaviour to rely on if the upstream test data branch is ever changed.

## Depending on ion-java and the group id that changed in 1.4.0

For most users the library arrives as a dependency rather than a source build. The README points at the ion-java page on Maven Central, where snippets for adding the dependency are available for whichever build tool you use. The coordinates are com.amazon.ion for the group and ion-java for the artifact.

There is a wrinkle worth catching early, because it is the kind of thing that only shows up as a dependency resolution failure. The README records that ion-java was originally published under the group id software.amazon.ion, and that since version 1.4.0 the official groupId was changed to com.amazon.ion to stay consistent with other Amazon open source libraries. The legacy group id is still maintained, but the README strongly encourages migrating to the official one.

If you are picking up an existing build, check what it declares before you change anything. A project pinned to software.amazon.ion will keep working, so a failing build is unlikely to be the cause, but you will be resolving an artifact the maintainers consider legacy. The reverse situation is more disruptive: moving a build from the legacy group id to the official one changes which coordinates are resolved and will pull in the newer versioning line.

The project also publishes javadoc, and the README points at the javadoc.io entry for the artifact for detailed information on how to use the library.

## The decision that matters most: IonValue or IonElement

This is the part of the README with the strongest opinion in it, and it is worth reading before writing any code.

ion-java provides an in-memory data model called IonValue, a tree of mutable nodes that mirror the structure of the document. The README says plainly that if you are looking for an in-memory Ion data model you should consider using IonElement from the separate ion-element-kotlin project instead, and that IonElement is the better choice as long as you can live within its limitations. The Ion maintainers recommend using IonElement instead of IonValue whenever possible.

The advantages are concrete. IonElement has significantly less memory overhead than IonValue. It is immutable and holds no references to parent values, which makes it always thread-safe, and unlike IonValue there is no need to make deep copies of an element before handing it around. That last point removes a class of defensive copying that shows up in any code sharing parsed documents between threads.

The limitations are equally concrete and equally important. IonElement does not support symbols with unknown text. It brings a dependency on the Kotlin Stdlib, which matters in a Java-only build. And if your application relies on being able to access the parent container of a value, you will have to change that logic, because IonElement has no parent reference to walk up to. The trade is a smaller, safer, immutable model traded against three capabilities that some applications genuinely need.

## The conformance test drivers in the repository root

Two executables at the root, ion-test-driver-setup and ion-test-driver-run, are the part of the tree that speaks most directly to what this library is for.

The naming suggests the flow. The setup script prepares an environment, and the run script executes against it. The test data itself lives in the ion-tests submodule, the same submodule the unit tests consume, which means the drivers and the unit tests are working from one shared corpus rather than from separate fixtures. For a notation with as many edge cases as Ion, where symbol tables, annotations and type markers all have to interoperate exactly, a single shared corpus is worth having.

The ion-java-cli directory sits alongside them, which indicates that the library also ships a command line front end rather than only a programmatic API.

Taken together with the submodule arrangement, the picture is of a library built to a specification rather than to a set of examples. The documentation site is the same project family, amazon-ion.github.io, and the README points to the Ion cookbook there as the recommended way to get started with the format itself before you get into the Java API. The README also links a page titled "Why is IonElement needed?" in the ion-element-kotlin repository, which is the maintainers' longer argument for the model choice described above.

## Limits worth knowing before you commit

The first limit is the group id history. Any long-lived build that has carried software.amazon.ion since before version 1.4.0 is resolving a coordinate the maintainers label legacy, and the README asks users to migrate. That is a low-effort change but it touches your dependency management and your lock files, so it is best done deliberately.

The second limit is the one the README raises about IonElement, and it applies to whichever model you pick depending on your application. If your code needs to walk up from a value to its containing list or struct, IonElement cannot do it and IonValue can. If your documents contain symbols whose text is not known at parse time, IonElement does not support them. And bringing the Kotlin Stdlib into a build that was deliberately Java-only is a dependency decision with its own consequences, from licence review to build image size.

The third is simply the shape of the library. ion-java is a parser and serializer, with an in-memory tree on top. It is not a schema validator, not a query language and not a document database. If you need those, the notation documentation and the cookbook are where the ecosystem is described, and this repository will not provide them.

Finally, the CLI is mentioned in the repository layout but not described in the README, so do not assume what it does beyond the fact that it exists.

## Alternatives to ion-java, and what the choice turns on

The alternative the project itself puts in front of you is ion-element-kotlin, the Kotlin library that provides IonElement. The difference in approach is not the notation, which is the same, but the shape of the object model you program against. IonValue is a mutable tree of nodes that mirror the document structure, so it can express parent relationships and be modified in place, at the cost of shared-state hazards and deep copies when values move between threads. IonElement is a small immutable tree with no links upwards, so it is cheaper in memory and safe to share, and in exchange you give up parent access, unknown-text symbols and get a Kotlin dependency.

For a read-mostly service that parses a document, hands the result to several consumers and moves on, IonElement is the better shape and the maintainers say so. For an application that edits a document in place, or that has to resolve a symbol table entry whose text is unknown, IonValue remains the only one of the two that works.

The other alternative is not a library but a discipline: skipping the in-memory model entirely and streaming values through as they are parsed. Since ion-java is a streaming parser, a pipeline that never holds the whole document in memory avoids the memory and copying questions above altogether. The cost is that you lose random access to values, so any step that needs to revisit an earlier part of the document forces you to buffer it, which is the situation IonValue and IonElement are designed for.

Whichever route you take, the notation itself and the cookbook are the common ground, and the Maven Central artifact with a stable coordinate is the common dependency.

## Release rhythm and the state of the repository

The library is actively maintained. The last push to the repository was on 2026-09-07, and the release line moved steadily through the year: v1.11.11 on 2025-10-15, v1.12.0 on 2026-06-24 and v1.12.1 on 2026-09-03, a patch release more than two months after the minor one.

The default branch is master rather than main, which is worth knowing if you write automation against the repository. The version number itself is kept in a project.version file at the root rather than being hardcoded in the build script, which is a small thing that matters if you consume the tree directly instead of taking the Maven Central artifact.

For an Apache-2.0 library with a NOTICE file and a third-party licence inventory, adoption into commercial products is straightforward as a matter of reading the licence text. You keep the notices with the copies you redistribute, and the THIRD_PARTY_LICENSES.md file tells you what the library itself depends on, which is the document to check when a licence review asks about transitive components.

Given the release cadence, the sensible starting point is the latest version on Maven Central rather than a build of the default branch, and a decision about the data model before the first line of parsing code is written.

## Conclusion

Adopt ion-java when you need to read or write Ion data from Java code and you want a library that ships conformance test drivers and a Maven Central artifact with a stable Apache-2.0 licence. Do not build new code around IonValue if you can avoid it, since the maintainers steer new work towards IonElement from ion-element-kotlin for its lower memory cost and immutability. Verify first that your build resolves the com.amazon.ion group id, not the legacy software.amazon.ion one, and that you are not relying on symbols with unknown text or on reaching a parent container, both of which IonElement does not support.

## FAQ

### How do I add ion-java to a Maven or Gradle build?

The artifact is published on Maven Central as com.amazon.ion:ion-java, and the README points there for snippets for whichever build tool you use. The older group id software.amazon.ion is still maintained but the README strongly encourages migrating to com.amazon.ion.

### What is the difference between IonValue and IonElement?

IonValue is the in-memory model provided by ion-java, a mutable tree that can reference its parents. IonElement comes from the separate ion-element-kotlin library, has lower memory overhead, is immutable and therefore thread-safe, but it does not support symbols with unknown text, has no parent references, and pulls in the Kotlin Stdlib.

### How do I build ion-java from source and run its tests?

The repository carries an ion-tests git submodule with the shared test data, so you need a recursive clone or an explicit git submodule init and git submodule update. After that the README builds and installs it into the local Maven repository with ./gradlew publishToMavenLocal.

## Sources

- [amazon-ion/ion-java on GitHub](https://github.com/amazon-ion/ion-java)
- [License: Apache-2.0](https://github.com/amazon-ion/ion-java/blob/master/LICENSE)
- [Project website](https://amazon-ion.github.io/ion-docs/)
- [README](https://github.com/amazon-ion/ion-java/blob/master/README.md)
- [Releases](https://github.com/amazon-ion/ion-java/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/amazon-ion-ion-java
