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