Guide: Using Ceylon’s Null‑Safe Types When Calling Java Libraries
Learn how to interoperate with Java code in Ceylon while leveraging its compile‑time null safety to avoid NullPointerExceptions.
04 Sept 2025, 06:26 UTC

Desired outcome
You have a Ceylon module that can call a Java library, treat any values that may be null as explicit nullable types, and guarantee that resources such as streams or connections are closed reliably. After following this guide you will be able to compile the module without null‑related warnings and run it without encountering a NullPointerException caused by the Java side.
Prerequisites
- Java Development Kit (JDK) version 8 or newer installed and
java -versionreturns a valid version. - Ceylon SDK version 1.3.3 (or any 1.x release) installed; the
ceyloncommand is available on your PATH. - A Java library you wish to use, provided as a JAR file or Maven artifact. For the example we assume a library named
example-java-libversion1.0.0that provides a classcom.example.JavaServicewith a methodString getData()that may returnnull. - Basic familiarity with editing text files and running commands in a terminal.
Procedure
-
Create a new Ceylon project
Choose a directory for your work, e.g.,
~/ceylon-java-interop. Inside that directory run the Ceylon project initializer:ceylon new com.example.myprojectThis creates a module descriptor
module.ceylonand a source layoutsrc/com/example/myproject. Adjust the module name if you prefer a different identifier. -
Add the Java library as a dependency
Edit
module.ceylonto declare a dependency on the Java JAR. If the library is available in a Maven‑compatible repository you can use theimport mavendirective; otherwise place the JAR in alibfolder and reference it with aimport javaclause.// module.ceylon module com.example.myproject "1.0.0" { import java.base "8"; import maven "example-java-lib" "1.0.0"; // if using a local JAR: // import java "lib/example-java-lib.jar"; }Save the file.
-
Write Ceylon code that calls the Java method safely
Create a source file
src/com/example/myproject/run.ceylonwith the following content. The key points are:- The return type of
getData()is declared asString?(nullable) to reflect that the Java method may producenull. - We use a
doblock to manage ajava.io.FileWriterresource, ensuring it is closed even if an error occurs. - Pattern matching (
exists) checks for a non‑null value before using it.
// run.ceylon import com.example.JavaService import java.io { FileWriter } void run() { // Create an instance of the Java class JavaService service = JavaService(); // Call the Java method; the Ceylon compiler treats the result as nullable String? raw = service.getData(); // Safely handle the possible null if (exists raw) { // Use the non‑null value println("Received data: " + raw); // Example resource management with a 'do' block do (FileWriter fw = FileWriter("output.txt")) { fw.write(raw); fw.write("\n"); } // fw is automatically closed here } else { println("Java service returned null; nothing to write."); } } // Module entry point shared void hello() { run(); }Save the file.
- The return type of
-
Compile the module
From the project root run:
ceylon compile com.example.myprojectIf the Java library is not on the classpath, the compiler will emit an error about missing types. Ensure the JAR is reachable via the Maven repository or the
libfolder as described in step 2. -
Run the compiled module
Execute:
ceylon run com.example.myprojectObserve the console output. If the Java method returns a non‑null string, you should see the message "Received data: …" and the file
output.txtcreated with that content. If it returnsnull, you will see the "Java service returned null" message and no file will be created.
Expected checks
- Compilation finishes with exit code 0 and no warnings about possible null dereferences.
- At runtime, the program does not throw a
NullPointerExceptionoriginating from the Java call. - When the Java method returns a non‑null value, the file
output.txtcontains exactly that value followed by a newline. - When the Java method returns
null, no file is created and the program terminates normally.
Recovery options
If you need to revert changes:
- Delete the generated
output.txtfile (if it exists). - Remove the project directory
~/ceylon-java-interopto erase all source, compiled binaries, and dependency caches. - Optionally, uninstall the Ceylon SDK if you no longer need it, though this is not required for simple cleanup.
These steps return the workspace to its pre‑guide state.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.