clojure-android / lein-droid

A Leiningen plugin for building Clojure/Android projects
Eclipse Public License 1.0
645 stars 56 forks source link

Support libraries in classpath but not found by compiler? #145

Closed kenrestivo closed 8 years ago

kenrestivo commented 8 years ago

I asked on the ML but I think this might be a bug.

I've been having trouble getting a project to compile with new lein-droid, using this dependency:

   [com.android.support/support-v4 "13.0.0"]

I'm getting a compile error of:

Exception in thread "main" java.lang.ClassNotFoundException: android.app.Activity.android.support.v4.content.LocalBroadcastManager, compiling:(service.clj:29:1)

I looked in the classpath with lein-tree, and I'm seeing that the library is in fact on the classpath:

[cheshire "5.5.0"]
[cider/cider-nrepl "0.9.1"]
[com.android.support/support-v4 "13.0.0"]
[neko "4.0.0-alpha5" :exclusions [[org.clojure-android/clojure]]]
[org.clojure-android/clojure "1.7.0"]
[org.clojure/tools.nrepl "0.2.10"]
[utilza "0.1.73"]

I can look into that jar too, and I can clearly see that the class is there!

But, for some reason, the compiler or JVM is not finding the class. I'm not clear on why.

I'm trying to build for target-version 14. I have to support old devices.

alexander-yakushev commented 8 years ago

14 should be fine, I guess...

When you execute with DEBUG=1, does it say it extracts AAR dependencies? Can you see actual JAR in target/debug/aar-extracted/com.android.support_support-v4_aar_13.0.0/classes.jar?

Wait, 13.0.0 was still a plain JAR, not an AAR. I'm pretty sure the problem is somewhere around there. It would help if you created a sample project for a newew version of Android and used AAR suppport library there, and confirmed that works.

kenrestivo commented 8 years ago

Hmm, with DEBUG=1, I'm getting this:

