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.

referencesframeworksJUNIT.md

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

JUnit / TestNG Conversion Guide

When This Applies

Detected when imports match org.junit.* or org.testng.*.

Key Rules

1. JUnit 4 to Kotlin (with JUnit 5)

JUnit 4 Kotlin (JUnit 5 / kotlin.test)
@Test @Test (from kotlin.test or org.junit.jupiter.api)
@Before @BeforeEach (JUnit 5) or @BeforeTest (kotlin.test)
@After @AfterEach (JUnit 5) or @AfterTest (kotlin.test)
@BeforeClass @BeforeAll in companion object with @JvmStatic
@AfterClass @AfterAll in companion object with @JvmStatic
@RunWith @ExtendWith (JUnit 5)
@Ignore @Disabled (JUnit 5)
@Rule / @ClassRule @ExtendWith or @RegisterExtension
Assert.assertEquals(expected, actual) assertEquals(expected, actual) (kotlin.test)
Assert.assertTrue(condition) assertTrue(condition) (kotlin.test)
@Test(expected = X.class) assertFailsWith<X> { } (kotlin.test) or assertThrows<X> { } (JUnit 5)

2. JUnit 5 stays mostly the same

JUnit 5 annotations (@Test, @BeforeEach, @AfterEach, etc.) remain unchanged. Focus on Kotlin idioms in the test body:

  • assertThrows<ExceptionType> { code } — uses reified generics, no .class needed.
  • Test classes and methods do not need to be public — Kotlin's default visibility is public, which satisfies JUnit's requirements.
  • Test methods do not need open unless using a framework that subclasses the test (e.g., certain Spring test configurations).

3. TestNG to Kotlin

TestNG Kotlin (JUnit 5)
@Test @Test
@BeforeMethod @BeforeEach
@AfterMethod @AfterEach
@BeforeClass @BeforeAll with @JvmStatic in companion object
@AfterClass @AfterAll with @JvmStatic in companion object
@DataProvider @ParameterizedTest + @MethodSource

4. Assertion style

Prefer kotlin.test assertions (assertEquals, assertTrue, assertFailsWith) for portability across test frameworks. They delegate to the underlying framework at runtime.

5. Backtick method names

Kotlin allows backtick-quoted method names for readable test names:

@Test
fun `should return empty list when no users exist`() { ... }

Example: JUnit 4 Test Class to Kotlin with JUnit 5

Java Input

package com.acme.service;

import org.junit.Before;
import org.junit.After;
import org.junit.Test;
import org.junit.BeforeClass;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

/**
 * Tests for the UserService class.
 */
public class UserServiceTest {

    private static DatabaseConnection db;
    private UserService userService;

    @BeforeClass
    public static void setupDatabase() {
        db = DatabaseConnection.create("test");
    }

    @Before
    public void setUp() {
        userService = new UserService(db);
    }

    @After
    public void tearDown() {
        db.clearTestData();
    }

    @Test
    public void testFindById() {
        User user = userService.findById(1L);
        assertNotNull(user);
        assertEquals("Alice", user.getName());
    }

    @Test
    public void testFindAllReturnsNonEmptyList() {
        List<User> users = userService.findAll();
        assertNotNull(users);
        assertTrue(users.size() > 0);
    }

    @Test(expected = IllegalArgumentException.class)
    public void testFindByIdWithNegativeIdThrows() {
        userService.findById(-1L);
    }
}

Kotlin Output

package com.acme.service

import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertNotNull
import kotlin.test.assertTrue

/**
 * Tests for the UserService class.
 */
class UserServiceTest {

    companion object {
        private lateinit var db: DatabaseConnection

        @BeforeAll
        @JvmStatic
        fun setupDatabase() {
            db = DatabaseConnection.create("test")
        }
    }

    private lateinit var userService: UserService

    @BeforeEach
    fun setUp() {
        userService = UserService(db)
    }

    @AfterEach
    fun tearDown() {
        db.clearTestData()
    }

    @Test
    fun `should find user by id`() {
        val user = userService.findById(1L)
        assertNotNull(user)
        assertEquals("Alice", user.name)
    }

    @Test
    fun `should return non-empty list from findAll`() {
        val users = userService.findAll()
        assertNotNull(users)
        assertTrue(users.isNotEmpty())
    }

    @Test
    fun `should throw IllegalArgumentException for negative id`() {
        assertFailsWith<IllegalArgumentException> {
            userService.findById(-1L)
        }
    }
}

Key points:

  • JUnit 4 @Before / @After → JUnit 5 @BeforeEach / @AfterEach.
  • @BeforeClass static method → @BeforeAll + @JvmStatic inside companion object.
  • @Test(expected = ...) → assertFailsWith<ExceptionType> { } with reified generics.
  • Static assertions become kotlin.test top-level function imports.
  • Test method names use backtick syntax for readability.
  • users.size() > 0 becomes idiomatic users.isNotEmpty().
  • The db field uses lateinit var since it is initialized in @BeforeAll.

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.