Skip to content

Modularization of the project #744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 43 commits into from
Jul 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
59bb475
Move all files to commong module
dmitrii-artuhov Jul 3, 2025
0055db6
Fix integration tests and hanging lincheck unit tests
dmitrii-artuhov Jul 3, 2025
6824b8e
Fix publishing, make 'common' module to generate 'lincheck' library a…
dmitrii-artuhov Jul 4, 2025
9347da8
Fix archive naming for 'common' subproject
dmitrii-artuhov Jul 4, 2025
c3ea7df
Extract trace agent into separate module
dmitrii-artuhov Jul 4, 2025
2a7a4d3
Add a separate module which will be the only dependency of trace agent
dmitrii-artuhov Jul 4, 2025
9e7b001
Fix comment typo
dmitrii-artuhov Jul 4, 2025
0c3ebc4
Renamed modules and prepared module for jvm-agent and transformers
dmitrii-artuhov Jul 4, 2025
3d5e0b3
Separate project in :core, :common, :jvm-agent subprojects
dmitrii-artuhov Jul 4, 2025
aee599e
Forgot to append a build script to prev commit
dmitrii-artuhov Jul 4, 2025
5f60b73
Set up different subprojects for trace-debugger and trace-recorder
dmitrii-artuhov Jul 4, 2025
b1961a1
Remove obsolete code
dmitrii-artuhov Jul 4, 2025
c5cd298
Set up proper agents for trace debugger and trace recorder (with sepa…
dmitrii-artuhov Jul 4, 2025
a5906df
Move core files back to the root of the project
dmitrii-artuhov Jul 7, 2025
8d6be2e
Set up working publishing for lincheck tool
dmitrii-artuhov Jul 7, 2025
d942fb3
Remove useless println's
dmitrii-artuhov Jul 7, 2025
7e8030f
Remove includes of ':core' subproject
dmitrii-artuhov Jul 7, 2025
52d05cb
Remove 'configureKotlin' and 'configureJava' invocation from subproje…
dmitrii-artuhov Jul 7, 2025
4c6a7de
Simplify builds and tests for trace-debugger/recorder
dmitrii-artuhov Jul 8, 2025
4956769
Fix paths in documentation
dmitrii-artuhov Jul 8, 2025
0566726
Extract common flags into a single file
dmitrii-artuhov Jul 8, 2025
ffe44fb
Move shared classes from :trace to :common subproject
dmitrii-artuhov Jul 8, 2025
8677e9c
Change trace agents file names
dmitrii-artuhov Jul 8, 2025
1e68af7
Change 'native_call' package name to 'nativecalls'
dmitrii-artuhov Jul 8, 2025
e7ef152
Rename 'trace_debugger' packages to 'trace.debugger'
dmitrii-artuhov Jul 8, 2025
1c40b1a
Rename 'trace_recorder'/'tracerecorder' packages to 'trace.recorder'
dmitrii-artuhov Jul 8, 2025
00dac1f
Refactor trace-debugger/recorder package names
dmitrii-artuhov Jul 8, 2025
3595990
Rename 'traceagent' package to 'trace.agent'
dmitrii-artuhov Jul 8, 2025
87a42fd
Add clarifying comments to the trace-recorder transformers stored in …
dmitrii-artuhov Jul 8, 2025
96d3519
Spare :jvm-agent subproject from dependency to :trace subproject
dmitrii-artuhov Jul 8, 2025
45d5c04
Set up proper visibility (api/implementation) between dependencies of…
dmitrii-artuhov Jul 8, 2025
13268d3
Add fixes
dmitrii-artuhov Jul 8, 2025
b0035e4
Add code cleanups
dmitrii-artuhov Jul 8, 2025
4a43c76
Set up friend paths and mark implementation-only classes in ':common'…
dmitrii-artuhov Jul 8, 2025
c55f45f
Refactor Logger visibility and reorder code in Utils.kt
dmitrii-artuhov Jul 9, 2025
a9cb6dc
Add minor fixes from PR
dmitrii-artuhov Jul 9, 2025
98f0004
Remove 'kotlinx' from trace-recorder/debugger packages
dmitrii-artuhov Jul 9, 2025
fc257a9
Fix the rest of the PR comments
dmitrii-artuhov Jul 9, 2025
48d7165
Remove todos and fix some code-style issues
dmitrii-artuhov Jul 9, 2025
ebe108b
Remove useless comments
dmitrii-artuhov Jul 9, 2025
057d8bd
Make all symbols from ':common' public to have proper IDEA highlighti…
dmitrii-artuhov Jul 9, 2025
e3f9a0b
Decrease file-diff size
dmitrii-artuhov Jul 9, 2025
cd85c3e
Add TODO for removing `api(project(":common"))` from lincheck "core" …
dmitrii-artuhov Jul 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 69 additions & 32 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
import org.gradle.jvm.tasks.Jar
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.dokka.gradle.DokkaTask
/*
* Lincheck
*
* Copyright (C) 2019 - 2025 JetBrains s.r.o.
*
* This Source Code Form is subject to the terms of the
* Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed
* with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.asRequestBody
import java.util.*
import org.gradle.kotlin.dsl.invoke
import org.gradle.kotlin.dsl.java
import org.gradle.kotlin.dsl.kotlin
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.nio.file.Paths
import java.util.Base64


buildscript {
repositories {
Expand Down Expand Up @@ -40,6 +53,33 @@ java {
configureJava()
}

subprojects {
plugins.apply("java")
plugins.apply("org.jetbrains.kotlin.jvm")

kotlin {
configureKotlin()
}

java {
configureJava()
}
}

/*
* Unfortunately, Lincheck was affected by the following bug in atomicfu
* (at the latest version 0.27.0 at the time when this comment was written):
* https://github.com/Kotlin/kotlinx-atomicfu/issues/525.
*
* To bypass the bug, the solution is to disable post-compilation JVM bytecode transformation
* and enable only the JVM-IR transformation at the Kotlin compilation stage.
*
* See also https://github.com/JetBrains/lincheck/issues/668 for a more detailed description of the bug.
*/
atomicfu {
transformJvm = false
}

sourceSets {
main {
java.srcDirs("src/jvm/main")
Expand Down Expand Up @@ -96,7 +136,10 @@ sourceSets {
val atomicfuVersion: String by project

compileOnly(project(":bootstrap"))
api(project(":trace"))
api(project(":common")) // TODO: `api` is used here in order to allow users of `lincheck` to access `LoggingLevel` enum class stored there,
// but later this enum will be marked as deprecated and then hidden, after that `api` should be changed to `implementation`
implementation(project(":jvm-agent"))
implementation(project(":trace"))

api("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
api("org.jetbrains.kotlin:kotlin-stdlib-common:$kotlinVersion")
Expand Down Expand Up @@ -178,6 +221,10 @@ tasks {
named<KotlinCompile>("compileTraceRecorderIntegrationTestKotlin") {
setupKotlinToolchain(project)
}

withType<KotlinCompile> {
getAccessToInternalDefinitionsOf(project(":common"))
}
}

// add an association to main and test modules to enable access to `internal` APIs inside integration tests:
Expand All @@ -201,19 +248,6 @@ fun KotlinCompilation<*>.configureAssociation() {
associateWith(test)
}

/*
* Unfortunately, Lincheck was affected by the following bug in atomicfu
* (at the latest version 0.27.0 at the time when this comment was written):
* https://github.com/Kotlin/kotlinx-atomicfu/issues/525.
*
* To bypass the bug, the solution is to disable post-compilation JVM bytecode transformation
* and enable only the JVM-IR transformation at the Kotlin compilation stage.
*
* See also https://github.com/JetBrains/lincheck/issues/668 for a more detailed description of the bug.
*/
atomicfu {
transformJvm = false
}

tasks.withType<Test> {
javaLauncher.set(
Expand Down Expand Up @@ -281,10 +315,10 @@ tasks {
if (!ideaActive) {
// We need to be able to run these tests in IntelliJ IDEA.
// Unfortunately, the current Gradle support doesn't detect
// the `jvmTestIsolated` and `trace[Debugger/Recorder]IntegrationTest` tasks.
// the `testIsolated` and `trace[Debugger/Recorder]IntegrationTest` tasks.
exclude("**/*IsolatedTest*")
exclude("org/jetbrains/trace_debugger/integration/*")
exclude("org/jetbrains/trace_recorder/integration/*")
exclude("org/jetbrains/trace/debugger/integration/*")
exclude("org/jetbrains/trace/recorder/integration/*")
}
// Do not run JdkUnsafeTraceRepresentationTest on Java 12 or earlier,
// as this test relies on specific ConcurrentHashMap implementation.
Expand Down Expand Up @@ -340,41 +374,42 @@ tasks {

registerTraceAgentIntegrationTestsPrerequisites()

val copyTraceDebuggerFatJar = copyTraceAgentFatJar(project(":trace-debugger"), "trace-debugger-fat.jar")
val copyTraceRecorderFatJar = copyTraceAgentFatJar(project(":trace-recorder"), "trace-recorder-fat.jar")

val traceDebuggerIntegrationTest = register<Test>("traceDebuggerIntegrationTest") {
configureJvmTestCommon()
group = "verification"
include("org/jetbrains/trace_debugger/integration/*")
include("org/jetbrains/trace/debugger/integration/*")

testClassesDirs = sourceSets["traceDebuggerIntegrationTest"].output.classesDirs
classpath = sourceSets["traceDebuggerIntegrationTest"].runtimeClasspath

outputs.upToDateWhen { false } // Always run tests when called
dependsOn(traceAgentIntegrationTestsPrerequisites)
dependsOn(copyTraceDebuggerFatJar)
}

val traceRecorderIntegrationTest = register<Test>("traceRecorderIntegrationTest") {
configureJvmTestCommon()
group = "verification"
include("org/jetbrains/trace_recorder/integration/*")
include("org/jetbrains/trace/recorder/integration/*")

testClassesDirs = sourceSets["traceRecorderIntegrationTest"].output.classesDirs
classpath = sourceSets["traceRecorderIntegrationTest"].runtimeClasspath

outputs.upToDateWhen { false } // Always run tests when called
dependsOn(traceAgentIntegrationTestsPrerequisites)
dependsOn(copyTraceRecorderFatJar)
}

check {
dependsOn += testIsolated
}
}

registerTraceAgentTasks()

val bootstrapJar = tasks.register<Copy>("bootstrapJar") {
dependsOn(":bootstrap:jar")
from(file("${project(":bootstrap").layout.buildDirectory.get()}/libs/bootstrap.jar"))
into(file("${layout.buildDirectory.get()}/resources/main"))
into(file("${project(":jvm-agent").layout.buildDirectory.get()}/resources/main"))
}

val jar = tasks.named<Jar>("jar") {
Expand All @@ -389,10 +424,10 @@ val sourcesJar = tasks.register<Jar>("sourcesJar") {
archiveClassifier.set("sources")
}

val javadocJar = createJavadocJar()
val javadocJar = createJavadocJar("src/jvm/main")

tasks.withType<Jar> {
dependsOn(bootstrapJar)
dependsOn(":bootstrapJar")

manifest {
val inceptionYear: String by project
Expand All @@ -410,7 +445,7 @@ tasks.withType<Jar> {
}

tasks.named("processResources").configure {
dependsOn(bootstrapJar)
dependsOn(":bootstrapJar")
}

publishing {
Expand Down Expand Up @@ -458,6 +493,8 @@ tasks {
val packSonatypeCentralBundle by registering(Zip::class) {
group = "publishing"

dependsOn(":common:publishMavenPublicationToArtifactsRepository")
dependsOn(":jvm-agent:publishMavenPublicationToArtifactsRepository")
dependsOn(":trace:publishMavenPublicationToArtifactsRepository")
dependsOn(":publishMavenPublicationToArtifactsRepository")

Expand Down
6 changes: 3 additions & 3 deletions buildSrc/src/main/kotlin/Documentation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@

import org.gradle.api.Project
import org.gradle.api.tasks.TaskProvider
import org.gradle.jvm.tasks.Jar
import org.gradle.api.tasks.bundling.Jar
import org.jetbrains.dokka.gradle.DokkaTask
import org.gradle.kotlin.dsl.*

fun Project.createJavadocJar(): TaskProvider<Jar> {
fun Project.createJavadocJar(mainSourceSetPath: String = "src/main"): TaskProvider<Jar> {
val dokkaHtml = tasks.named<DokkaTask>("dokkaHtml") {
outputDirectory.set(file("${layout.buildDirectory.get()}/javadoc"))
dokkaSourceSets {
named("main") {
sourceRoots.from(file("src/jvm/main"))
sourceRoots.from(file(mainSourceSetPath))
reportUndocumented.set(false)
}
}
Expand Down
15 changes: 15 additions & 0 deletions buildSrc/src/main/kotlin/Toolchain.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import org.gradle.jvm.toolchain.JavaToolchainService
import org.gradle.kotlin.dsl.provideDelegate
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.nio.file.Paths
import kotlin.text.get

fun KotlinJvmProjectExtension.configureKotlin() {
compilerOptions {
Expand Down Expand Up @@ -51,4 +53,17 @@ private fun KotlinCompile.setupKotlinToolchain(javaToolchains: JavaToolchainServ
kotlinJavaToolchain.toolchain.use(javaToolchains.launcherFor {
languageVersion.set(JavaLanguageVersion.of(jdkToolchainVersion))
})
}

fun KotlinCompile.getAccessToInternalDefinitionsOf(vararg projects: Project) {
projects.forEach { project ->
val mainSourceSet = project.extensions
.getByType(JavaPluginExtension::class.java).sourceSets
.getByName("main").output.classesDirs
val jarArchive = Paths.get(project.layout.buildDirectory.get().asFile.absolutePath, "libs",
if (project.name == "lincheck") project.name + "-" + project.version + ".jar"
else project.name + ".jar"
).toFile()
friendPaths.from(mainSourceSet + jarArchive)
}
}
22 changes: 21 additions & 1 deletion buildSrc/src/main/kotlin/TraceAgentIntegrationTestsTasks.kt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,26 @@ fun Project.registerTraceAgentIntegrationTestsPrerequisites() {

traceAgentIntegrationTestsPrerequisites = tasks.register("traceAgentIntegrationTestsPrerequisites") {
prerequisite.forEach { dependsOn(it) }
dependsOn("traceAgentFatJar")
dependsOn(":trace-debugger:traceDebuggerFatJar")
dependsOn(":trace-recorder:traceRecorderFatJar")
}
}

/**
* This function is required to copy `trace-recorder-fat.jar` and `trace-debugger-fat.jar` files from
* the corresponding projects into the lincheck's build directory. This allows integration tests to see
* the fat-jars and add paths to them via `-javaagent` VM flag.
*
* @param fromProject trace-debugger/recorder project from which to copy the fat-jar.
* @param fatJarName expected fat-jar name.
*/
fun Project.copyTraceAgentFatJar(fromProject: Project, fatJarName: String): TaskProvider<Copy> {
val copyTraceAgentFatJar = tasks.register<Copy>("${fromProject.name}_copyAgentFatJar") {
dependsOn(traceAgentIntegrationTestsPrerequisites)
val fatJarFile = fromProject.layout.buildDirectory.file("libs/$fatJarName")
from(fatJarFile)
into(layout.buildDirectory.dir("libs"))
}

return copyTraceAgentFatJar
}
14 changes: 7 additions & 7 deletions buildSrc/src/main/kotlin/TraceAgentTasks.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import org.gradle.api.plugins.JavaPluginExtension

// Below are tasks that are used by the trace debugger plugin.
// When these jars are loaded the `-Dlincheck.traceDebuggerMode=true` or `-Dlincheck.traceRecorderMode=true` VM argument is expected
fun Project.registerTraceAgentTasks() {
fun Project.registerTraceAgentTasks(fatJarName: String, fatJarTaskName: String, premainClass: String) {
// Ensure the Java plugin is applied (for sourceSets and runtimeClasspath)
plugins.apply("java")

Expand All @@ -28,12 +28,12 @@ fun Project.registerTraceAgentTasks() {

val runtimeClasspath = configurations.getByName("runtimeClasspath")

val traceAgentFatJar = tasks.register<Jar>("traceAgentFatJar") {
archiveBaseName.set("lincheck-fat")
val traceAgentFatJar = tasks.register<Jar>(fatJarTaskName) {
archiveBaseName.set(fatJarName)
archiveVersion.set("")
duplicatesStrategy = DuplicatesStrategy.EXCLUDE

dependsOn("bootstrapJar")
dependsOn(":bootstrapJar")

// Include compiled sources
from(mainSourceSet.output)
Expand All @@ -48,7 +48,7 @@ fun Project.registerTraceAgentTasks() {
manifest {
attributes(
mapOf(
"Premain-Class" to "org.jetbrains.kotlinx.lincheck.traceagent.TraceAgent",
"Premain-Class" to premainClass,
"Can-Redefine-Classes" to "true",
"Can-Retransform-Classes" to "true"
)
Expand All @@ -57,8 +57,8 @@ fun Project.registerTraceAgentTasks() {
}

// This jar is useful to add as a dependency to a test project to be able to debug
val traceAgentJarNoDeps = tasks.register<Jar>("traceAgentJarNoDeps") {
archiveBaseName.set("nodeps-trace-debugger")
val traceAgentJarNoDeps = tasks.register<Jar>("${fatJarTaskName}NoDeps") {
archiveBaseName.set("nodeps-$fatJarName")
duplicatesStrategy = DuplicatesStrategy.EXCLUDE

from(mainSourceSet.output)
Expand Down
Loading