diff --git a/.gitignore b/.gitignore index 92d3420..b523b0e 100644 --- a/.gitignore +++ b/.gitignore @@ -155,3 +155,4 @@ gradle-app.setting # Custom Ignores build.sh .env +bukkit/run diff --git a/build.gradle.kts b/build.gradle.kts index 20160c7..b9182b7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -46,6 +46,12 @@ subprojects { processResources { expand("version" to rootProject.version) } + + register("inspectDependencies") { + doLast { + inspectDependenciesForProject(project) + } + } } } diff --git a/buildSrc/src/main/kotlin/Configurations.kt b/buildSrc/src/main/kotlin/Configurations.kt index 2355af5..7811ce7 100644 --- a/buildSrc/src/main/kotlin/Configurations.kt +++ b/buildSrc/src/main/kotlin/Configurations.kt @@ -17,6 +17,8 @@ fun Project.setupShadowJar() { exclude(dependency("org.checkerframework:")) } + exclude("**/Utils21.class") + relocate( rootProject.group, "com.github.benmanes.caffeine", diff --git a/buildSrc/src/main/kotlin/DependencyInspection.kt b/buildSrc/src/main/kotlin/DependencyInspection.kt new file mode 100644 index 0000000..5f7b001 --- /dev/null +++ b/buildSrc/src/main/kotlin/DependencyInspection.kt @@ -0,0 +1,61 @@ +import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration +import java.io.File +import java.nio.ByteBuffer +import java.nio.ByteOrder + + +fun inspectDependenciesForProject(project: Project) { + val inspectConfig = createInspectionConfiguration(project) + val files = resolveDependencies(inspectConfig, project) ?: return + + if (files.isEmpty()) { + println("No dependencies found for project ${project.name}.") + return + } + + files.forEach { file -> + inspectClassFilesInJar(file, project) + } +} + +fun createInspectionConfiguration(project: Project): Configuration { + return project.configurations.create("inspectConfig").apply { + extendsFrom(project.configurations.findByName("implementation")) + isCanBeResolved = true + } +} + +fun resolveDependencies(configuration: Configuration, project: Project): Set? { + return try { + configuration.resolve() + } catch (e: Exception) { + println("Could not resolve dependencies for project ${project.name}.") + null + } +} + +fun inspectClassFilesInJar(file: File, project: Project) { + project.zipTree(file).visit { + if (name.endsWith(".class")) { + val majorVersion = extractMajorVersionFromClassFile(this.file) + + if (majorVersion == 65) { + println(""" + Warning: Class file in ${file.name} ${this.path} + uses Java class version $majorVersion (file version 65) + """.trimIndent()) + } + } + } +} + +fun extractMajorVersionFromClassFile(classFile: File): Int { + val classFileBytes = classFile.readBytes() + val byteBuffer = ByteBuffer.wrap(classFileBytes).order(ByteOrder.BIG_ENDIAN) + + // Skip the first 4 bytes for the magic number, then read the next two for minor and another two for major + byteBuffer.position(4) + val minorVersion = byteBuffer.short.toInt() + return byteBuffer.short.toInt() +}