All skills
kotlin avatar

/kotlin-tooling-java-to-kotlin

@8fc58af official
by kotlinkotlin/kotlin-agent-skills1.1k stars
42

Use when converting Java source files to idiomatic Kotlin, when user mentions "java to kotlin", "j2k", "convert java", "migrate java to kotlin", or when working with .java files that need to become .kt files. Handles framework-aware conversion for Spring, Lombok, Hibernate, Jackson, Micronaut, Quarkus, Dagger/Hilt, RxJava, JUnit, Guice, Retrofit, and Mockito.

Use this Skill: https://skilld.dev/gh/kotlin/kotlin-agent-skills/kotlin-tooling-java-to-kotlin

This session only. Nothing lands on disk.

referencesframeworksQUARKUS.md

≈964 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Quarkus Conversion Guide

When This Applies

This guide applies when the Java source contains imports matching io.quarkus.*, javax.enterprise.*, or jakarta.enterprise.*. This covers Quarkus REST, Quarkus CDI, and Panache ORM.

Key Rules

1. CDI beans need a no-arg constructor

The CDI specification requires beans to have a no-arg constructor (package-private or public). In Kotlin, satisfy this by giving all constructor parameters default values, or by adding a secondary no-arg constructor.

2. Scope annotations

@ApplicationScoped, @RequestScoped, @Dependent — preserve these exactly. Beans with these scopes must have a no-arg constructor accessible to CDI.

3. @Inject field injection → constructor injection

Replace @Inject on fields with an @Inject-annotated primary constructor in Kotlin. CDI requires the @Inject annotation on the constructor when multiple constructors exist. With a single constructor, Quarkus discovers it automatically.

4. REST endpoint annotations

@Path, @GET, @POST, @PUT, @DELETE, @Produces, @Consumes — preserve these exactly. No annotation site target is needed.

5. Panache entities

Panache entities must remain open — do NOT use data class. Extend PanacheEntity (auto-generated Long ID) or PanacheEntityBase (custom ID type). Keep fields as open mutable properties because Panache enhances field access at build time.

6. @ConfigProperty

Use on constructor parameters with a default value to satisfy CDI's no-arg constructor requirement:

@ConfigProperty(name = "app.greeting") val greeting: String = ""

Examples

Example 1: REST Resource with CDI Injection

Java:

package com.acme.web;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import java.util.List;

@Path("/api/products")
@ApplicationScoped
@Produces(MediaType.APPLICATION_JSON)
public class ProductResource {

    @Inject
    ProductService productService;

    @Inject
    PricingService pricingService;

    @GET
    public List<ProductDto> listProducts() {
        return productService.findAll();
    }

    @GET
    @Path("/{id}")
    public ProductDto getProduct(@PathParam("id") Long id) {
        return productService.findById(id);
    }
}

Kotlin:

package com.acme.web

import jakarta.enterprise.context.ApplicationScoped
import jakarta.inject.Inject
import jakarta.ws.rs.GET
import jakarta.ws.rs.Path
import jakarta.ws.rs.PathParam
import jakarta.ws.rs.Produces
import jakarta.ws.rs.core.MediaType

@Path("/api/products")
@ApplicationScoped
@Produces(MediaType.APPLICATION_JSON)
class ProductResource @Inject constructor(
    private val productService: ProductService,
    private val pricingService: PricingService
) {

    // No-arg constructor required by CDI — default values satisfy this
    constructor() : this(
        productService = ProductService(),
        pricingService = PricingService()
    )

    @GET
    fun listProducts(): List<ProductDto> {
        return productService.findAll()
    }

    @GET
    @Path("/{id}")
    fun getProduct(@PathParam("id") id: Long): ProductDto? {
        return productService.findById(id)
    }
}

Key changes:

  • @Inject field injection is replaced by an @Inject-annotated primary constructor.
  • A secondary no-arg constructor is added to satisfy the CDI specification. In practice, CDI will use the @Inject constructor — the no-arg constructor exists only to pass validation.
  • Constructor parameters become private val in the primary constructor.
  • Return type ProductDto becomes ProductDto? where the service may return null.

Source: SKILL.md on GitHub

No alerts16d4 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    This skill provides a methodology for converting Java source code to Kotlin. While the logic is sound and focused on development tasks, it possesses an indirect prompt injection surface by processing untrusted source code and performing file system operations.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 8fc58af. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 weeks ago.

Activeupdated 7 months ago
metadata
{
  "author": "JetBrains",
  "version": "1.0.0"
}
  • kotlin
  • java
  • migration
  • spring
  • hibernate
  • jackson
  • junit
  • rxjava
  • retrofit
  • mockito
  • conversion

README badge

README badge for kotlin/kotlin-agent-skills/kotlin-tooling-java-to-kotlin

Converts Java source files to idiomatic Kotlin using a structured 4-step methodology with framework-aware handling for Spring, Lombok, Hibernate, Jackson, Micronaut, Quarkus, Dagger/Hilt, RxJava, JUnit, Guice, Retrofit, and Mockito. Preserves git history through two-phase renames and supports batch conversion with dependency ordering.

Generated from the current SKILL.md.

What frameworks does this skill handle?
Spring, Lombok, Hibernate, Jackson, Micronaut, Quarkus, Dagger/Hilt, RxJava, JUnit, Guice, Retrofit, and Mockito. The skill detects which frameworks are in use by scanning import statements and loads only the relevant framework guides.
Does this skill preserve git blame history?
Yes. It uses a two-phase approach: first rename the file with `git mv`, then replace the content in a separate commit so the rename is tracked separately from the conversion changes.
Can this skill convert multiple Java files at once?
Yes. For batch conversions, it sorts files by dependency order (leaf files first), converts one at a time through the full workflow, and updates cross-references as needed.
What happens if conversion fails the verification step?
The skill reverts to the previous conversion step and retries. It checks five invariants at each step and verifies output by compilation, tests, and annotation site targets.
Does this handle Java interop edge cases like platform types and checked exceptions?
Yes. The skill documents and handles Kotlin keyword conflicts, SAM conversion ambiguity, platform types, @JvmStatic/@JvmField/@JvmOverloads, checked exceptions, and wildcard generics in a separate known-issues reference.

Generated from the current SKILL.md. These answers refresh after source changes.