Skip to content

Commit

Permalink
[CALCITE-6393] Add bytecode verification check using ASM in the gradl…
Browse files Browse the repository at this point in the history
…e build
  • Loading branch information
zabetak committed May 2, 2024
1 parent 1506857 commit 4c02740
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 0 deletions.
11 changes: 11 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApis
import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApisExtension
import java.net.URI
import net.ltgt.gradle.errorprone.errorprone
import org.apache.calcite.buildtools.asmchecker.AsmCheckerTask
import org.apache.calcite.buildtools.buildext.dsl.ParenthesisBalancer
import org.gradle.api.tasks.testing.logging.TestExceptionFormat

Expand All @@ -37,6 +38,7 @@ plugins {
publishing
// Verification
checkstyle
id("calcite.asmchecker")
calcite.buildext
jacoco
id("jacoco-report-aggregation")
Expand Down Expand Up @@ -844,6 +846,15 @@ allprojects {
}
jvmArgs("-Xmx6g")
}
register<AsmCheckerTask>("bytecodeCheck") {
group = LifecycleBasePlugin.VERIFICATION_GROUP
description = "Checks the bytecode of every .class file in the build directory using ASM."
dependsOn("classes")
}

check {
dependsOn("bytecodeCheck")
}
configureEach<SpotBugsTask> {
group = LifecycleBasePlugin.VERIFICATION_GROUP
if (enableSpotBugs) {
Expand Down
1 change: 1 addition & 0 deletions buildSrc/settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pluginManagement {
}
}

include("asmchecker")
include("javacc")
include("fmpp")
include("buildext")
Expand Down
34 changes: 34 additions & 0 deletions buildSrc/subprojects/asmchecker/asmchecker.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

dependencies {
val asmVersion = "9.6"
implementation("org.ow2.asm:asm:$asmVersion")
implementation("org.ow2.asm:asm-analysis:$asmVersion")
implementation("org.ow2.asm:asm-commons:$asmVersion")
implementation("org.ow2.asm:asm-tree:$asmVersion")
implementation("org.ow2.asm:asm-util:$asmVersion")
}

gradlePlugin {
plugins {
register("asmchecker") {
id = "calcite.asmchecker"
implementationClass = "org.apache.calcite.buildtools.asmchecker.AsmCheckerPlugin"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.calcite.buildtools.asmchecker

import org.gradle.api.Plugin
import org.gradle.api.Project

open class AsmCheckerPlugin : Plugin<Project> {
override fun apply(target: Project) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.calcite.buildtools.asmchecker

import java.nio.file.Files
import java.nio.file.Paths
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.TaskAction
import org.objectweb.asm.ClassReader
import org.objectweb.asm.ClassWriter
import org.objectweb.asm.commons.ClassRemapper
import org.objectweb.asm.commons.Remapper
import org.objectweb.asm.util.CheckClassAdapter

@CacheableTask
open class AsmCheckerTask : DefaultTask() {

@TaskAction
fun run() {
project.buildDir.walk().filter { file -> file.getName().toLowerCase().endsWith(".class") }
.forEach {
val classReader = ClassReader(Files.readAllBytes(Paths.get(it.getPath())))
val classVisitor = CheckClassAdapter(ClassWriter(ClassWriter.COMPUTE_MAXS))
val classRemapper = ClassRemapper(classVisitor, object : Remapper() {})
try {
classReader.accept(classRemapper, ClassReader.EXPAND_FRAMES)
} catch (e: java.lang.RuntimeException) {
throw java.lang.RuntimeException("Invalid bytecode file:" + it, e)
}
}
}
}

0 comments on commit 4c02740

Please sign in to comment.