Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Android API-friendliness checks #4505

Merged
merged 6 commits into from
Nov 24, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions conventions/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ dependencies {
implementation("org.ow2.asm:asm-tree:9.1")
implementation("org.apache.httpcomponents:httpclient:4.5.13")
implementation("org.gradle:test-retry-gradle-plugin:1.2.1")
implementation("ru.vyarus:gradle-animalsniffer-plugin:1.5.3")
// When updating, also update dependencyManagement/build.gradle.kts
implementation("net.bytebuddy:byte-buddy-gradle-plugin:1.11.20")
implementation("gradle.plugin.io.morethan.jmhreport:gradle-jmh-report:0.9.0")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
plugins {
`java-library`

id("ru.vyarus.animalsniffer")
}

dependencies {
add("signature", "com.toasttab.android:gummy-bears-api-21:0.3.0:coreLib@signature")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we call this conventions something like android or android-compatible?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I don't mind - I used otel.animalsniffer-conventions because the SDK file is named the same way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

android-compatibility? (and we can update in SDK repo too)

}

animalsniffer {
sourceSets = listOf(java.sourceSets.main.get())
}
24 changes: 24 additions & 0 deletions instrumentation-api/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import ru.vyarus.gradle.plugin.animalsniffer.AnimalSniffer

plugins {
id("org.xbib.gradle.plugin.jflex")

id("otel.java-conventions")
id("otel.animalsniffer-conventions")
id("otel.jacoco-conventions")
id("otel.japicmp-conventions")
id("otel.publish-conventions")
Expand Down Expand Up @@ -66,4 +69,25 @@ tasks {
isFailOnNoMatchingTests = false
}
}

withType<AnimalSniffer>().configureEach {
// we catch NoClassDefFoundError when use caffeine3 is not available on classpath and fall back to caffeine2
exclude("**/internal/shaded/caffeine3/**")

ignoreClasses = listOf(
// ignore shaded caffeine3 references
"io.opentelemetry.instrumentation.api.internal.shaded.caffeine3.cache.Caffeine",
"io.opentelemetry.instrumentation.api.internal.shaded.caffeine3.cache.Cache",

// these standard Java classes seem to be desugared properly
"java.lang.ClassValue",
"java.util.concurrent.CompletableFuture",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not aware of this working on API21 still (how are you verifying it desugars properly?).

I think it's ok because we don't call any caffeine API using it though so that's the comment we should add I guess?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how are you verifying it desugars properly?

I'm basing it on a very simple (probably too simple 😅 ) assumption -- if splunk-otel-android compiles correctly with instrumentation-api that uses those they're probably fine.
But it may as well be that those classes are just being referenced in those parts of caffeine that we don't call and it' the reason the whole thing works - I'll check that and update the comment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for clarifying - indeed that looks like API level 21

https://github.com/signalfx/splunk-otel-android/blob/main/splunk-otel-android/build.gradle

And if it's working it seems likely that it's because we don't call it indeed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I looked through all the ignored classes and it does seem that most of them come from not used code paths.
There are still several points to consider:

  • Unsafe is used in lots of places in caffeine - whether we're not really using it or it works properly on Android, it's hard to say. It seems to be okay though, so I left the ignore.
  • LongAdder in caffeine2 is only present in unused paths; we're using it in our SupportabilityMetrics though. Not used unless somebody sets the otel.javaagent.debug property, which seems rather unlikely in Android.
  • ClassValue is used in SpanNames and ClassNames - we're not using any of these in our Android repo, but it's not failing the compilation on desugaring problems so I decided to keep it in the ignores. I have no idea whether this actually works on Android though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's quite dangerous to put this here, since you might use it, and if it is actually used, it will break Android compatibility. Same with any of these overrides.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can quite easily remove the ClassValue and LongAdder usage - for example, we could replace ClassValue with our own Cache (we should better compare these 2 in a benchmark first though).

I don't have any good idea about what to do with the caffeine classes though.

"java.util.concurrent.CompletionException",
"java.util.concurrent.CompletionStage",
"java.util.concurrent.ConcurrentHashMap",
mateuszrzeszutek marked this conversation as resolved.
Show resolved Hide resolved
"java.util.concurrent.ForkJoinPool",
"java.util.concurrent.atomic.LongAdder",
"sun.misc.Unsafe"
)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id("otel.library-instrumentation")
id("otel.nullaway-conventions")
id("otel.animalsniffer-conventions")
}

dependencies {
Expand Down
1 change: 1 addition & 0 deletions instrumentation/grpc-1.6/library/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
plugins {
id("otel.library-instrumentation")
id("otel.animalsniffer-conventions")
}

val grpcVersion = "1.6.0"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id("otel.library-instrumentation")
id("otel.nullaway-conventions")
id("otel.animalsniffer-conventions")
}

dependencies {
Expand Down
1 change: 1 addition & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pluginManagement {
id("org.xbib.gradle.plugin.jflex") version "1.5.0"
id("nebula.release") version "15.3.1"
id("com.github.johnrengelman.shadow") version "7.0.0"
id("ru.vyarus.animalsniffer") version "1.5.3"
}
}

Expand Down