DEBUG=1 lein  do droid build
Leiningen's classpath: /home/lken/.lein/self-installs/leiningen-2.5.3-standalone.jar
Applying task do to [droid build]
Applying task droid to [build]
Generating manifest...
Merging secondary manifests: (#object[java.io.File 0x6b9c69a9 /home/cust/happycamp/src/spazdroid/target/debug/aar-extracted/com.android.support_multidex_aar_1.0.0/AndroidManifest.xml])
Generating R.java files...
/usr/local/android/sdk-linux_x86/build-tools/23.0.2/aapt package -f -m -M /home/cust/happycamp/src/spazdroid/target/debug/AndroidManifest.xml -S /home/cust/happycamp/src/spazdroid/target/debug/res -S /home/cust/happycamp/src/spazdroid/res -S /home/cust/happycamp/src/spazdroid/target/debug/aar-extracted/com.android.support_multidex_aar_1.0.0/res -I /usr/local/android/sdk-linux_x86/platforms/android-14/android.jar -J /home/cust/happycamp/src/spazdroid/target/debug/gen --output-text-symbols /home/cust/happycamp/src/spazdroid/target/debug/gen --auto-add-overlay --generate-dependencies

Running javac with [-target 1.7 -source 1.7 -bootclasspath /opt/oracle/jdk1.7.0_09/lib/ @/tmp/.leiningen-cmdline5610599118370070344.tmp]
Compiling 3 source files to /home/cust/happycamp/src/spazdroid/target/debug/classes
Applying task javac to nil
Running javac with [-target 1.7 -source 1.7 -bootclasspath /opt/oracle/jdk1.7.0_09/lib/ @/tmp/.leiningen-cmdline5924925159166106487.tmp]
Compiling 1 source files to /home/cust/happycamp/src/spazdroid/target/debug/classes
Compiling Clojure files...
Project classpath: (/usr/local/android/sdk-linux_x86/tools/support/annotations.jar /usr/local/android/sdk-linux_x86/platforms/android-14/android.jar /home/cust/happycamp/src/spazdroid/test /home/cust/happycamp/src/spazdroid/src/clojure /home/cust/happycamp/src/spazdroid/src /home/cust/happycamp/src/spazdroid/resources /home/cust/happycamp/src/spazdroid/target/debug/classes /home/lken/.m2/repository/org/tcrawley/dynapath/0.2.3/dynapath-0.2.3.jar /home/lken/.m2/repository/cider/cider-nrepl/0.9.1/cider-nrepl-0.9.1.jar /home/lken/.m2/repository/tigris/tigris/0.1.1/tigris-0.1.1.jar /home/lken/.m2/repository/utilza/utilza/0.1.73/utilza-0.1.73.jar /home/lken/.m2/repository/org/timmc/handy/1.7.0/handy-1.7.0.jar /home/lken/.m2/repository/org/clojure/tools.nrepl/0.2.10/tools.nrepl-0.2.10.jar /home/lken/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-smile/2.5.3/jackson-dataformat-smile-2.5.3.jar /home/lken/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.5.3/jackson-core-2.5.3.jar /home/lken/.m2/repository/neko/neko/4.0.0-alpha5/neko-4.0.0-alpha5.jar /home/lken/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-cbor/2.5.3/jackson-dataformat-cbor-2.5.3.jar /home/lken/.m2/repository/org/clojure-android/clojure/1.7.0/clojure-1.7.0.jar /home/lken/.m2/repository/com/android/support/support-v4/13.0.0/support-v4-13.0.0.jar /home/lken/.m2/repository/cheshire/cheshire/5.5.0/cheshire-5.5.0.jar /home/cust/happycamp/src/spazdroid/target/debug/aar-extracted/com.android.support_multidex_aar_1.0.0/classes.jar)
Build type: debug, dynamic compilation: enabled, remote REPL: enabled.
Applying task javac to nil
Running javac with [-target 1.7 -source 1.7 -bootclasspath /opt/oracle/jdk1.7.0_09/lib/ @/tmp/.leiningen-cmdline1247885027859356254.tmp]
Compiling 1 source files to /home/cust/happycamp/src/spazdroid/target/debug/classes
Compiling org.spaz.radio.service
Exception in thread "main" java.lang.ClassNotFoundException: android.app.Activity.android.support.v4.content.LocalBroadcastManager, compiling:(service.clj:29:1)

I'm a bit concerned about that "multidex" support thing being included. But in any case, the jar is definitely included. I'll generate a minimum repro.

rabipelais commented 8 years ago

I am experiencing a possibly related error. Adding as a dependency [com.android.support/support-v4 "21.0.0" :extension "aar"] and importing a corresponding library (e.g. (:import (android.support.v4.view ViewPager)) causes the program to compile correctly, but crash at startup (deployed with lein droid doall). Lein tree also shows the lib is loaded.

If I however misspell the import, for example (:import (android.support.v4.view ViewPagerfoooooo)), the error is correctly caught at compile time.

Logcat of the crash:

java.lang.ExceptionInInitializerError
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:308)
    at clojure.lang.RT.classForName(RT.java:2174)
    at clojure.lang.RT.classForName(RT.java:2183)
    at clojure.lang.RT.loadClassForName(RT.java:2202)
    at clojure.lang.RT.load(RT.java:443)
    at clojure.lang.RT.load(RT.java:419)
    at clojure.core$load$fn__5458.invoke(core.clj:5862)
    at clojure.core$load.doInvoke(core.clj:5861)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.lang.Var.invoke(Var.java:379)
    at my.stuff.fitlogger.MainActivity.<clinit>(Unknown Source)
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:308)
    at java.lang.Class.forName(Class.java:272)
    at neko.App$1.run(App.java:55)
    at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.ClassNotFoundException: android.support.v4.view.ViewPager
    at java.lang.Class.classForName(Native Method)
    at java.lang.Class.forName(Class.java:308)
    at clojure.lang.RT.classForName(RT.java:2174)
    at clojure.lang.RT.classForNameNonLoading(RT.java:2187)
    at my.stuff.fitlogger.main$loading__5350__auto____21.invoke(main.clj:1)
    at my.stuff.fitlogger.main__init.load(Unknown Source)
    at my.stuff.fitlogger.main__init.<clinit>(Unknown Source)
    ... 17 more
Caused by: java.lang.ClassNotFoundException: Didn't find class "android.support.v4.view.ViewPager" on path: DexPathList[[zip file "/data/app/my.stuff.fitlogger.debug-2/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
    ... 24 more
    Suppressed: java.lang.ClassNotFoundException: android.support.v4.view.ViewPager
            at java.lang.Class.classForName(Native Method)
            at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
            at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
            at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
            ... 25 more
    Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available
kenrestivo commented 8 years ago

That's a similar error, but mine is at compile time. I'll try to prepare a minimum repro case. You might want to do so too. If we give Alexander something he can reproduce, then it can get fixed more quickly.

kenrestivo commented 8 years ago

@alexander-yakushev Here's a minimum repro test that exhibits exactly the failure I was describing: https://github.com/kenrestivo/v4supporttest

That service library is critical for my application; there appears to be no substitute for it in Neko.

kenrestivo commented 8 years ago

Problem solved: the import statement was malformed (maybe was OK in previous versions of clojure, but not now).

works:

(ns support.test.service
  "Shamelessly copy/pasted from Nightweb http://github.com/oakes/Nightweb"
  (:import  android.support.v4.content.LocalBroadcastManager))

does not work:

(ns support.test.service
  "Shamelessly copy/pasted from Nightweb http://github.com/oakes/Nightweb"
  (:import [android.support.v4.content.LocalBroadcastManager]))

Closing this; I guess it was pilot error.

alexander-yakushev commented 8 years ago

Oops! I didn't notice that either. Anyway, all's well that ends well. :)

On Wed, Dec 9, 2015, 08:29 ken restivo notifications@github.com wrote:

Closed #145 https://github.com/clojure-android/lein-droid/issues/145.

— Reply to this email directly or view it on GitHub https://github.com/clojure-android/lein-droid/issues/145#event-486526029 .