Install
$ agentstack add skill-kora-projects-kora-skills-kora-project-setup-java ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Kora Project Setup — Java
Scaffold a minimal, compilable Kora service in Java. Kora is a compile-time framework: its annotation processor generates ApplicationGraph, controllers, JSON readers/writers and aspects during compileJava. If the processor is not wired into the Gradle build, nothing is generated and nothing works. This skill gets that wiring right the first time.
BOM version: ru.tinkoff.kora:kora-parent:1.2.17 (declared once; every ru.tinkoff.kora:* artifact inherits it — never version them individually). JDK: 17 minimum, 21 recommended. Gradle: 7+ (wrapper pins 9.5.1).
Quick Start
Smallest build that compiles and runs an HTTP endpoint. Mirrors .kora-agent/kora-examples/guides/java/kora-java-guide-getting-started-app.
build.gradle:
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.jvm.toolchain.JvmVendorSpec
plugins {
id "java"
id "application"
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
vendor = JvmVendorSpec.ADOPTIUM
}
}
repositories {
mavenCentral()
}
configurations {
koraBom
annotationProcessor.extendsFrom(koraBom)
compileOnly.extendsFrom(koraBom)
implementation.extendsFrom(koraBom)
testImplementation.extendsFrom(koraBom)
testAnnotationProcessor.extendsFrom(koraBom)
}
dependencies {
koraBom platform("ru.tinkoff.kora:kora-parent:1.2.17")
// Mandatory: without this nothing is generated.
annotationProcessor "ru.tinkoff.kora:annotation-processors"
implementation "ru.tinkoff.kora:http-server-undertow"
implementation "ru.tinkoff.kora:config-hocon"
implementation "ru.tinkoff.kora:json-module"
implementation "ru.tinkoff.kora:logging-logback"
testAnnotationProcessor "ru.tinkoff.kora:annotation-processors"
testImplementation "ru.tinkoff.kora:test-junit5"
}
application {
mainClass = "com.example.Application"
}
settings.gradle:
plugins {
id "org.gradle.toolchains.foojay-resolver-convention" version "1.0.0"
}
rootProject.name = "kora-example"
src/main/java/com/example/Application.java:
package com.example;
import ru.tinkoff.kora.application.graph.KoraApplication;
import ru.tinkoff.kora.common.KoraApp;
import ru.tinkoff.kora.config.hocon.HoconConfigModule;
import ru.tinkoff.kora.http.server.undertow.UndertowHttpServerModule;
import ru.tinkoff.kora.json.module.JsonModule;
import ru.tinkoff.kora.logging.logback.LogbackModule;
@KoraApp
public interface Application extends
HoconConfigModule,
JsonModule,
LogbackModule,
UndertowHttpServerModule {
static void main(String[] args) {
KoraApplication.run(ApplicationGraph::graph);
}
}
ApplicationGraph is generated by the annotation processor from the @KoraApp interface; it appears in build/generated/sources/annotationProcessor/ after the first compile. ApplicationGraph::graph is the entry point passed to KoraApplication.run.
src/main/java/com/example/HelloController.java:
package com.example;
import ru.tinkoff.kora.common.Component;
import ru.tinkoff.kora.http.common.HttpMethod;
import ru.tinkoff.kora.http.common.annotation.HttpRoute;
import ru.tinkoff.kora.http.common.body.HttpBody;
import ru.tinkoff.kora.http.server.common.HttpServerResponse;
import ru.tinkoff.kora.http.server.common.annotation.HttpController;
@Component
@HttpController
public final class HelloController {
@HttpRoute(method = HttpMethod.GET, path = "/hello")
public HttpServerResponse hello() {
return HttpServerResponse.of(200, HttpBody.plaintext("Hello, Kora!"));
}
}
src/main/resources/application.conf:
httpServer {
publicApiHttpPort = 8080
privateApiHttpPort = 8085
}
logging.level {
"root": "WARN"
"ru.tinkoff.kora": "INFO"
}
Build and run:
./gradlew clean build # runs the annotation processor, builds the graph
./gradlew run # GET http://localhost:8080/hello -> "Hello, Kora!"
Project structure
my-app/
├── build.gradle
├── settings.gradle
├── gradle.properties
├── gradle/wrapper/gradle-wrapper.properties
├── src/main/java/com/example/Application.java
├── src/main/resources/application.conf
├── src/main/resources/logback.xml
└── src/test/java/com/example/
What's in references/ and assets/
| File | Purpose | |------|---------| | [references/build-gradle-reference.md](references/build-gradle-reference.md) | Fully annotated build.gradle, the koraBom configuration explained, test/run tuning, distribution packaging | | [references/troubleshooting-reference.md](references/troubleshooting-reference.md) | Build-error symptom → cause → fix table (processor not run, ApplicationGraph missing, dependency not found, daemon hangs) | | [assets/build.gradle.template](assets/build.gradle.template) | Drop-in build.gradle | | [assets/settings.gradle.template](assets/settings.gradle.template) | settings.gradle with the foojay toolchain resolver | | [assets/gradle.properties](assets/gradle.properties) | JVM args and Gradle flags | | [assets/Application.java.template](assets/Application.java.template) | @KoraApp graph root | | [assets/gradle-wrapper.properties](assets/gradle-wrapper.properties) | Gradle wrapper distribution |
When to use vs NOT
Use this skill when:
- Creating a Java Kora service from scratch (build files +
@KoraApproot). - A build fails with "annotation processor did not run", a missing
ApplicationGraph, or "Required dependency was not found".
- Choosing the JDK toolchain, the
kora-parentBOM version, or the Gradle
wrapper for a Kora project.
Do NOT use this skill for:
- Kotlin projects →
kora-project-setup-kotlin(usesksp+
symbol-processors, not annotationProcessor).
- Adding HTTP / Database / Kafka / gRPC modules to an existing build →
kora-project-dependencies.
- Writing
@ConfigSourcetyped config →kora-config-hocon. - DI patterns (
@Component,@Module, factories) →kora-di-compile.
The four things that must be right
koraBomconfiguration wiring. A customkoraBomconfiguration holds
the platform("ru.tinkoff.kora:kora-parent:1.2.17") and is extended by annotationProcessor, implementation, compileOnly, and the test* configurations. The annotation-processor classpath is separate from the application classpath, so it needs the BOM explicitly — otherwise the processor resolves without a version and fails.
annotationProcessor "ru.tinkoff.kora:annotation-processors". This is
the single processor that generates the graph, controllers, JSON readers/writers, and aspects. Add testAnnotationProcessor too so @KoraAppTest works.
@KoraAppgraph root. Aninterfaceannotated with@KoraAppthat
extends the framework *Module interfaces it needs. main calls KoraApplication.run(ApplicationGraph::graph) — the generated ApplicationGraph lives in the same package.
- Correct imports.
@KoraAppisru.tinkoff.kora.common.KoraApp;
KoraApplication is ru.tinkoff.kora.application.graph.KoraApplication; @Component is ru.tinkoff.kora.common.Component.
Core patterns
Modules are interfaces the @KoraApp extends
Framework capabilities ship as *Module interfaces. The graph root pulls them in via extends; each module contributes component factories to the graph.
@KoraApp
public interface Application extends
HoconConfigModule, // config-hocon
JsonModule, // json-module
LogbackModule, // logging-logback
UndertowHttpServerModule // http-server-undertow
{ ... }
Each extends must be backed by an implementation "ru.tinkoff.kora:" in build.gradle. If a module is on the build path but not extended, its factories are not added to the graph.
Your code joins the graph via @Component
A class annotated with @Component becomes a managed node. Dependencies are declared as constructor parameters — Kora resolves them at compile time.
@Component
@HttpController
public final class HelloController {
private final GreetingService service; // resolved from the graph
public HelloController(GreetingService service) {
this.service = service;
}
}
Do not use field injection. Kora wires components only through constructors.
A minimal @KoraAppTest
test-junit5 provides @KoraAppTest, which builds the real graph and injects components into the test via @TestComponent.
import static org.junit.jupiter.api.Assertions.assertNotNull;
import org.junit.jupiter.api.Test;
import ru.tinkoff.kora.test.extension.junit5.KoraAppTest;
import ru.tinkoff.kora.test.extension.junit5.TestComponent;
@KoraAppTest(Application.class)
class ApplicationTest {
@TestComponent
private HelloController controller;
@Test
void controllerIsWired() {
assertNotNull(controller);
}
}
Requires testAnnotationProcessor "ru.tinkoff.kora:annotation-processors" so the test graph is generated. Deeper testing → kora-testing-junit-java.
Common pitfalls
| Symptom | Cause | Fix | |---------|-------|-----| | No generated classes; ApplicationGraph unresolved | annotationProcessor "ru.tinkoff.kora:annotation-processors" missing | Add it to dependencies | | "Could not resolve ru.tinkoff.kora:annotation-processors" (no version) | annotationProcessor does not extend koraBom | annotationProcessor.extendsFrom(koraBom) | | Module factories absent from the graph | Module on classpath but not in @KoraApp extends | Add the *Module to extends | | cannot find symbol KoraApp / KoraApplication | Wrong import package | Use ru.tinkoff.kora.common.KoraApp and ru.tinkoff.kora.application.graph.KoraApplication | | @KoraAppTest finds no components | testAnnotationProcessor missing | Add testAnnotationProcessor "ru.tinkoff.kora:annotation-processors" | | Build hangs after clean | Stale Gradle daemon | ./gradlew --stop, retry | | IDE shows red but ./gradlew classes passes | IDE has not indexed build/generated/ | Re-run classes, refresh/invalidate IDE caches |
Full diagnosis table: [references/troubleshooting-reference.md](references/troubleshooting-reference.md).
Next steps
- [
kora-project-dependencies](../kora-project-dependencies/SKILL.md) — add HTTP, Database, Kafka, gRPC, S3 modules. - [
kora-config-hocon](../kora-config-hocon/SKILL.md) — typed@ConfigSourceconfiguration. - [
kora-di-compile](../kora-di-compile/SKILL.md) — compile-time DI patterns. - [
kora-testing-junit-java](../kora-testing-junit-java/SKILL.md) —@KoraAppTesttesting.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: kora-projects
- Source: kora-projects/kora-skills
- License: Apache-2.0
- Homepage: http://kora-projects.github.io/kora-docs
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.