clojure-android / neko

The Clojure/Android Toolkit
Other
297 stars 36 forks source link

Ref-adapter classloader explodes at runtime #29

Closed kenrestivo closed 10 years ago

kenrestivo commented 10 years ago

Does ref-adapter work?

I'm trying to use ref-adapter, looks very cool, but explodes at runtime with, among other things, the following:

E AndroidRuntime(7164)        Caused by: java.lang.ClassNotFoundException: neko.ui.adapters.InterchangeableListAdapter
E AndroidRuntime(7164)          at java.lang.Class.classForName(Native Method)
E AndroidRuntime(7164)          at java.lang.Class.forName(Class.java:217)
E AndroidRuntime(7164)          at java.lang.Class.forName(Class.java:172)
E AndroidRuntime(7164)          at neko.ui.adapters$loading__4910__auto__.invoke(adapters.clj:12)
E AndroidRuntime(7164)          at neko.ui.adapters__init.load(Unknown Source)
E AndroidRuntime(7164)          at neko.ui.adapters__init.<clinit>(Unknown Source)
E AndroidRuntime(7164)          ... 36 more
E AndroidRuntime(7164)        Caused by: java.lang.NoClassDefFoundError: neko/ui/adapters/InterchangeableListAdapter
E AndroidRuntime(7164)          ... 42 more

It's unclear from the stacktrace where exactly the failure is, but it happens at the SplashActivity, and the code which calls ref-adapter is:

(defn schedule-adapter []
  (adapters/ref-adapter
   (fn [] [:text-view {}])
   (fn [_ view _ show]
     (on-ui
      (.setText view (format-show show)))) 
   schedule/schedule
   :future))

My versions of things are:

Leiningen 2.3.4 on Java 1.7.0_03 OpenJDK 64-Bit Server VM

And Android SDK 22.3.

And some project stuff:

