Search code examples
javainteropceylon

Interoperability between Ceylon and Java: How to share an import from 'ceylon.language'


I'm trying to epose a ceylon class derived from ceylon.interop.java { CeylonList } to a java unit (in ceylon terms this would be called a module, but java hasn't that yet) outside the ceylon module that contains this derived ceylon class.

run.ceylon:

import java.util {
    JList=List
}

import ceylon.interop.java {
    CeylonList
}

// CL is deliberately annotated as 'shared' - this is the crucial point !!
shared class CL(JList<out Integer> jil) extends CeylonList<Integer>(jil) {}

To make the imported modules visible on the java side I annotate the imported modules in the module descriptor as 'shared'.

module.ceylon:

native ("jvm") module com.example.simple "1.0.0" {
    shared import "java.base" "8";
    shared import ceylon.collection "1.2.2";
    shared import ceylon.interop.java "1.2.2";
}

But the compiler still reports errors:

source/com/example/simple/run.ceylon:18: error: supertype of type 'CL' that is visible outside this module comes from an imported module that is not re-exported: 'Collection<Integer>' involves an unexported type declaration
shared class CL(JList<out Integer> jil) extends CeylonList<Integer>(jil) {}
                 ^
source/com/example/simple/run.ceylon:18: error: supertype of type 'CL' that is visible outside this module comes from an imported module that is not re-exported: 'List<Integer>' involves an unexported type declaration
shared class CL(JList<out Integer> jil) extends CeylonList<Integer>(jil) {}
                 ^
source/com/example/simple/run.ceylon:18: error: supertype of type 'CL' that is visible outside this module comes from an imported module that is not re-exported: 'Correspondence<Integer,Integer>' involves an unexported type declaration
shared class CL(JList<out Integer> jil) extends CeylonList<Integer>(jil) {}
                 ^
source/com/example/simple/run.ceylon:18: error: supertype of type 'CL' that is visible outside this module comes from an imported module that is not re-exported: 'Ranged<Integer,Integer,List<Integer>>' involves an unexported type declaration
shared class CL(JList<out Integer> jil) extends CeylonList<Integer>(jil) {}

A solution should be to re-export ceylon.language

...
    shared import ceylon.language "1.2.2";
...

But on the one hand ceylon.language isn't allowed to be imported at all and so it cannot be annotated neither re-exported.

On the other hand I cannot discover any '... imported module that is not re-exported ...' because all imported modules are annotated as shared.

Aside: The class CL from run.ceylon is then imported and used in Use.java

Use.java:

package some.other.package
// And thus some.other.module if there were

import com.example.simple.*;
import java.util.* ;

public class  Use{
  public static void main (String[] args) {

    LinkedList ll = new LinkedList();
    ll.add(1);
    ll.add(2);

    CL c = new CL(ll);

  }
}

The question is now (referring to the error messages above), 1. what supertype of type 'CL' is visible outside this module and comes from an imported module that is not re-exported, and 2. how to re-export it?


Solution

  • In Ceylon 1.2.2, your example won't work, since Java code cannot consume Ceylon declarations in the same module.

    In the yet-to-be-released Ceylon 1.2.3, this should be supported, but I get the same errors as you, and don't see anything wrong with the example code.