Integrate Ceylon in Maven builds.
Here is an example project.
Use this in your pom.xml
file:
<build> <plugins> <plugin> <groupId>org.ceylon-lang</groupId> <artifactId>ceylon-maven-plugin</artifactId> <version>1.3.3</version> <configuration> <!-- Recommended for mixing Java/Ceylon modules --> <explode>true</explode> </configuration> <extensions>true</extensions> </plugin> </plugins> </build>
By default, if you configure your plugin with extensions
enabled, you don’t need
to specify any phase: the default compile
, compileTest
and test
phases
will be respected and your modules will be compiled in the proper phases.
The Ceylon module declarations go in src/main/ceylon
and your tests go in
src/test/ceylon
.
It is recommended to have a single Ceylon module per Maven module, and to make the pom.xml
coordinates such as groupId
, artifactId
and version
match with those
declared in the module.ceylon
file, as well as the list of dependencies. This can
be disabled with:
<configuration> <disablePomChecks>true</disablePomChecks> </configuration>
You can find more information at https://ceylon-lang.org/documentation/1.3/reference/interoperability/maven/
The import-dependency
goal imports a Maven dependency in a Ceylon repository:
<execution> <goals> <goal>import-dependency</goal> </goals> <configuration> <moduleImports> <moduleImport> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-core</artifactId> <version>1.3</version> </dependency> </moduleImport> </moduleImports> </configuration> </execution>
-
the default execution phase is
initialize
-
the default imported module name is
${groupId}.${artifactId}/${version}
-
the default module repository resolves to
target/modules
An ommited dependency version is resolved from the project dependencies.
The imported module coordinates can be overriden with the name
and version
:
<configuration> <moduleImport> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-core</artifactId> <version>1.3</version> </dependency> <name>org.harmcrest.core</name> <version>1.3-SP2</version> </moduleImport> </configuration>
A module descriptor can be provided thanks to the descriptor
configuration:
<configuration> <moduleImport> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-core</artifactId> <version>1.3</version> </dependency> <descriptor>hamcrest.properties</descriptor> </moduleImport> </configuration>
A module import can be forced
:
<configuration> <moduleImport> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-core</artifactId> <version>1.3</version> </dependency> <force>true</force> </moduleImport> </configuration>
The out
configuration changes the module output directory:
<configuration> <!-- module will be imported in target/mymodules --> <out>mymodules</out> </configuration>
The compile
and compile-js
goals compile Ceylon modules, for the JVM and JS backends respectively:
<execution> <goals> <goal>compile</goal> </goals> </execution>
-
the default execution phase is
compile
-
the default compiled sources fileset is
${basedir}/src/main/ceylon
-
the default module repository resolves to
target/modules
The sources fileset can be configured:
<execution> <goals> <goal>compile</goal> </goals> <configuration> <sources> <source> <directory>${project.basedir}/src/foo/ceylon</directory> </source> <source> <directory>${project.basedir}/src/bar/ceylon</directory> </source> </sources> </configuration> </execution>
Resources can be added:
<configuration> <resources> <resource> <directory>${project.basedir}/src/resources</directory> </resource> </resources> </configuration>
Extra user repositories can be added:
<configuration> <userRepos> <userRepo>/path/to/my/module/repo</userRepo> </userRepos> </configuration>
The default output repository can be changed:
<configuration> <out>my_modules</out> </configuration>
Javac options can be passed:
<configuration> <javacOptions>-target 8</javacOptions> </configuration>
The resulting modules can be exploded to a specific directory:
<configuration> <explodeTo>target/classes</explodeTo> </configuration>
The verbosity can be configured:
<configuration> <verbose>true</verbose> </configuration>
Valid values are:
-
true
, which has the same effect as the--verbose
flag -
any combination of
all, loader, ast, code, cmr, benchmark
, which has the same effect as the--verbose=<…>
flag
The run
and run-js
goals run a Ceylon application, for the JVM and JS backends respectively:
<execution> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <module>my.module/1.0.0</module> </configuration> </execution>
-
the goal does not have default execution phase
-
the default module repository resolves to
target/modules
Arguments can be passed to the process:
<configuration> <arguments> <argument>first_arg</argument> <argument>second_arg</argument> </arguments> </configuration>
Extra user repositories can be added:
<configuration> <userRepos> <userRepo>/path/to/my/module/repo</userRepo> </userRepos> </configuration>
The verbosity can be configured:
<configuration> <verbose>true</verbose> </configuration>
Valid values are:
-
true
, which has the same effect as the--verbose
flag -
any combination of
all, loader, cmr
, which has the same effect as the--verbose=<…>
flag
Finally the execution can be skipped:
<configuration> <skip>true</skip> </configuration>
The test
and test-js
goals test a Ceylon application, for the JVM and JS backends respectively:
<execution> <phase>test</phase> <goals> <goal>test</goal> </goals> <configuration> <module>my.module/1.0.0</module> </configuration> </execution>
Options are the same as those for run
and run-js
except you can run multiple modules:
<configuration> <modules> <module>my.module/1.0.0</module> </modules> </configuration>
You can also specify which tests to run:
<configuration> <modules> <module>my.module/1.0.0</module> </modules> <tests> <test>my.module::testFoo</test> <test>my.module::testBar</test> </tests> </configuration>
The doc
goal documents a Ceylon:
<execution> <phase>prepare-package</phase> <goals> <goal>goal</goal> </goals> <configuration> <modules> <module>my.module</module> </modules> </configuration> </execution>
-
the goal does not have default execution phase
-
the default module repository resolves to
target/modules
Arguments can be passed to the process:
Extra user repositories can be added:
<configuration> <userRepos> <userRepo>/path/to/my/module/repo</userRepo> </userRepos> </configuration>
The copy
goal copies Ceylon modules to a given repository:
<execution> <goals> <goal>copy</goal> </goals> <!-- Other configuration can be used, such as userRepos, ceylonHome, verbose --> <configuration> <!-- include everything (defaults to false) --> <all>true</all> <!-- include js modules: .js (defaults to true) --> <js>true</js> <!-- include jvm modules: .car and .jar (defaults to true) --> <jvm>true</jvm> <!-- include source modules: .src (defaults to false) --> <src>true</src> <!-- include module documentation (defaults to false) --> <docs>true</docs> <!-- include script modules (defaults to false) --> <scripts>true</scripts> <!-- include dependencies (defaults to false) --> <withDependencies>true</withDependencies> <!-- include the language module (defaults to false) --> <languageModule>true</languageModule> <!-- HTTP timeout in milliseconds (defaults to 20 seconds) --> <!-- Can be configured with (-Dceylon.timeout) --> <timeout>true</timeout> <!-- URI of target repository (defaults to ./modules) --> <out>target/new-repo</out> <!-- HTTP user name of target repository, if HTTP --> <!-- Can be configured with (-Dceylon.username) --> <username>Bob</username> <!-- HTTP password of target repository, if HTTP --> <!-- Can be configured with (-Dceylon.password) --> <password>Bob</password> <!-- list of modules to copy --> <modules> <module>com.example.foo/1.1</module> <module>com.example.bar/2.3</module> </modules> </configuration> </execution>
In order to create a project with the Ceylon Maven plugin using Eclipse, start by creating the project using a Maven wizard just as you normally would.
Since the default directory for the Ceylon source code is ${basedir}/src/main/ceylon
you should create that directory and put
your modules in there unless you changed the default. Then change your pom.xml
according to the instructions at the beginning
of this document. That should be enough for it to work via Maven.
In order to make your project work with the Ceylon plugin for Eclipse, first get the Ceylon plugin for Eclipse using the Eclipse market place.
Once you have that plugin right click on your project and click Configure>Convert to Ceylon Project.
Then, if you’re aren’t already in the Ceylon perspective get into it by clicking Window>Switch Perspective>Ceylon.
Then in the Ceylon explorer, right click on your project and click Build Path>Configure Build Path.
In the window that pops up navigate to Ceylon Build>Build Path. Once you’re there, make sure ${basedir}/src/main/ceylon
is listed as one of the source folders. If it isn’t, click add folder and select ${basedir}/src/main/ceylon
.
Then change the output folder at the bottom of the window from target
to target/classes
, click OK.
At this point you can create a module in ${basedir}/src/main/ceylon
using the Ceylon plugin for Eclipse.
You should also be able to run that module.
If you have trouble running the module go to the run configurations and make sure that your module is selected.
Plugin versions are named after Ceylon releases using an extra number for its own numbering, for example:
-
1.2.0: first version for Ceylon 1.2.0
-
1.2.0.1: next version for Ceylon 1.2.0
-
1.2.1: first version for Ceylon 1.2.1
-
etc…
-
1.3.3:
-
Updated to Ceylon 1.3.3
-
-
1.3.2.1:
-
Added copy goal
-
-
1.3.2:
-
Updated to Ceylon 1.3.2
-
Hooked into regular phases, using extension
-
Added test compilation and runs
-
-
1.3.1:
-
Fixed problem with unset
options.javacTarget
-
-
1.3.0:
-
Repository lookup now looks in the proper folder (
target/modules
) by default -
Becasue of that the
cwd
option could be removed -
Added
compile-js
andrun-js
goals -
Added
explodeTo
option for the compilers
-
-
compile: specify module
-
import sources jar
-
default module id when classifer != null
-
maybe need to handle dependency scope in importer
-
test external snapshot resolution