; ...
  :source-paths ["src/clojure" "src"]
  :java-source-paths ["src/java" "gen"]
  :plugins [[lein-droid "0.2.2"]]
  :javac-options ["-target" "1.6" "-source" "1.6" "-Xlint:-options"]
  :dependencies [[org.clojure-android/clojure "1.5.1-jb" :use-resources true]
                 [neko/neko "3.0.0"]
                 [utilza "0.1.53"]
                 [cheshire "5.3.0"]]
  :profiles {:dev {:dependencies [[android/tools.nrepl "0.2.0-bigstack"]
                                  [clojure-complete "0.2.3"]
                                  [compliment "0.0.3"]]
; ...
  :android {
            :dex-opts ["-JXmx4096M"]
            :support-libraries ["v13"] ;; needed for localbroadcast
            :target-version "14"
            :aot-exclude-ns [clojure.parallel
                             clojure.core.reducers
; ...

And I'm building with lein-droid doall.

I've tried cleaning with lein clean, and wiping out the old APK on the device.

The device is a TF101 running CM 9.1.

Indeed, I looked into the classes.dex and if I am reading it correctly the class is not in there, though it is referenced:

  Virtual methods   -
    #0              : (in Lneko/ui/adapters$ref_adapter;)
      name          : 'invoke'
      type          : '(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;'
      access        : 0x0001 (PUBLIC)
      code          -
      registers     : 13
      ins           : 4
      outs          : 5
      insns size    : 33 16-bit code units
      catches       : (none)
      positions     : 
        0x0000 line=19
      locals        : 
        0x0001 - 0x0020 reg=0 this Lneko/ui/adapters$ref_adapter; 
        0x0002 - 0x0021 reg=1 create_view_fn Ljava/lang/Object; 
        0x0003 - 0x0021 reg=2 update_view_fn Ljava/lang/Object; 
        0x0004 - 0x0021 reg=3 ref_type Ljava/lang/Object; 
        0x0000 - 0x0021 reg=9 this Lneko/ui/adapters$ref_adapter; 
    #1              : (in Lneko/ui/adapters$ref_adapter;)
      name          : 'invoke'
      type          : '(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;'
      access        : 0x0001 (PUBLIC)
      code          -
      registers     : 20
      ins           : 5
      outs          : 4
      insns size    : 310 16-bit code units
      catches       : (none)
      positions     : 
        0x0000 line=19
        0x005e line=44
        0x0078 line=45
        0x009a line=19
      locals        : 
        0x004f - 0x0057 reg=5 create_fn Lneko/ui/adapters$ref_adapter$create_fn__2359; 
        0x0001 - 0x0099 reg=0 this Lneko/ui/adapters$ref_adapter; 
        0x0078 - 0x0099 reg=6 adapter Lneko/ui/adapters/InterchangeableListAdapter; 
        0x0057 - 0x009a reg=5 create_fn Ljava/lang/Object; 
        0x009a - 0x0136 reg=0 this Lneko/ui/adapters$ref_adapter; 
        0x0003 - 0x0136 reg=1 create_view_fn Ljava/lang/Object; 
        0x0005 - 0x0136 reg=2 update_view_fn Ljava/lang/Object; 
        0x0007 - 0x0136 reg=3 ref_type Ljava/lang/Object; 
        0x0009 - 0x0136 reg=4 access_fn Ljava/lang/Object; 
        0x0000 - 0x0136 reg=15 this Lneko/ui/adapters$ref_adapter; 
  source_file_idx   : 15306 (adapters.clj)

And, looking in target/classes, there's nothing there either.

find target/ -name '*InterchangeableListAdapter*'
$

So, it looks like this class is not getting compiled at all? Why would that be? Is there something wrong with my toolchain, is there something I have misconfigured, or is something missing from neko?

alexander-yakushev commented 10 years ago

This is weird. InterchangeableListAdapter is a part of Neko, it is written in Java, and is included into Neko jar in the compiled form. So for some reason it is not included into dex-file, I've never faced such an issue.

This could be a problem of JDK version mismatch. Can you try doing the same with Neko 3.0.1? It doesn't contain any relevant changes but I could have compiled it with JDK7 (while 3.0.0 might be compiled with 6).

Also, can you do DEBUG=1 lein droid create-dex to see all the jars that are scanned for classfiles during dexing?

kenrestivo commented 10 years ago

Will do. With neko 3.0.1, and create-dex, the neko 3.0.1 jar is indeed being included, and I get this interesting error:


trouble processing:
bad class file magic (cafebabe) or version (0033.0000)
...while parsing neko/ui/adapters/InterchangeableListAdapter.class
...while processing neko/ui/adapters/InterchangeableListAdapter.class

trouble processing:
bad class file magic (cafebabe) or version (0033.0000)
...while parsing JSONStringEscapingInputStream.class
...while processing JSONStringEscapingInputStream.class

trouble processing:
bad class file magic (cafebabe) or version (0033.0000)
...while parsing org/writequit/tigris/JSONStringEscapingInputStream.class
...while processing org/writequit/tigris/JSONStringEscapingInputStream.class
3 warnings

And the same crash happens.

With 3.0.0, create-dex says:


trouble processing:
bad class file magic (cafebabe) or version (0033.0000)
...while parsing neko/ui/adapters/InterchangeableListAdapter.class
...while processing neko/ui/adapters/InterchangeableListAdapter.class

trouble processing:
bad class file magic (cafebabe) or version (0033.0000)
...while parsing JSONStringEscapingInputStream.class
...while processing JSONStringEscapingInputStream.class

trouble processing:
bad class file magic (cafebabe) or version (0033.0000)
...while parsing org/writequit/tigris/JSONStringEscapingInputStream.class
...while processing org/writequit/tigris/JSONStringEscapingInputStream.class
3 warnings

So, some version mismatch? I confess to being rather ignorant of the JVM and these Java issues, and I thank you very much for your help and quick response. I'm not sure what to do next here.

kenrestivo commented 10 years ago

I should also note that create-dex also says:

/usr/local/android/sdk-linux_x86/build-tools/17.0.0/dx 

Which is odd because I have 19.0.1 installed as well.

kenrestivo commented 10 years ago

Aha, I forcibly deleted 17.0.0 and 19.0.1 and left only 19.0.3 in the build-tools dir, and create-dex found the most recent version and used it... and the cafebabe errors stopped.

kenrestivo commented 10 years ago

That was it! With dex from 19.0.3, the error goes away and the program runs. ref-adapter is very cool, almost om/reagent/react-like. Thanks!