Welcome to the step-by-step tutorial to implement a LPhy or LPhyBEAST extension. Before reading this tutorial, we suggest you learn some essential knowledges about Gradle, and know how IntelliJ IDEA integrates with Gradle. It is also helpful to understand the technial background, which is available in the system integration section.

1. Setup development environment

The development requires Java 17, Gradle, and IntelliJ. If you are not familiar with this step, please follow the tutorial to setup development environment and load your Gradle project into IntelliJ.

IntelliJ will automatically import modules and dependencies from the Gradle settings. Please do not try to change them through Project Structure in IntelliJ, because these changes might be lost after reimporting.

2. Establish a standard project structure

The extension project must be set to the standard Gradle directory structure. You can either create a Gradle project using IntelliJ, or simply copy the structure from an existing example, such as Phylonco, and then fill in your contents.

For example, in Figure 1, you need to rename the 3 subprojects (subfolders) to your subprojects, which are phylonco-beast, phylonco-lphy, and phylonco-lphybeast. Then replace their names inside include to yours, which are highlighted in the settings.gradle.kts.

IntelliJ Setting
Figure 1: Project structure and Gradle setting file in Phylonco.

Please be aware that if you are migrating your existing projects, you need to use either IntelliJ or git mv to move files, otherwise the history of files will be lost.

3. Fill in your project metadata

We are using composite builds. In the project root, there is a settings.gradle.kts to configure this structure, and a common build file build.gradle.kts to share build logics. Furthermore, each subproject has its own build file. They have been pointed by a red arrow in Figure 1.

You need to replace the project metadata in these files to your project information. The main changes are listed below, and click links to see where they are:

The advanced tutorial Gradle project master - project structure will explain this in detail.

4. Dependency management

In this step, you need to configure the dependencies block for your subprojects. First we recommend to use module dependencies, but this requires all libraries are published to the Maven central repo. If this is unavailable, then you can consider to use file dependencies, which stores the released libraries in a lib folder in the repository and load them as files. The significant drawbacks are that you have to manually validate their dependencies and update them. Sometimes, if a subproject depends on another in the same repository, you can import it using project dependencies. But we do not recommend this, if the subproject can be imported using module dependencies.

There are several types of dependency configurations. Each of them defines a specific scope for the dependencies declared in a Gradle project. Please be aware of the key difference between implementation and api, and be respectful of consumers.

The advanced tutorial Gradle project master - dependencies will introduce the details of these concepts.

5. Java development

To create a LPhy extension, you need to create the container provider class under the package mypackage.lphy.spi to list all extended Java classes, and register it in the module-info.java file. The following posts explain how the core and extensions work in a technical level.

The advanced tutorial Java extension mechanism of LPhy and LPhyBEAST will demonstrate the usage of LPhy and LPhyBEAST extension mechanism.

6. Build the project

The output of basic tasks will be kept in a build folder created by each build. For example, the libs contains all jar files, the distributions contains the zip or tar files, and the reports and test-results contain unit test results.