Skip to content

Add Protobuf/gRPC-based EtsIR loader #318

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

Open
wants to merge 1 commit into
base: neo
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 7 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
cache-read-only: ${{ github.ref != 'refs/heads/develop' && github.ref != 'ref/heads/neo' }}

- name: Build and run tests
run: ./gradlew --scan build -x :jacodb-ets:build
run: ./gradlew --scan build

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
Expand Down Expand Up @@ -122,11 +122,11 @@ jobs:

- name: Set up ArkAnalyzer
run: |
REPO_URL="https://gitcode.com/Lipen/arkanalyzer"
REPO_URL="https://gitcode.com/Lipen/arkanalyzer.git"
DEST_DIR="arkanalyzer"
MAX_RETRIES=10
RETRY_DELAY=3 # Delay between retries in seconds
BRANCH="neo/2025-06-16"
RETRY_DELAY=3 # Delay between retries in seconds
BRANCH="neo/2025-06-20"

for ((i=1; i<=MAX_RETRIES; i++)); do
git clone --depth=1 --branch $BRANCH $REPO_URL $DEST_DIR && break
Expand All @@ -147,6 +147,9 @@ jobs:
npm install
npm run build

- name: Enable ETS modules
run: echo "enableEts=true" >> local.properties

- name: Run ETS tests
run: ./gradlew --scan :jacodb-ets:generateTestResources :jacodb-ets:test

