Question about how jvm level works with library de...
# library-development
c
Question about how jvm level works with library development (in this case an android library) I have my android library setup as JVM_17 and the library includes a dependency on a library that requires a bump to jvm 21. So I made the bump to 21. Does this mean consuming apps will need a bump to jvm 21? I of course tried it myself, and my sample app compiled without issues. So anyway just trying to sanity check if I should be expecting issues (maybe id get runtime issues and not compile time?)
This is what I mean as "setup as JVM 17"
Copy code
android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = "17"
    }
}
c
got it. so consumers will have to update (according to JW). so weird that i haven't updated in my sample app and everything still works.
since im here. does anyone know of a library that forces anything newer than java_11 in an android project? curious to see how that error gets shown to library consumers. or if its a runtime thing.
m
I don't think Jake said consumers have to update? The android toolchain will translate some/most of the newer APIs. But if you're unlucky and your dependency uses one symbol that is unsupported by your Android version then your app is going to crash
Spring uses java 17 now. It's not really Android but you can try to execute it on Android and see what happens.
c
"The biggest impact of bumping to 17 is that you force your consumers to also be using 17, but again, this makes no real difference and is just a minor annoyance." -Jake
m
Oh ok. Sorry I missed that. Must be the Gradle dependency resolution failing then
Try to add spring to your dependencies and Gradle should fail to resolve it
At least that's what I would expect
c
thanks. will give that a whirl. also maybe dumb question. but is there any way to check "what version" an aar was built with/requires? like if i can download the aar, can i inspect it to see a java 17 requirement? kinda talking out loud. but will investigate.
m
Unzip the aar, unzip classes.jar and run javap on any .class file in there
👀 1
But the important one is in the .module file, not .aar
Open your .module file and look for
org.gradle.jvm.version
. this is the one I expected to trigger a failure
Gradle duplicates that information and I don't like it
If you're publishing a .aar there's a non-zero chance that publishing without Gradle metadata (the .module file) makes it more compatible for consumers
c
Untitled
^ intersting. heres my library sample .module that gets generated. no mention of jvm version (AFAICT)
will try the aar route
m
Interesting... I'm curious how the error would show then 🤔
c
I can't get javap to work on a class (going to chatgpt it to see if it can figure it out), but i use a command line file browser, and when i "preview" a class file in the aar > classes.jar > it says this
so looks like its 1.8
m
What does javap say?
javap foo.class
c
Copy code
$ > javap ServerException.class

Compiled from ""
public final class com.myapp.sdk.api.exception.ServerException extends com.myapp.sdk.api.exception.MyAppException {
  public com.myapp.sdk.api.exception.ServerException(android.content.Context, java.lang.String, java.lang.String);
  public com.myapp.sdk.api.exception.ServerException(android.content.Context, java.lang.String, java.lang.String, int, kotlin.jvm.internal.DefaultConstructorMarker);
  public final java.lang.String getErrorMessage();
  public final java.lang.String getError();
}
m
Maybe with
-v
?
javap -v foo.class
c
major version: 52
m
Ah! Cool
So it's java 8
(the java version is that number minus 44 🤷)
c
(just like lint version is AGP version + 23 🤷 )
cool. thank you so much for teaching martin. i should be able to take it from here and figure out my issue
tried setting my own lib version to java 17. published. inspected the class with javap -v. indeed shows at major code 61. hooray. so it does work!
interesting that if i depend on my new java 17 dependency... in a new sample app that is set to java 11. i dont get any errors.
very weird. would have thought that would have done it.
m
I just tried it as well. Given that
org.gradle.jvm.version
isn't present in the module file, it's all working fine
🫡 1
As long as you're not using any API from JDK17 that is neither handled by R8/L8 or absent from your device
If you depend on a lib compiled for Java 21 (and uses removeFirst) that doesn't have
org.gradle.jvm.version
in the module file and you try to use that in an android app, it'll compile fine but you'll get a crash at runtime on devices < 35 (it's complicated)
👀 1
c
thanks for all the sanity checks. i really do wish there was a way to check. IIRC jake has also said that androidx targets java 11 and so i figured if i move my app down to java 8, then it would at least complain about androidx/java 11... but no dice even in that scenario
m
Yea, I don't think it would catch this in the absence of
org.gradle.jvm.version
. And TBH this is the "good" behaviour since the Android toolchain can deal with this
If you publish the same lib but as a .jar, chances are it will fail at build time while the Android toolchain could work with it quite well
There's just no build-time way to enforce everything will be working at runtime (that I know of)
Like said in that other thread,
animalsniffer
can help if you give it your lowest
android.jar
. But that's overly conservative since R8/L8 can transform a lot of things
❤️ 1