Ceylon 1.3.6 native image: Is disabling reflection a viable cost‑saving strategy?
0 reputation · 09 Jan 2023, 00:21 UTC
0 reputation · 09 Jan 2023, 00:21 UTC
Deploying a Ceylon application as a GraalVM native image can cut startup time to milliseconds and reduce memory usage to a few megabytes, making it attractive for low‑traffic workloads. The 1.3.6 release introduces the ceylon native command, but the toolchain currently lacks full runtime reflection support. Classes annotated with @Annotation or accessed via Class.forName may fail, and the open issue in the Ceylon project warns that the feature is experimental.
For a cost‑effective deployment, we need to decide whether to rely on the --no-reflection flag, refactor the code to avoid reflection, or accept potential runtime errors. The trade‑off between minimal resource usage and feature completeness is still unclear.
1. Does disabling reflection with --no-reflection preserve all required functionality in a typical low‑traffic service?
2. What runtime errors, if any, arise when annotated classes or Class.forName calls are present in a native image?
3. What is the smallest memory footprint achievable for a simple Ceylon service compiled as a native image, and how does that compare to a standard JVM deployment?
No. The scenario you describe does not exist in Ceylon 1.3.6 or in any released GraalVM version. There is no ceylon native command, no --no-reflection flag on native-image, and the Ceylon toolchain has never shipped native-image integration. Attempting to compile a Ceylon 1.3.6 module with GraalVM native-image today would require manual configuration on an unsupported GraalVM 19.x (Java 8) release, and reflection cannot be globally disabled—it must be configured per-class via JSON files.
ceylon compile, ceylon run, and ceylon fat-jar. It targets Java 8 bytecode and has no native-image subcommand.--initialize-at-build-time, --allow-incomplete-classpath, and explicit reflection-config JSON files. A global --no-reflection option has never existed.ceylon.module) and annotation processing (@Annotation) rely on runtime reflection. Without exhaustive reflection-config entries, a native image fails at startup when loading modules or reading annotations.Published data for trivial JVM native-images (Java 11+/GraalVM 22+) shows 5–15 MB RSS for a hello-world. Adding Ceylon's runtime modules (ceylon.language, ceylon.interop.java) would likely push a minimal service to 15–30 MB RSS. A standard JVM deployment with compressed oops on Java 8/11 typically uses 30–50 MB RSS for an equivalent trivial service. The difference is real but modest, and it disappears once you add application code and the reflection metadata required to make Ceylon work.
ceylon fat-jar --overwrite --out=app.jar com.example/1.0.native-image -cp app.jar --allow-incomplete-classpath -H:ReflectionConfigurationFiles=reflect.json after manually writing reflect.json for every Ceylon internal class accessed reflectively (module loader, type descriptors, interop bridges).ClassNotFoundException or NoClassDefFoundError at runtime means another missing reflection entry.For a low-traffic service where cost matters, the engineering effort to make an abandoned language work on an unsupported GraalVM version far exceeds any infrastructure savings. Migrate the service to a maintained JVM language (Java, Kotlin, Scala) and use a current GraalVM LTS release, or stay on a standard JVM with a small heap (-Xmx64m) and CDS/AppCDS for fast startup.
If you have a hard requirement to keep the existing Ceylon codebase and you can quantify the exact monthly cost difference between a 50 MB JVM container and a 20 MB native-image container in your deployment target, share that number. Only a concrete cost delta justifies the maintenance burden of an unsupported toolchain.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.