Expand Down
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
.idea/
.gradle/
build/
.kotlin/
build/
generated/
idea-community
*.db
/generated/
/local.properties
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ allprojects {
license {
include("**/*.kt")
include("**/*.java")
exclude { it.file.startsWith(layout.buildDirectory.asFile.get()) }
header(rootProject.file("docs/copyright/COPYRIGHT_HEADER.txt"))
}
}
Expand All @@ -173,7 +174,6 @@ if (!repoUrl.isNullOrEmpty()) {
project(":jacodb-storage"),
project(":jacodb-approximations"),
project(":jacodb-taint-configuration"),
project(":jacodb-ets"),
)
) {
tasks {
Expand Down
4 changes: 4 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ plugins {
repositories {
mavenCentral()
}

dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
}
82 changes: 69 additions & 13 deletions buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ object Versions {
const val asm = "9.7.1"
const val dokka = "1.9.20" // note: must be compatible with kotlin version
const val gradle_download = "5.3.0"
const val gradle_node = "7.1.0"
const val gradle_versions = "0.47.0"

// hikaricp version compatible with Java 8
const val hikaricp = "4.0.3"

const val grpc = "1.72.0"
const val grpc_kotlin = "1.4.3"
const val guava = "31.1-jre"
const val hikaricp = "4.0.3" // compatible with Java 8
const val javax_activation = "1.1"
const val javax_mail = "1.4.7"
const val javax_servlet_api = "2.5"
Expand All @@ -24,23 +24,26 @@ object Versions {
const val junit = "5.9.2"
const val kotlin = "2.1.0"
const val kotlin_logging = "1.8.3"
const val kotlin_metadata = kotlin
const val kotlinx_benchmark = "0.4.6"
const val kotlinx_cli = "0.3.5"
const val kotlinx_collections_immutable = "0.3.5"
const val kotlinx_coroutines = "1.6.4"
const val kotlin_metadata = kotlin
const val kotlinx_serialization = "1.8.0"
const val licenser = "0.6.1"
const val lmdb_java = "0.9.0"
const val mockk = "1.13.3"
const val protobuf = "4.30.2"
const val rocks_db = "9.1.1"
const val sarif4k = "0.5.0"
const val shadow = "8.1.1"
const val slf4j = "1.7.36"
const val slf4j = "2.0.17"
const val soot_utbot_fork = "4.4.0-FORK-2"
const val sootup = "1.0.0"
const val sqlite = "3.41.2.2"
const val xodus = "2.0.1"
const val rocks_db = "9.1.1"
const val lmdb_java = "0.9.0"
const val wire = "5.3.1"
const val wire_grpc_server = "1.0.0-alpha04"

// libs for tests only
const val jgit_test_only_version = "5.9.0.202009080501-r"
Expand Down Expand Up @@ -144,11 +147,6 @@ object Libs {
)

// https://github.com/Kotlin/kotlinx.serialization
val kotlinx_serialization_core = dep(
group = "org.jetbrains.kotlinx",
name = "kotlinx-serialization-core",
version = Versions.kotlinx_serialization
)
val kotlinx_serialization_json = dep(
group = "org.jetbrains.kotlinx",
name = "kotlinx-serialization-json",
Expand Down Expand Up @@ -339,6 +337,52 @@ object Libs {
name = "commons-compress",
version = Versions.commons_compress_test_only_version
)

// https://github.com/grpc/grpc-java
val grpc_api = dep(
group = "io.grpc",
name = "grpc-api",
version = Versions.grpc
)
val grpc_protobuf = dep(
group = "io.grpc",
name = "grpc-protobuf",
version = Versions.grpc
)
val grpc_services = dep(
group = "io.grpc",
name = "grpc-services",
version = Versions.grpc
)
val grpc_netty_shaded = dep(
group = "io.grpc",
name = "grpc-netty-shaded",
version = Versions.grpc
)

// https://github.com/square/wire
val wire_runtime = dep(
group = "com.squareup.wire",
name = "wire-runtime",
version = Versions.wire
)
val wire_grpc_client = dep(
group = "com.squareup.wire",
name = "wire-grpc-client",
version = Versions.wire
)

// https://github.com/square/wire-grpc-server
val wire_grpc_server = dep(
group = "com.squareup.wiregrpcserver",
name = "server",
version = Versions.wire_grpc_server
)
val wire_grpc_server_generator = dep(
group = "com.squareup.wiregrpcserver",
name = "server-generator",
version = Versions.wire_grpc_server
)
}

object Plugins {
Expand All @@ -357,6 +401,12 @@ object Plugins {
id = "de.undercouch.download"
)

// https://github.com/node-gradle/gradle-node-plugin
object GradleNode : ProjectPlugin(
version = Versions.gradle_node,
id = "com.github.node-gradle.node"
)

// https://github.com/ben-manes/gradle-versions-plugin
object GradleVersions : ProjectPlugin(
version = Versions.gradle_versions,
Expand All @@ -380,6 +430,12 @@ object Plugins {
version = Versions.shadow,
id = "com.github.johnrengelman.shadow"
)

// https://github.com/square/wire
object Wire : ProjectPlugin(
version = Versions.wire,
id = "com.squareup.wire"
)
}

fun PluginDependenciesSpec.id(plugin: Plugins.ProjectPlugin) {
Expand Down
77 changes: 77 additions & 0 deletions buildSrc/src/main/kotlin/ProcessUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.Reader
import java.util.concurrent.TimeUnit
import kotlin.time.Duration

object ProcessUtil {
data class Result(
val exitCode: Int,
val stdout: String,
val stderr: String,
val isTimeout: Boolean, // true if the process was terminated due to timeout
)

fun run(
command: List<String>,
input: Reader = "".reader(),
timeout: Duration? = null,
builder: ProcessBuilder.() -> Unit = {},
): Result {
val process = ProcessBuilder(command).apply(builder).start()
return communicate(process, input, timeout)
}

private fun communicate(
process: Process,
input: Reader,
timeout: Duration? = null,
): Result {
val stdout = StringBuilder()
val stderr = StringBuilder()

val scope = CoroutineScope(Dispatchers.IO)

// Handle process input
val stdinJob = scope.launch {
process.outputStream.bufferedWriter().use { writer ->
input.copyTo(writer)
}
}

// Launch output capture coroutines
val stdoutJob = scope.launch {
process.inputStream.bufferedReader().useLines { lines ->
lines.forEach { stdout.appendLine(it) }
}
}
val stderrJob = scope.launch {
process.errorStream.bufferedReader().useLines { lines ->
lines.forEach { stderr.appendLine(it) }
}
}

// Wait for completion
val isTimeout = if (timeout != null) {
!process.waitFor(timeout.inWholeNanoseconds, TimeUnit.NANOSECONDS)
} else {
process.waitFor()
false
}

// Wait for all coroutines to finish
runBlocking {
joinAll(stdinJob, stdoutJob, stderrJob)
}

return Result(
exitCode = process.exitValue(),
stdout = stdout.toString(),
stderr = stderr.toString(),
isTimeout = isTimeout,
)
}
}
1 change: 1 addition & 0 deletions jacodb-ets/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
arkanalyzer
/src/test/resources/samples/etsir
/src/test/resources/projects

Expand Down
Loading