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.

referencesframeworksDAGGER-HILT.md

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

Dagger / Hilt Conversion Guide

When This Applies

This guide applies when the Java source contains imports matching dagger.* or dagger.hilt.*. This covers Dagger 2, Hilt for Android, and Hilt Jetpack integrations.

Key Rules

1. @Inject constructor syntax

Kotlin places @Inject before the constructor keyword in the primary constructor:

class Foo @Inject constructor(private val bar: Bar)

2. @Module classes with @Provides methods

Keep @Provides methods open, or use object for modules that contain only @JvmStatic provides methods (companion object pattern):

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
    @Provides
    @Singleton
    fun provideOkHttpClient(): OkHttpClient = OkHttpClient.Builder().build()
}

3. @Binds abstract methods

@Binds methods work in abstract classes exactly as in Java. Convert the abstract class directly — no special Kotlin considerations.

4. Hilt Android annotations

@HiltAndroidApp, @AndroidEntryPoint, @HiltViewModel — preserve these exactly on Application, Activity, Fragment, and ViewModel classes.

5. Scoping annotations

@Singleton, @ActivityScoped, @ViewModelScoped, @FragmentScoped — preserve exactly. No annotation site target is needed.

6. @AssistedInject / @AssistedFactory

@AssistedInject replaces @Inject on the constructor. @Assisted parameters appear alongside regular injected parameters in the primary constructor:

class PlayerViewModel @AssistedInject constructor(
    @Assisted private val playerId: String,
    private val repository: PlayerRepository
) : ViewModel()

7. @Component / @Subcomponent interfaces

Convert directly to Kotlin interfaces. Dagger's annotation processing works identically with Kotlin interfaces via kapt or KSP.


Examples

Example 1: Hilt ViewModel with @Inject Constructor and a @Module

Java:

package com.acme.feature;

import androidx.lifecycle.ViewModel;
import dagger.Module;
import dagger.Provides;
import dagger.hilt.InstallIn;
import dagger.hilt.android.lifecycle.HiltViewModel;
import dagger.hilt.components.SingletonComponent;
import javax.inject.Inject;
import javax.inject.Singleton;

@HiltViewModel
public class UserProfileViewModel extends ViewModel {

    private final UserRepository userRepository;
    private final AnalyticsTracker analyticsTracker;

    @Inject
    public UserProfileViewModel(UserRepository userRepository, AnalyticsTracker analyticsTracker) {
        this.userRepository = userRepository;
        this.analyticsTracker = analyticsTracker;
    }

    public LiveData<User> getUser(String userId) {
        analyticsTracker.trackProfileView(userId);
        return userRepository.getUser(userId);
    }
}

@Module
@InstallIn(SingletonComponent.class)
public class AnalyticsModule {

    @Provides
    @Singleton
    public AnalyticsTracker provideAnalyticsTracker(Application app) {
        return new AnalyticsTracker(app);
    }
}

Kotlin:

package com.acme.feature

import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.components.SingletonComponent
import javax.inject.Inject
import javax.inject.Singleton

@HiltViewModel
class UserProfileViewModel @Inject constructor(
    private val userRepository: UserRepository,
    private val analyticsTracker: AnalyticsTracker
) : ViewModel() {

    fun getUser(userId: String): LiveData<User> {
        analyticsTracker.trackProfileView(userId)
        return userRepository.getUser(userId)
    }
}

@Module
@InstallIn(SingletonComponent::class)
object AnalyticsModule {

    @Provides
    @Singleton
    fun provideAnalyticsTracker(app: Application): AnalyticsTracker {
        return AnalyticsTracker(app)
    }
}

Key changes:

  • @Inject moves before the constructor keyword in the primary constructor.
  • Constructor parameters become private val in the primary constructor.
  • The module class becomes an object since it contains only static-like provides methods.
  • SingletonComponent.class becomes SingletonComponent::class (Kotlin class reference).
  • Java getter method getUser becomes a regular function getUser (no get prefix convention change needed here since it takes a parameter).

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.