Diagnosing Ceylon Module Resolution Failures and Version Conflicts (1.3.3)
A diagnostic guide to Ceylon 1.3.3 module resolution failures: repository order, version range conflicts, stale caches, invalid .car archives, and Java interop native imports.
15 Dec 2025, 15:24 UTC

If your Ceylon build fails with "module not found", "invalid module archive", or compiles cleanly but throws NoClassDefFoundError at runtime, the cause is almost always one of four things: repository configuration, version range conflicts, stale caches, or a broken Java interop declaration. This guide walks through each condition and its fix.
Context matters here: Ceylon 1.3.3 (2017) is the final release. The language is archived, the Herd repository is offline, and no fixes are coming. Everything below applies to maintaining existing Ceylon codebases. For new projects, migrate rather than build on Ceylon.
Recognizing the failure
Module resolution problems surface at three distinct points, and the symptom tells you where to look:
| Symptom | Phase | Likely cause |
|---|---|---|
module not found at compile time | Resolution | Missing repository, offline Herd dependency, or stale cache |
| Version conflict / ambiguous dependency error | Resolution | Incompatible version ranges in a diamond dependency |
invalid module archive | Loading | .car file with missing or mismatched module descriptor |
NoClassDefFoundError at runtime after clean compile | Runtime | Missing or mismatched native import for a Java module |
| Editor errors but CLI build succeeds | IDE | Eclipse plugin's embedded compiler differs from CLI tools |
Ordered checks
Work through these in order; each is cheap and rules out a class of causes.
- Confirm the toolchain version. Run
ceylon --versionin your shell. This guide assumes 1.3.3. Mixed tool versions on the same machine produce confusing, inconsistent errors. - Clear the cache. Run
ceylon clean, then rebuild. The compiler and runtime share a cache under~/.ceylon/cache, and stale entries survive repository changes. This requires no special permissions and is safe — the cache is repopulated on the next build. - Inspect repository order. Check
~/.ceylon/configand any project-level.ceylon/config. Maven Central should be listed before any Herd mirror. Herd itself has been offline for years, so any entry pointing at the original Herd URL will time out or fail; replace it with a local mirror if you still need Herd-only modules. - Read module.ceylon carefully. Verify every
shared importhas a version range that actually overlaps with the ranges required by your other dependencies. Ceylon enforces semantic versioning and selects the highest compatible version — but it cannot satisfy two ranges that don't intersect. - Validate the archive. For a locally built or converted module, run
ceylon print-module-archive yourmodule-1.0.0.carand confirm the embedded descriptor's name and version match the file name. A JAR manually repackaged as a .car without a propermodule.ceylondescriptor is the classic source of "invalid module archive".
Fixes tied to findings
Diamond version conflicts
If module A needs shared import lib "1.2.0..2.0.0" and module B needs lib "2.1.0", resolution fails because no single version satisfies both. The fix is to widen or narrow one range in your own module.ceylon so the intersection is non-empty, then rebuild after ceylon clean. If the conflicting module is third-party and unmaintained (common, given the ecosystem is frozen), you may need to build a patched copy locally with a corrected descriptor.
Java interop and native imports
Compilation succeeding while runtime throws NoClassDefFoundError almost always means a Java dependency was visible to the compiler but not declared as a native module import, so it never made it onto the runtime module path. Add the explicit native import, e.g.:
native("jvm")
module my.app "1.0.0" {
shared import java.base "8";
import maven:"org.apache.commons:commons-lang3" "3.5";
}Two caveats: the native("jvm") annotation restricts the module to the JVM backend, and Ceylon predates the Java 9 module system. Ceylon does not understand JPMS automatic modules, so run on a JDK 8-era toolchain if possible; on newer JDKs expect additional classpath friction.
Herd-only legacy modules
If resolution fails only for older community modules, they were probably hosted exclusively on Herd. The practical fix is to obtain the .car from an archive or mirror, place it in a local repository directory, and register that directory in .ceylon/config ahead of remote repositories. Verify the archive with ceylon print-module-archive before trusting it.
IDE false positives
The Eclipse and IntelliJ plugins are unmaintained and embed their own compiler. If the editor reports resolution errors but ceylon compile succeeds, trust the CLI. Treat IDE diagnostics as advisory only, and disable the plugin's builder if it interferes.
Escalation criteria
Stop troubleshooting and reconsider the platform when: the failing module exists only on Herd and no mirror copy can be located; the conflict is inside a third-party module you cannot rebuild; or the build must run on a modern JDK where JPMS assumptions break Ceylon's native module model. At that point the engineering-sound move is migrating the affected module to Kotlin or Java rather than layering more workarounds onto an archived toolchain.
Verifying the fix
After any change: run ceylon clean, then ceylon compile, then actually execute with ceylon run my.app/1.0.0. Compile success alone is not proof — the native-import class of bug only appears at runtime. A green compile plus a clean run against the real dependency set is the meaningful check.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.