Hello,

On Thu Mar  8 02:43 2012, Rostislav Svoboda wrote:
> Hi. I'm trying to run:
>     java -cp clojure-${VERSION}.jar clojure.main
> 
> on an Android phone from bash (using the 'terminal-ide' app) but I
> can't make it past the error bellow. I did the jar-to-dex conversion
> using:
>     dx --verbose --dex --output=clojure-${VERSION}.dex.jar
> clojure-${VERSION}.jar
> 
> for clojure-1.3.0.jar, clojure-1.3.0-slim.jar and even for the clojure
> clone for Android Neko Toolkit from Daniel Solano Gómez:
>       https://github.com/sattvik/clojure.git
> 
> Does anyone know what I missed? Thx in advance
> 
> Bost

I don't use the terminal-ide app, so I have no idea of how its
implementation of the java command works.  So I am not sure I have any
specific ideas that can help you.

In general, Android differs from the standard JVM in how classes are
packed into a JAR.

You can have a source-only JAR that works with Java.  For example, given
the namespace 'my.app.core', it could be packaged as follows:

app-slim.jar:
  /my/app/core.clj

If you were to AOT-compile the class, the you would get something like
this:

app.jar:
  /my/app/core__init.class
  /my/app/core$foo.class
  /my/app/core$bar.class
  /my/app/core$baz.class

With Android, all of the classes are processed and written to a single
classes.dex, which is placed at the root of the package:

app.apk:
  /classes.dex


Now, some comments about your stack traces:

>   Now searching: clojure-1.3.0.dex.jar
>     found
> java.lang.ExceptionInInitializerError
>         at java.lang.reflect.Method.invokeNative(Native Method)
>         at java.lang.reflect.Method.invoke(Method.java:507)
>         at com.spartacusrex.spartacuside.external.java.main(java.java:124)
>         at dalvik.system.NativeStart.main(Native Method)
> Caused by: java.lang.ExceptionInInitializerError
>         at clojure.main.<clinit>(main.java:20)
>         ... 4 more
> Caused by: java.lang.RuntimeException: java.io.FileNotFoundException:
> Could not locate clojure/core__init.class or clojure/core.clj on
> classpath:
>         at clojure.lang.Util.runtimeException(Util.java:165)
>         at clojure.lang.RT.<clinit>(RT.java:319)
>         ... 5 more
> Caused by: java.io.FileNotFoundException: Could not locate
> clojure/core__init.class or clojure/core.clj on classpath:
>         at clojure.lang.RT.load(RT.java:430)
>         at clojure.lang.RT.load(RT.java:398)
>         at clojure.lang.RT.doInit(RT.java:434)
>         at clojure.lang.RT.<clinit>(RT.java:316)
>         ... 5 more

Just out of curiousity, which version Android are you testing this on?
Now that I think of it, this looks vaguely familiar to a problem I ran
into with Eclair.  At one level, you can see that some of the Clojure
code is running, but it fails when it tries to bootstrap 'clojure.core'.
This may be due the classpath not being quite right.  In an Android
application, there is usually a thread-context classloader where Clojure
finds its own classes.  Perhaps the java implementation here isn't
setting things up quite right?

> In case of the clojure clone for Daniel Solano Gómez:
> 
>   Now searching: clojure-1.4.0-master-SNAPSHOT.dex.jar
>     found
> java.lang.ExceptionInInitializerError
>         at java.lang.reflect.Method.invokeNative(Native Method)
>         at java.lang.reflect.Method.invoke(Method.java:507)
>         at com.spartacusrex.spartacuside.external.java.main(java.java:124)
>         at dalvik.system.NativeStart.main(Native Method)
> Caused by: java.lang.ExceptionInInitializerError
>         at clojure.main.<clinit>(main.java:20)
>         ... 4 more
> Caused by: java.lang.ExceptionInInitializerError
>         at java.lang.Class.classForName(Native Method)
>         at java.lang.Class.forName(Class.java:234)
>         at java.lang.Class.forName(Class.java:181)
>         at clojure.lang.RT.<clinit>(RT.java:235)
>         ... 5 more
> Caused by: java.lang.ExceptionInInitializerError
>         at android.os.Build$VERSION.<clinit>(Build.java:75)
>         ... 9 more
> Caused by: java.lang.UnsatisfiedLinkError: native_get
>         at android.os.SystemProperties.native_get(Native Method)
>         at android.os.SystemProperties.get(SystemProperties.java:59)
>         at android.os.Build.getString(Build.java:216)
>         at android.os.Build.<clinit>(Build.java:27)
>         ... 10 more


This version does not get quite as far as the first.  This is seems to
fail during a reflective call to load android.os.Build.VERSION.
Apparently, there is some native library function that isn't being
found.  I am guessing this might be related to how the java command is
implemented in TermIDE.

Off-hand, after taking a brief glance at TermIDE's source, my guess that
the easiest way to fix it would be to modify the
com.spartacusrex.spartacuside.external.java class from TermIDE to set
current thread's context loader to the dexclassloader created there.  I
think that will work.

Sincerely,

Daniel

> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

Attachment: signature.asc
Description: Digital signature

Reply via email to