grafana / grafana/pyroscope

Support Kotlin (.kt) file extension in Java source code integration

Open
#4,878 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
11.7k
Forks
802
Avg merge
1d 19h
Merged PRs (30d)
80

Description

## Problem

The current Java source code integration (`find_java.go`) hardcodes the `.java` file extension when resolving function names to source file paths:

```go
const ExtJava = ".java"
```

The `convertJavaFunctionNameToPath` function always appends `.java`:
- `com/example/MyClass.method` → `com/example/MyClass.java`

This means **Kotlin applications get 404 errors for every source code lookup**, since Kotlin source files use the `.kt` extension.

## Context

Kotlin is a JVM language officially supported by Google for Android and widely used in server-side applications (Spring Boot, Ktor, etc.). Kotlin compiles to JVM bytecode, so the async-profiler / JFR profiling agent captures Kotlin classes the same way as Java classes. However, when Pyroscope tries to fetch the source code from GitHub, it looks for `MyClass.java` instead of `MyClass.kt`, resulting in a 404.

## Reproduction

1. Set up a Kotlin project with `.pyroscope.yaml`:
```yaml
version: v1
source_code:
mappings:
- function_name:
- prefix: com/example/myapp
language: java
source:
github:
owner: my-org
repo: my-kotlin-app
ref: main
path: src/main/kotlin
```
2. Profile the application and click on any function in the flame graph
3. Pyroscope requests `src/main/kotlin/com/example/myapp/MyClass.java` from GitHub
4. GitHub returns 404 because the actual file is `MyClass.kt`

## Proposed Solution

When `language: java`, try multiple JVM file extensions before returning "not found":

1. Try `.java` first (current behavior)
2. If 404, try `.kt` (Kotlin)
3. Optionally try `.scala`, `.groovy` for other JVM languages

Alternatively, add a new `language: kotlin` option that uses `.kt` as the primary extension.

### Suggested change in `find_java.go`:

```go
var jvmExtensions = []string{".java", ".kt"}

func (ff *FileFinder) findJavaFile(ctx context.Context, mapping []MappingConfig) (*connect.Response[vcsv1.GetFileResponse], error) {
span, ctx := opentracing.StartSpanFromContext(ctx, "findJavaFile")
defer span.Finish()

path := convertJavaFunctionNameToPath(ff.file)
// path has .java extension, try .kt as fallback
basePath := strings.TrimSuffix(path, ExtJava)

for _, ext := range jvmExtensions {
candidate := basePath + ext
for _, m := range mapping {
resp, err := ff.fetchMappingFile(ctx, candidate, m)
if err == nil {
return resp, nil
}
// continue on 404, return on other errors
}
}
return nil, CodeNotFound
}
```

## Impact

This affects all JVM projects using non-Java languages:
- **Kotlin** — widely used in Android and server-side (Spring Boot)
- **Scala** — used in data engineering (Spark, Akka)
- **Groovy** — used in Gradle build scripts and some web apps

## Environment

- Grafana Cloud with Pyroscope
- Kotlin 1.9.x + Spring Boot 3.x application
- Profiled via Grafana Alloy with `pyroscope.java` component
- `.pyroscope.yaml` with 33 mappings, all returning 404 due to `.java` extension

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.