KBeans
KBeans¶
KBean is the central concept of the execution engine. KBeans are classes with declared executable methods. There is only one KBean instance by KBean class in any given Jeka project (JkRuntime).
KBean classes share the following characteristics :
- They extend
KBean
class. - They may declare
public void
methods without taking any arguments. All these methods can be invoked from the command line. - They may declare
public
fields (aka KBean properties). These field values can be injected from the command line. These can also be non-public fields annotated with@JkDoc
. - They must provide a no-arg constructor
- They may override
init()
method - They must be instantiated by the execution engine and not from the user code.
Simple Example¶
The following KBeans expose the cleanPublish
method which delegates the creation of jar files to the 'project' KBean.
ProjectKBean
is available on the Jeka classpath as it is part of the standard KBeans bundled in the JeKa distribution.
import dev.jeka.core.api.project.JkProject;
@JkDoc("A simple example to illustrate KBean concept.")
public class SimpleJkBean extends KBean {
final ProjectKBean projectKBean = load(ProjectKBean.class); // Instantiate KBean or return singleton instance.
@Override
protected void init() { // When init() is invoked, projectKBean field instances has already been injected.
projectKBean.project.simpleFacade()
.addCompileDeps(
"com.google.guava:guava:30.0-jre",
"com.sun.jersey:jersey-server:1.19.4"
)
.addTestDeps(
"org.junit.jupiter:junit-jupiter:5.8.1"
);
}
@JkDoc("Clean, compile, test, create jar files, and publish them.")
public void cleanPublish() {
projectKBean.cleanPack();
projectKBean.publishLocal();
}
}
KBean Commands¶
A KBean command is an instance method of a KBean class that can be invoked from the command line. In order to be considered as a command, a method must :
- be
public
- be an instance method
- take no argument
- return
void
KBean Attributes¶
A KBean attribute is a public
instance field of a KBean class. Its value can be injected from the command line,
or from property file.
It can be also non-public fields annotated with @JkDoc
.
Attributes can be annotated with @JkInjectProperty("my.prop.name")
to inject the value of a property within.
For more details on field accepted types, see dev.jeka.core.tool.FieldInjector#parse
method.
KBean properties can also be nested composite objects, see example in ProjectKBean#pack
field.
Naming KBeans¶
In order to be referenced conveniently, KBeans can be called by names. For any given JkBean class, accepted names are :
- Full qualified class name
- Uncapitalized simple class name (e.g. 'myBuild' matches 'org.example.MyBuild')
- Uncapitalized simple class Name without 'JkBean' suffix (.g. 'project' matches 'dev.jeka.core.tool.builtin.project.ProjectKBean')
Tip
Execute jeka
, at the root of a project to display KBeans present in Jeka classpath.
Document KBeans¶
KBean classes, methods, and properties can be annotated with @JkDoc
annotation in order to provide self documentation.
Text within these annotations is displayed when invoking help
method on the console.
Invoke KBeans¶
From Command Line¶
KBean methods can be invoked from the command line using
jeka [kbeanName]#methoName [kbeanName]#[propertyName]=xxx
Many methods/properties can be invoked in a single command line.
Info
[kbeanName] prefix can be omitted. By default, it will be resolved on the bean mentioned by the -kb= option,
or the first KBean found in def dir, if the option is not present.
Search is executed by alphabetical order of fully qualified class names.
Example : jeka #toSomething #aProperty=xxxx
It is also possible to refer to the default KBean by using kb# prefix in place of #.
Example : jeka kb#toSomething kb#aProperty=xxxx
From IntelliJ Jeka Plugin¶
[IntelliJ Jeka Plugin] allows the invocation of methods directly from the editor or the explorer tool window.
From naked IDE¶
KBean methods can also be launched/debugged from IDE using classic main
methods.
In KBean class, declare one or several main methods as :
public static void main(String[] args) {
JkInit.instanceOf(MyBuild.class, args).cleanPack();
}
public static class Release {
public static void main(String[] args) {
JkInit.instanceOf(MyBuild.class, args, "-runIT").release();
}
}
JkInit#instanceOf
in order for it to be set up properly.
The arguments passed in the main
method are interpreted as command line arguments.
Launching or debugging this way is performant as all build classes and their dependencies are already on classpath. Therefore, no compilation or dependency resolution is needed.
Warning
Be careful to launch the main method using module dir as working dir. On IntelliJ, this is not the default (it uses project dir).
To change intelliJ defaults, follow : Edit Configurations | Edit configuration templates... | Application | Working Directory : $MODULE_DIR$.
Sometimes, you may need to mimic the command line behavior more closely, for debugging purposes or to pass '@' arguments.
- Create an IDE launcher for a Java Application
- Set
dev.jeka.tool.Main
as Java main class. - Set the same command line arguments as you would do for invoking from command line (Do not include jeka command).
Let KBeans cooperate¶
Generally KBeans interact with each other by declaring KBeans using KBean#load(MyBean.class)
method as shown in this example.
When a KBean depends on another one, it's good to declare it as an instance field of the first bean, as this dependency will be mentioned in the auto-generated documentation and showed explicitly in IDE tool.
KBeans in Multi-Projects¶
In a multi-project, it's quite common that a KBean accesses a KBean instance from another project. You can achieve this in a statically typed way.
- In master KBean, declare a field of type
KBean
(e.g. ´JkBean importedBuild;`). It doesn't have to be public. - Annotate it with
@JkInjectProject
mentioning the relative path of the imported project (e.g. `@JkInjectProject("../anotherModule")). - Execute
jeka intellij#iml
orjeka eclipse#files
. - Redefine the declared type from
KBean
to the concrete type of imported KBean - Now, master KBean can access the imported KBean in a static typed way.
- See example here.
- Be mindful that the imported KBean must deal with file paths using
KBean#getBaseDir
in order for it to be safely executed from any working directory.
Bundled KBeans¶
There are a bunch of KBeans bundled within Jeka. Those KBeans are always present.
project¶
ProjectKBean
provides a wrapper around a JkProject
for building JVM-based projects. This KBean initialises
a default sensitive project object and provides a classic method for building a project (compile, package in jar, publish ...)
This KBean proposes an extension point through its configure(JkProject)
method. This way, other KBeans can
modify the properties of the project to be built.
intellij¶
IntellijKBean
provides methods for generating metadata files for IntelliJ IDE. The content of an iml file is computed
according the JkProject
object found in project KBean.
This KBean proposes an extension point through its configure
methods in order to modify the resulting iml
(e.g. using a module dependency instead of a library dependency).
scaffold¶
ScaffoldjKBean
provides methods for project directories and files to create a new Jeka project. Basically,
it creates a project ready to create vanilla automation tasks.
This KBean offers an extension point in order for another KBean to augment the scaffolded structure. For example,
executing jeka scaffold#run
will create a basic Jeka project while jeka scaffold#run project#
will create
a project ready to build a JVM-based project.
git¶
GitKBean
exposes some common git command combos. It can also auto-inject a version inferred from Git into project KBean.