EE-mode
Since Ceylon 1.3.1 the JVM compiler has had a special "EE-mode" to ease interoperability with Java-EE-like environments where classes are instantiated and manipulated by frameworks.
final method modifier
          
          
          
          Normally the ceylon compiler wil generate final methods for elements which subclasses should
          not be able to override. This makes it safer to subclass a Ceylon class in Java.
In EE mode, classes are generated without having the final modifier on their methods.
The rationale for this is to make these classes proxiable by runtime bytecode generation.
public nullary constructor
          
          
          
          Normally the Ceylon compiler will generate a nullary constructor because
          Ceylon classes are implicitly java.io.Serializable,
          and so must have a non-private nullary constructor.
In EE mode, this constructor is made public.
The rationale for this is to make classes usable with JAX-RS.
late initialization checking
          
          
          
          Normally the Ceylon compiler will add runtime checks to the getters and setters for late
          attributes to prevent those attributes from being used before they've been initialized,
          or to prevent them from being reinitialized if they're not variable.
          In many cases this runtime check can simply use the null-ness of the underlying field to
          detect access before initialization, or reinitialization. In other cases, specifically
          when the attribute gets transformed into a primitive-typed field, or the attribute has a nullable type,
          it is necessary to use an extra boolean field to track the initialization of the attribute's field.
In EE mode the compiler omits runtime initialization checks which would require an
          extra boolean field.
The rationale for this is that frameworks will inject the attribute directly into the field (not via the setter), and don't know about the boolean state tracking field, meaning that without EE-mode a Ceylon class would incorrectly throw an initialization exception.
Java types for "optional primitive" fields
Normally the Ceylon compiler will tranform an attribute of type Integer to a long field, and an attribute of type
          Integer? to a field of type ceylon.language.Integer (which, being a reference type, can be null). Similarly Ceylon
          boxes are also used for String?, Float?, Character?, Boolean? and Byte?
          (see type mapping for details).
In EE mode such fields are of the equivalent Java boxed primitive types
          java.lang.Long, java.lang.String, java.lang.Double, java.lang.Character,
          java.lang.Boolean and java.lang.Byte respectively.
The rationale for this is that frameworks injecting field state typcially understand these types without needing special adapter classes to be written.
Java types for List, Set and Map
          
          
          
          Normally the Ceylon compiler will transform an attribute of type ceylon.language::List<Element>
          to a field of that type. Likewise ceylon.language::Set<Element> and ceylon.language::Map<Key,Item> .
In EE mode such fields are of type java.util.List, java.util.Set and java.util.Map respectively.
          The compiler wraps a Ceylon collection in an adapter on set and unwraps, or rewraps on get.
          Such wrapping and rewrapping applies to arbitrary nesting of these collections, so long as the
          static types are ceylon.language::List<Element>, ceylon.language::Set<Element> or ceylon.language::Map<Key,Item> .
Moreover an attribute of static type ceylon.language::List<Integer>  is stored in a field of type
          java.util.List<java.lang.Long>, and likewise for the other "primitive" types and the other
          collections.
For example:
class Example() {
    shared late List<Integer> list; // java.util.List<java.lang.Long>
    shared late Map<String, List<String>> map; // java.util.Map<java.lang.String, java.util.List<java.lang.String>>
    shared late MutableSet<String> set; // EE-mode mapping does not apply, because the static type is not Set
}
The rationale for this is that frameworks injecting field state typcially understand these types without needing special adapter classes to be written.
Activating EE mode
EE mode is activated for all classes in a module when javax.javaeeapi or equivalently  maven:javax:"javaee-api" (any version) is imported in the module.ceylon.
EE mode is also activated for a class when that class is annotated with any of the following:
- javax.xml.bind.annotation.XmlAccessorType
- javax.persistence.Entity
- 
javax.persistence.Embeddable(since Ceylon 1.3.2)
- javax.inject.Inject
- javax.ejb.Stateless
- javax.ejb.Stateful
- javax.ejb.MessageDriven
- javax.ejb.Singleton
If necessary, the compiler options
          --ee-annotation and
          --ee-import can be used to replace
          the fully qualified annotation type names and module names which trigger activation.
Alternatively the option
          --ee
          can be used to enable EE mode for the entire compilation.
These options can also be specified in your
          .ceylon/config file, for example
[compiler.jvm]
eeimport=mvn:"org.springframework.boot:spring-boot"
eeannotation=org.springframework.beans.factory.annotation.Autowired