Skip to content
This repository was archived by the owner on Jan 27, 2021. It is now read-only.

Commit 18b1036

Browse files
committed
GEODE-8087: Fix Java binary compatibility errors reported by japicmp
* Fix 'exludeAnnotations' to use FQN of the annotation. * Allow changes if a class or superclass is marked @experimental
1 parent 8f0650e commit 18b1036

File tree

6 files changed

+192
-82
lines changed

6 files changed

+192
-82
lines changed

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ plugins {
2929
id "org.ajoberstar.grgit" version "4.0.1" apply false
3030
id "org.nosphere.apache.rat" version "0.6.0" apply false
3131
id "org.sonarqube" version "2.8" apply false
32-
id "me.champeau.gradle.japicmp" version "0.2.8"
32+
id "me.champeau.gradle.japicmp" apply false // Version defined in buildSrc/build.gradle
3333
}
3434

3535

buildSrc/build.gradle

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ plugins {
2222

2323
repositories {
2424
mavenCentral()
25+
maven {
26+
url "https://plugins.gradle.org/m2/"
27+
}
2528
}
2629

2730
dependencies {
@@ -32,6 +35,7 @@ dependencies {
3235
implementation('org.apache.commons:commons-lang3:3.3.2')
3336
implementation('org.apache.maven:maven-artifact:3.3.3')
3437
implementation('com.github.docker-java:docker-java:3.0.14')
38+
implementation('me.champeau.gradle:japicmp-gradle-plugin:0.2.8')
3539

3640
implementation('junit:junit:4.12')
3741

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.geode.gradle.japicmp
19+
20+
import japicmp.model.JApiCompatibility
21+
import me.champeau.gradle.japicmp.report.Violation
22+
import me.champeau.gradle.japicmp.report.stdrules.AbstractRecordingSeenMembers
23+
import me.champeau.gradle.japicmp.report.Severity
24+
25+
class AllowMajorBreakingChanges extends AbstractRecordingSeenMembers {
26+
@Override
27+
Violation maybeAddViolation(final JApiCompatibility member) {
28+
if (!member.isBinaryCompatible()) {
29+
return Violation.notBinaryCompatible(member, Severity.warning)
30+
} else {
31+
return null
32+
}
33+
}
34+
}
35+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.geode.gradle.japicmp;
19+
20+
import me.champeau.gradle.japicmp.report.Violation
21+
import me.champeau.gradle.japicmp.report.stdrules.AbstractRecordingSeenMembers
22+
import japicmp.model.JApiMethod
23+
import japicmp.model.JApiClass
24+
import japicmp.model.JApiSuperclass
25+
import japicmp.model.JApiConstructor
26+
import japicmp.model.JApiCompatibility
27+
28+
29+
class ParentIsExperimental extends AbstractRecordingSeenMembers {
30+
@Override
31+
public Violation maybeAddViolation(final JApiCompatibility member) {
32+
boolean isExperimental = true
33+
if (!member.isBinaryCompatible()) {
34+
if (member instanceof JApiMethod || member instanceof JApiConstructor) {
35+
isExperimental = isClassExperimental(member.jApiClass)
36+
} else if (member instanceof JApiClass) {
37+
isExperimental = isClassExperimental(member)
38+
}
39+
40+
if (isExperimental) {
41+
println("return accept [${member}]")
42+
return Violation.accept(member, "Parent class is @Experimental")
43+
}
44+
}
45+
}
46+
47+
boolean isClassExperimental(final JApiClass member) {
48+
println(" member annotations: [${member.annotations}]")
49+
boolean isExperimental = false
50+
if (!member.annotations.find {
51+
it.fullyQualifiedName == 'org.apache.geode.annotations.Experimental'
52+
}) {
53+
JApiSuperclass sup = member.superclass
54+
if (sup.getJApiClass().present) {
55+
isExperimental = isClassExperimental(sup.getJApiClass().get())
56+
} else {
57+
}
58+
} else {
59+
isExperimental = true
60+
}
61+
return isExperimental
62+
}
63+
}

geode-assembly/build.gradle

+1-81
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,12 @@
1515
* limitations under the License.
1616
*/
1717

18-
import me.champeau.gradle.japicmp.JapicmpTask
19-
import me.champeau.gradle.japicmp.report.Severity
20-
2118
apply from: "${rootDir}/${scriptDir}/standard-subproject-configuration.gradle"
2219
apply from: "${rootDir}/${scriptDir}/warnings.gradle"
2320

24-
2521
import org.apache.geode.gradle.plugins.DependencyConstraints
26-
import org.apache.maven.artifact.versioning.ComparableVersion
27-
import org.apache.maven.artifact.versioning.DefaultArtifactVersion
2822

2923
import java.nio.file.Paths
30-
import org.gradle.api.file.FileCollection
3124

3225
// This project aggressively reaches into many other projects and must wait for those configurations
3326
// to be evaluated and resolved. Evaluation depends on each of these subprojects.
@@ -703,77 +696,4 @@ acceptanceTest {
703696
dependsOn(tasks.docker)
704697
}
705698

706-
// For the list of 'old-versions' find the newest using semver
707-
// If the newest old release is a differnt major # than us, we can do what we want
708-
// otherwise, fail on x,y,z
709-
710-
def mostRecentReleaseProj = project(':geode-old-versions').subprojects.max(){ v -> new ComparableVersion(v.name)}
711-
def newest = mostRecentReleaseProj.name
712-
713-
import me.champeau.gradle.japicmp.report.ViolationRule
714-
import me.champeau.gradle.japicmp.report.Violation
715-
import japicmp.model.JApiCompatibility
716-
import japicmp.model.JApiMethod
717-
718-
class AllowMajorBreakingChanges implements ViolationRule {
719-
@Override
720-
Violation maybeViolation(final JApiCompatibility member) {
721-
if (!member.binaryCompatible()) {
722-
Violation.notBinaryCompatible(member, Severity.warning)
723-
}
724-
}
725-
}
726-
tasks.register('japicmp', me.champeau.gradle.japicmp.JapicmpTask) {
727-
inputs.files { tasks.named('distTar') }
728-
def ourUnpackTaskProvider = project(":geode-old-versions:${newest}").tasks.named('downloadAndUnzipFile')
729-
inputs.files { ourUnpackTaskProvider }
730-
731-
def d = Paths.get(project(":geode-old-versions:${newest}").buildDir.path.toString(), "apache-geode-${newest}", 'lib')
732-
oldClasspath = files()
733-
oldArchives = files()
734-
doFirst {
735-
oldClasspath = files(file(d).listFiles())
736-
oldArchives = files(file(d).listFiles(new FilenameFilter() {
737-
public boolean accept(File dir, String name) {
738-
return name.toLowerCase().startsWith("geode-") && name.toLowerCase().endsWith(".jar");
739-
};
740-
}))
741-
}
742-
743-
newClasspath = configurations.geodeArchives
744-
newArchives = configurations.geodeArchives.filter { File f ->
745-
f.toString().contains("geode-") && f.toString().endsWith(".jar")
746-
}
747-
748-
ignoreMissingClasses = true
749-
onlyModified = true
750-
accessModifier = "protected"
751-
752-
def allowMajorBreaking = false
753-
if (new DefaultArtifactVersion(version).majorVersion > new DefaultArtifactVersion(newest).majorVersion) {
754-
logger.error("disable fail on binary breaking changes")
755-
allowMajorBreaking = true
756-
}
757-
failOnModification = allowMajorBreaking
758-
failOnSourceIncompatibility = allowMajorBreaking
759-
760-
// onlyBinaryIncompatibleModified = true
761-
// includeSynthetic = true
762-
763-
def reportFileName = "japi-v${newest}-${version}"
764-
txtOutputFile = file("$buildDir/reports/${reportFileName}.txt")
765-
htmlOutputFile = file("$buildDir/reports/${reportFileName}.html")
766-
packageExcludes = ["*internal*"]
767-
packageIncludes = ["org.apache.geode.*"]
768-
annotationExcludes = ["@Experimental"]
769-
770-
richReport {
771-
title = "Geode API Compatibility Report"
772-
description = "Comparing current ${version} against downloaded v${newest}."
773-
reportName = "rich-report-${reportFileName}.html"
774-
if (allowMajorBreaking) {
775-
addRule(AllowMajorBreakingChanges)
776-
// addDefaultRules = failBuild
777-
}
778-
}
779-
}
699+
apply from: Paths.get("${rootDir}", 'gradle', 'japicmp.gradle')

gradle/japicmp.gradle

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import japicmp.model.JApiChangeStatus
19+
import org.apache.maven.artifact.versioning.ComparableVersion
20+
import org.apache.maven.artifact.versioning.DefaultArtifactVersion
21+
22+
import org.apache.geode.gradle.japicmp.AllowMajorBreakingChanges
23+
import org.apache.geode.gradle.japicmp.ParentIsExperimental
24+
25+
26+
def mostRecentReleaseProj = project(':geode-old-versions').subprojects.max(){ v -> new ComparableVersion(v.name)}
27+
def newest = mostRecentReleaseProj.name
28+
29+
tasks.register('japicmp', me.champeau.gradle.japicmp.JapicmpTask) {
30+
inputs.files { configurations.geodeArchives }
31+
def ourUnpackTaskProvider = project(":geode-old-versions:${newest}").tasks.named('downloadAndUnzipFile')
32+
inputs.files { ourUnpackTaskProvider }
33+
34+
def d = java.nio.file.Paths.get(project(":geode-old-versions:${newest}").buildDir.path.toString(), "apache-geode-${newest}", 'lib')
35+
// Dirty hack, to set the value as requied in configuration,
36+
// but then reset to the acutal unpacked jars on runtime.
37+
oldClasspath = files()
38+
oldArchives = files()
39+
doFirst {
40+
oldClasspath = files(file(d).listFiles())
41+
oldArchives = files(file(d).listFiles(new FilenameFilter() {
42+
public boolean accept(File dir, String name) {
43+
return name.toLowerCase().startsWith("geode-") && name.toLowerCase().endsWith(".jar");
44+
};
45+
}))
46+
}
47+
48+
newClasspath = configurations.geodeArchives
49+
newArchives = configurations.geodeArchives.filter { File f ->
50+
f.toString().contains("geode-") && f.toString().endsWith(".jar")
51+
}
52+
53+
ignoreMissingClasses = true
54+
onlyModified = true
55+
accessModifier = "protected"
56+
57+
def allowMajorBreaking = false
58+
if (new DefaultArtifactVersion(version).majorVersion > new DefaultArtifactVersion(newest).majorVersion) {
59+
logger.error("japicmp will always pass when comparing across major versions.")
60+
allowMajorBreaking = true
61+
}
62+
// failOnModification = !allowMajorBreaking
63+
// failOnSourceIncompatibility = !allowMajorBreaking
64+
65+
// onlyBinaryIncompatibleModified = true
66+
// includeSynthetic = true
67+
68+
def reportFileName = "japi-v${newest}-${version}"
69+
txtOutputFile = file("$buildDir/reports/${reportFileName}.txt")
70+
htmlOutputFile = file("$buildDir/reports/${reportFileName}.html")
71+
packageExcludes = ['*internal*']
72+
packageIncludes = ['org.apache.geode.*']
73+
annotationExcludes = ['@org.apache.geode.annotations.Experimental']
74+
75+
richReport {
76+
title = "Geode API Compatibility Report"
77+
description = "Comparing current ${version} against downloaded v${newest}."
78+
reportName = "rich-report-${reportFileName}.html"
79+
80+
if (allowMajorBreaking) {
81+
addRule(AllowMajorBreakingChanges)
82+
} else {
83+
addRule(JApiChangeStatus.REMOVED, ParentIsExperimental)
84+
addRule(JApiChangeStatus.MODIFIED, ParentIsExperimental)
85+
}
86+
addDefaultRules = true
87+
}
88+
}

0 commit comments

Comments
 (0)