-
Notifications
You must be signed in to change notification settings - Fork 56
Sample program crashes at SplashActivity in lean mode with target-version 14 #147
Comments
Just to note: this is the bog-standard lein-droid sample application from the lein-droid repository, one line in the project.clj modified to change :target-version from 18 to 14 |
Hm, I haven't really tested Skummet on older devices, so I'm not sure why this can happen. Apparently Dalvik rejects I infer your lean build pipeline includes proguarding the classes. Can you try disabling it by setting |
Sure. Tried that, still dies:
|
Hm, I have no other ideas yet. Unfortunately, I have too little time on my hands these days to investigate this myself. The only thing I can suggest to you is to google around what things might cause VerifyError on Dalvik and inspect clojure.lang.Var's bytecode inside Skummet's jar to search for possible causes. |
The actual cause appears to be this:
So, maybe something is optimizing that class out, but only when target 14 is used? As time permits, I'll investigate further. Thanks for Skummet though. I used it in an embedded project (not Android/Dalvik, just the Oracle JVM), and it dramatically improved startup time. |
That's really nice to hear! I'm planning to get back to active Skummet development to improve the startup time of our internal JVM projects. I'm glad someone has already tried that. |
I verified that the problem has something to do with the runtime. An apk compiled to target level 14 runs fine on an android 5.0 device, but crashes on the 4.0.4 device as so:
It's over my head at this point. I'll just set the minimum API level to the minimum device I can test on and get it to work, and put it out that way. |
I chased this down to at least this line: final static public Var OUT =
Var.intern(CLOJURE_NS, Symbol.intern("*out*"), new OutputStreamWriter(System.out)).setDynamic() Baksmali says, with lean mode and skummet, it becomes: .line 181
sget-object v8, Lclojure/lang/RT;->CLOJURE_NS:Lclojure/lang/Namespace;
const-string v9, "*out*"
invoke-static {v9}, Lclojure/lang/Symbol;->intern(Ljava/lang/String;)Lclojure/lang/Symbol;
move-result-object v9
new-instance v10, Ljava/io/OutputStreamWriter;
sget-object v11, Ljava/lang/System;->out:Ljava/io/PrintStream;
invoke-direct {v10, v11}, Ljava/io/OutputStreamWriter;-><init>(Ljava/io/OutputStream;)V
invoke-static {v8, v9, v10}, Lclojure/lang/Var;->intern(Lclojure/lang/Namespace;Lclojure/lang/Symbol;Ljava/lang/Object;)Lclojure/lang/Var;
move-result-object v8
invoke-virtual {v8}, Lclojure/lang/Var;->setDynamic()Lclojure/lang/Var;
move-result-object v8
sput-object v8, Lclojure/lang/RT;->OUT:Lclojure/lang/Var;
With debug mode using regular clojure (not skummet), I found something interesting. RT.java decompiles into several RT$1.java RT$2.java etc files, as well as an RT.smali file. And in RT.smali, that problematic line has a much shorter implementation: .line 181
const-string v5, "clojure.core"
invoke-static {v5}, Lclojure/lang/Symbol;->intern(Ljava/lang/String;)Lclojure/lang/Symbol;
move-result-object v5
invoke-static {v5}, Lclojure/lang/Namespace;->findOrCreate(Lclojure/lang/Symbol;)Lclojure/lang/Namespace;
move-result-object v5
sput-object v5, Lclojure/lang/RT;->CLOJURE_NS:Lclojure/lang/Namespace;
I'm still way over my head, but maybe this could save someone else time if they had the same problem. It also works in debug mode using regular clojure. One thing I haven't yet tried is to recompile skummet using the exact same compiler I'm using for this project. Maybe there's some problem with javac. |
The second bytecode you provided is actually for another command :) CLOJURE_NS = Namespace.findOrCreate(Symbol.intern("clojure.core")); It goes exactly before
What made you suspect this specific line? |
Oh. I was taking the stacktrace very literally:
And that's how I arrived at line 181. And in regular Clojure it does point to the bytecode for defining OUT. Still can't figure out why Android API 14 runtime choke on this though, while Android API 18 runtime does not? |
No ideas left, sorry:(. |
Just throwing this into the mix: I should note, I am compiling using Java 8. I haven't tried compiling with earlier java versions yet, but that might fix it. |
Oh, absolutely. Only Java7 is supported on Android, anything else is a wobbly incompatibility. |
I downgraded java and javac to version 7. Cleaned and built again. Same error. So it's not dependent on java or javac version. |
Runs fine in debug mode in target-version 14 on this android 4.0.4 device, but not in lean mode.
Is this fixable? I need to support ancient (cheap, used) devices with this app.
The text was updated successfully, but these errors were encountered: