1// ASM: a very small and fast Java bytecode manipulation framework 2// Copyright (c) 2000-2011 INRIA, France Telecom 3// All rights reserved. 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions 7// are met: 8// 1. Redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer. 10// 2. Redistributions in binary form must reproduce the above copyright 11// notice, this list of conditions and the following disclaimer in the 12// documentation and/or other materials provided with the distribution. 13// 3. Neither the name of the copyright holders nor the names of its 14// contributors may be used to endorse or promote products derived from 15// this software without specific prior written permission. 16// 17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27// THE POSSIBILITY OF SUCH DAMAGE. 28 29buildscript { 30 repositories { mavenCentral() } 31 dependencies { classpath 'org.netbeans.tools:sigtest-maven-plugin:1.5' } 32} 33 34plugins { id 'com.github.sherter.google-java-format' version '0.9' apply false } 35plugins { id 'me.champeau.jmh' version '0.6.8' apply false } 36plugins { id 'org.sonarqube' version '4.3.1.3277' apply false } 37 38description = 'ASM, a very small and fast Java bytecode manipulation framework' 39 40apply plugin: 'java-platform' 41dependencies { 42 constraints { 43 api project(':asm'), project(':asm-tree'), project(':asm-analysis') 44 api project(':asm-util'), project(':asm-commons') 45 } 46} 47 48allprojects { 49 group = 'org.ow2.asm' 50 version = '9.6' + (rootProject.hasProperty('release') ? '' : '-SNAPSHOT') 51} 52 53subprojects { 54 repositories { mavenCentral() } 55 apply plugin: 'java-library' 56 apply plugin: 'jacoco' 57 sourceCompatibility = '1.8' 58 targetCompatibility = '1.8' 59 test { useJUnitPlatform() } 60 ext.provides = [] // The provided java packages, e.g. ['org.objectweb.asm'] 61 ext.requires = [] // The required Gradle projects, e.g. [':asm-test'] 62 ext.transitiveRequires = { -> 63 return requires.collect{project(it)} 64 .collect{it.transitiveRequires().plus(it.provides[0])}.flatten() as Set 65 } 66 ext.transitiveImports = { -> 67 return requires.collect{project(it)} 68 .collect{it.transitiveImports().plus(it.provides)}.flatten() as Set 69 } 70 ext.depends = [] // The external dependencies, e.g. ['junit:junit:4.12'] 71 // Some external dependencies (such as Jacoco) depend transitively on ASM, and 72 // without this rule Gradle can mix ASM jars of different versions (e.g. 73 // asm-6.0.jar with the asm-tree.jar built locally). 74 configurations.all { resolutionStrategy { preferProjectModules() } } 75} 76 77// ----------------------------------------------------------------------------- 78// Project descriptions 79// ----------------------------------------------------------------------------- 80 81project(':asm') { 82 description = parent.description 83 provides = ['org.objectweb.asm', 'org.objectweb.asm.signature'] 84} 85 86project(':asm-analysis') { 87 description = "Static code analysis API of ${parent.description}" 88 provides = ['org.objectweb.asm.tree.analysis'] 89 requires = [':asm-tree'] 90} 91 92project(':asm-commons') { 93 description = "Usefull class adapters based on ${parent.description}" 94 provides = ['org.objectweb.asm.commons'] 95 requires = [':asm', ':asm-tree'] 96 dependencies { testImplementation project(':asm-util') } 97} 98 99project(':asm-test') { 100 description = "Utilities for testing ${parent.description}" 101 provides = ['org.objectweb.asm.test'] 102 depends = ['org.junit.jupiter:junit-jupiter-api:5.9.1', 103 'org.junit.jupiter:junit-jupiter-params:5.9.1'] 104} 105 106project(':asm-tree') { 107 description = "Tree API of ${parent.description}" 108 provides = ['org.objectweb.asm.tree'] 109 requires = [':asm'] 110} 111 112project(':asm-util') { 113 description = "Utilities for ${parent.description}" 114 provides = ['org.objectweb.asm.util'] 115 requires = [':asm', ':asm-tree', ':asm-analysis'] 116 dependencies { testImplementation 'org.codehaus.janino:janino:3.1.9' } 117} 118 119// Use "gradle benchmarks:jmh [-PjmhInclude='<regex>']" to run the benchmarks. 120project(':benchmarks') { 121 description = "Benchmarks for ${rootProject.description}" 122 apply plugin: 'me.champeau.jmh' 123 dependencies { 124 implementation files('libs/csg-bytecode-1.0.0.jar', 'libs/jclasslib.jar') 125 jmh project(':asm'), project(':asm-tree') 126 } 127 depends = [ 128 'kawa:kawa:1.7', 129 'net.sf.jiapi:jiapi-reflect:0.5.2', 130 'net.sourceforge.serp:serp:1.15.1', 131 'org.apache.bcel:bcel:6.0', 132 'org.aspectj:aspectjweaver:1.8.10', 133 'org.cojen:cojen:2.2.5', 134 'org.javassist:javassist:3.21.0-GA', 135 'org.mozilla:rhino:1.7.7.1' 136 ] 137 ['4.0', '5.0.1', '6.0', '7.0', '8.0.1', '9.0'].each { version -> 138 configurations.create("asm${version}") 139 dependencies.add("asm${version}", "org.ow2.asm:asm:${version}@jar") 140 dependencies.add("asm${version}", "org.ow2.asm:asm-tree:${version}@jar") 141 task "asm${version}"(type: Copy) { 142 from configurations."asm${version}".collect{zipTree(it)} 143 into "${buildDir}/asm${version}" 144 duplicatesStrategy = DuplicatesStrategy.INCLUDE // module-info.class 145 } 146 classes.dependsOn "asm${version}" 147 } 148 configurations.create('input-classes-java8') 149 dependencies.add('input-classes-java8', 'io.vavr:vavr:0.10.0@jar') 150 task copyInputClasses(type: Copy) { 151 from configurations.'input-classes-java8'.collect{zipTree(it)} 152 into "${buildDir}/input-classes-java8" 153 } 154 classes.dependsOn copyInputClasses 155 jmh { 156 jvmArgsAppend = ["-Duser.dir=${rootDir}"] 157 resultFormat = 'CSV' 158 profilers = ['org.objectweb.asm.benchmarks.MemoryProfiler'] 159 if (rootProject.hasProperty('jmhInclude')) { 160 includes = [jmhInclude] 161 } 162 } 163} 164 165project(':tools') { 166 description = "Tools used to build ${parent.description}" 167} 168 169project(':tools:retrofitter') { 170 description = "JDK 1.5 class retrofitter based on ${rootProject.description}" 171 sourceCompatibility = '1.9' 172 targetCompatibility = '1.9' 173 // TODO: this compiles asm twice (here and in :asm). 174 sourceSets.main.java.srcDirs += project(':asm').sourceSets.main.java.srcDirs 175} 176 177// ----------------------------------------------------------------------------- 178// Project tasks creation and configuration 179// ----------------------------------------------------------------------------- 180 181// All projects are checked with googleJavaFormat, Checkstyle and PMD, 182// and tested with :asm-test and JUnit. 183subprojects { 184 apply plugin: 'com.github.sherter.google-java-format' 185 googleJavaFormat.toolVersion = '1.15.0' 186 googleJavaFormat.exclude 'src/resources/java/**/*' 187 188 // Check the coding style with Checkstyle. Fail in case of error or warning. 189 apply plugin: 'checkstyle' 190 checkstyle.configFile = file("${rootDir}/tools/checkstyle.xml") 191 checkstyle.maxErrors = 0 192 checkstyle.maxWarnings = 0 193 194 // Check the code with PMD. 195 apply plugin: 'pmd' 196 pmd.ruleSets = [] 197 pmd.ruleSetFiles = files("${rootDir}/tools/pmd.xml") 198 pmd.consoleOutput = true 199 pmdMain.dependsOn ':asm:jar' 200 pmdTest.dependsOn ':asm:jar' 201 202 dependencies { 203 requires.each { projectName -> api project(projectName) } 204 depends.each { artifactName -> api artifactName } 205 testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1', 206 'org.junit.jupiter:junit-jupiter-params:5.9.1' 207 testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.1' 208 testImplementation project(':asm-test') 209 } 210 211 // Produce byte-for-byte reproducible archives. 212 tasks.withType(AbstractArchiveTask).configureEach { 213 preserveFileTimestamps = false 214 reproducibleFileOrder = true 215 dirMode = 0775 216 fileMode = 0664 217 } 218} 219 220// Configure the projects with a non-empty 'provides' property. They must be 221// checked for code coverage and backward compatibility, retrofited to Java 1.5, 222// and packaged with generated module-info classes. 223configure(subprojects.findAll{it.provides}) { 224 // Code coverage configuration. 225 jacoco.toolVersion = '0.8.10' 226 jacocoTestReport { 227 reports { xml.required = true } 228 classDirectories.setFrom(sourceSets.main.output.classesDirs) 229 } 230 jacocoTestCoverageVerification { 231 classDirectories.setFrom(sourceSets.main.output.classesDirs) 232 violationRules.rule { limit { minimum = 0.95; counter = 'INSTRUCTION' } } 233 dependsOn ':asm:jar' 234 dependsOn ':asm-tree:jar' 235 dependsOn ':asm-commons:jar' 236 } 237 check.dependsOn jacocoTestCoverageVerification 238 239 // Retrofit the code in-place to Java 1.5 and generate a module-info class 240 // from the code content, in compileJava.doLast. 241 if (name != 'asm-test') { 242 compileJava.dependsOn ':tools:retrofitter:classes' 243 compileJava.doLast { 244 def path = project(':tools:retrofitter').sourceSets.main.runtimeClasspath 245 def loader = new URLClassLoader(path.collect {f -> f.toURL()} as URL[]) 246 def retrofitter = 247 loader.loadClass('org.objectweb.asm.tools.Retrofitter').newInstance() 248 def classes = sourceSets.main.output.classesDirs.singleFile 249 def requires = transitiveRequires() as List 250 retrofitter.retrofit(classes, "${version}") 251 retrofitter.verify(classes, "${version}", provides, requires) 252 } 253 } 254 255 // Create one backward compatibility checking task for each 'sigtest-*' file 256 // in test/resources, and make the 'check' task depend on all these tasks. 257 if (file('src/test/resources/').exists()) { 258 file('src/test/resources/').eachFileMatch(~/sigtest-.*/) { f -> 259 task "${f.name}"(dependsOn: 'classes') { 260 inputs.files(f, sourceSets.main.java) 261 outputs.file("${buildDir}/${f.name}") 262 doLast { 263 def sigtest = new com.sun.tdk.signaturetest.SignatureTest() 264 def args = ['-ApiVersion', version, '-Backward', '-Static', 265 '-Mode', 'bin', '-FileName', f, '-Classpath', 266 project(':tools').file('jdk8-api.jar').path + File.pathSeparator + 267 sourceSets.main.output.classesDirs.asPath, '-Package'] + provides 268 outputs.getFiles()[0].withPrintWriter { printWriter -> 269 sigtest.run(args as String[], printWriter, null) 270 } 271 if (!sigtest.isPassed()) throw new GradleException() 272 } 273 } 274 check.dependsOn f.name 275 } 276 // Define a task to create a sigtest file for the current version. 277 task "buildSigtest"(dependsOn: 'classes') { 278 inputs.files(sourceSets.main.java) 279 outputs.file("src/test/resources/sigtest-${version}.txt") 280 doLast { 281 def setup = new com.sun.tdk.signaturetest.Setup() 282 def args = ['-ApiVersion', version, '-FileName', outputs.getFiles()[0], 283 '-Classpath', project(':tools').file('jdk8-api.jar').path + 284 File.pathSeparator + sourceSets.main.output.classesDirs.asPath + 285 File.pathSeparator + sourceSets.main.compileClasspath.asPath, 286 '-Package'] + provides 287 setup.run(args as String[], new PrintWriter(System.err, true), null) 288 if (!setup.isPassed()) throw new GradleException() 289 } 290 } 291 } 292 293 jar.manifest.attributes( 294 'Implementation-Title': project.description, 295 'Implementation-Version': "${version}") 296 // Package the project as an OSGi bundle. Exclude the asm-test project (the 297 // DefaultPackage class prevents it from being a proper bundle). 298 if (name != 'asm-test') { 299 def imports = transitiveImports() 300 jar.manifest.attributes( 301 'Bundle-DocURL': 'http://asm.ow2.org', 302 'Bundle-License': 'BSD-3-Clause;link=https://asm.ow2.io/LICENSE.txt', 303 'Bundle-ManifestVersion': 2, 304 'Bundle-Name': provides[0], 305 'Bundle-RequiredExecutionEnvironment': 'J2SE-1.5', 306 'Bundle-SymbolicName': provides[0], 307 'Bundle-Version': "${version}", 308 'Export-Package': 309 provides.collect{"${it};version=\"${version}\""}.join(',') + 310 (imports ? ";uses:=\"${imports.join(',')}\"" : "")) 311 if (imports) { 312 jar.manifest.attributes( 313 'Import-Package': 314 imports.collect{"${it};version=\"${version}\""}.join(','), 315 'Module-Requires': 316 transitiveRequires().collect{"${it};transitive=true"}.join(',')) 317 } 318 } 319 320 // Apply the SonarQube plugin to monitor the code quality of the project. 321 // Use with 'gradlew sonar -Dsonar.host.url=https://sonarqube.ow2.org'. 322 apply plugin: 'org.sonarqube' 323 sonar { 324 properties { property 'sonar.projectKey', "ASM:${project.name}" } 325 } 326 327 // Add a task to generate a private javadoc and add it as a dependency of the 328 // 'check' task. 329 task privateJavadoc(type: Javadoc) { 330 source = sourceSets.main.allJava 331 classpath = configurations.compileClasspath 332 destinationDir = file("${javadoc.destinationDir}-private") 333 options.memberLevel = JavadocMemberLevel.PRIVATE 334 options.addBooleanOption('Xdoclint:all,-missing', true) 335 } 336 check.dependsOn privateJavadoc 337 338 // Add tasks to generate the Javadoc and a source jar, to be uploaded to Maven 339 // together with the main jar (containing the compiled code). 340 task javadocJar(type: Jar, dependsOn: 'javadoc') { 341 from javadoc.destinationDir 342 archiveClassifier = 'javadoc' 343 } 344 task sourcesJar(type: Jar, dependsOn: 'classes') { 345 from sourceSets.main.allSource 346 archiveClassifier = 'sources' 347 } 348 java { 349 withJavadocJar() 350 withSourcesJar() 351 } 352} 353 354// Configure the root project, and those with a non-empty 'provides' property, 355// to be published in Maven with a POM. 356configure([rootProject] + subprojects.findAll { it.provides }) { 357 apply plugin: 'maven-publish' 358 apply plugin: 'signing' 359 publishing { 360 repositories { 361 maven { 362 def baseUrl = 'https://repository.ow2.org/nexus/' 363 def releasesUrl = baseUrl + 'service/local/staging/deploy/maven2' 364 def snapshotsUrl = baseUrl + 'content/repositories/snapshots' 365 name = 'nexus' 366 url = rootProject.hasProperty('release') ? releasesUrl : snapshotsUrl 367 credentials { 368 username System.env.NEXUS_USER_NAME 369 password System.env.NEXUS_PASSWORD 370 } 371 } 372 } 373 publications { 374 maven(MavenPublication) { 375 def isRoot = project == rootProject 376 artifactId (isRoot ? 'asm-bom' : project.name) 377 from (isRoot ? components.javaPlatform : components.java) 378 pom.withXml { 379 def parent = asNode().appendNode('parent') 380 parent.appendNode('groupId', 'org.ow2') 381 parent.appendNode('artifactId', 'ow2') 382 parent.appendNode('version', '1.5.1') 383 } 384 pom { 385 name = artifactId 386 description = project.description 387 packaging 'jar' 388 inceptionYear = '2000' 389 licenses { 390 license { 391 name = 'BSD-3-Clause' 392 url = 'https://asm.ow2.io/license.html' 393 } 394 } 395 url = 'http://asm.ow2.io/' 396 mailingLists { 397 mailingList { 398 name = 'ASM Users List' 399 subscribe = 'https://mail.ow2.org/wws/subscribe/asm' 400 post = '[email protected]' 401 archive = 'https://mail.ow2.org/wws/arc/asm/' 402 } 403 mailingList { 404 name = 'ASM Team List' 405 subscribe = 'https://mail.ow2.org/wws/subscribe/asm-team' 406 post = '[email protected]' 407 archive = 'https://mail.ow2.org/wws/arc/asm-team/' 408 } 409 } 410 issueManagement { 411 url = 'https://gitlab.ow2.org/asm/asm/issues' 412 } 413 scm { 414 connection = 'scm:git:https://gitlab.ow2.org/asm/asm/' 415 developerConnection = 'scm:git:https://gitlab.ow2.org/asm/asm/' 416 url = 'https://gitlab.ow2.org/asm/asm/' 417 } 418 developers { 419 developer { 420 name = 'Eric Bruneton' 421 id = 'ebruneton' 422 email = '[email protected]' 423 roles = ['Creator', 'Java Developer'] 424 } 425 developer { 426 name = 'Eugene Kuleshov' 427 id = 'eu' 428 email = '[email protected]' 429 roles = ['Java Developer'] 430 } 431 developer { 432 name = 'Remi Forax' 433 id = 'forax' 434 email = '[email protected]' 435 roles = ['Java Developer'] 436 } 437 } 438 organization { 439 name = 'OW2' 440 url = 'http://www.ow2.org/' 441 } 442 } 443 } 444 } 445 } 446 signing { 447 required rootProject.hasProperty('release') 448 sign publishing.publications.maven 449 } 450 tasks.withType(GenerateModuleMetadata) { enabled = false } 451} 452