clojure on android over CLI

271 views
Skip to first unread message

Rostislav Svoboda

unread,
Mar 7, 2012, 8:43:06 PM3/7/12
to clo...@googlegroups.com
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


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


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

Jim - FooBar();

unread,
Mar 8, 2012, 5:14:53 AM3/8/12
to clo...@googlegroups.com
There is a clojure repl for android...it will make your life
easier...the only problem is you cannot include external libs in your
project...

Jim

On 08/03/12 01:43, 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:

> In case of the clojure clone for Daniel Solano G�mez:

Daniel Solano Gomez

unread,
Mar 8, 2012, 6:47:33 PM3/8/12
to clo...@googlegroups.com
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?


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 clo...@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+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

signature.asc

Rostislav Svoboda

unread,
Mar 8, 2012, 8:44:25 PM3/8/12
to clo...@googlegroups.com
On 8 March 2012 11:14, Jim - FooBar(); <jimpi...@gmail.com> wrote:
> There is a clojure repl for android...

Jim, my goal is to be able to write android apps in clojure. But to
develop an app in clojure on a PC is pain: The android emulator eats a
lot of memory and takes minutes to start, 'ant debug install' takes
about 1 minute to complete. The JVM (1.7.0_03-b04) running this
command crashes quite regularly. In short: a continuous development is
simply impossible.

So I bought myself a shiny new phone to eliminate some of these
obstacles and I'm trying to set up a decent development environment on
the android. In the 1st step I want to connect from the PC to the
android (over telnet or ssh) and launch the clojure REPL from a bash
running on the android. But as I wrote in the prev post the 'java -jar
clojure-${ver}.dex.jar clojure.main' doesn't work.

regards

Bost

Rostislav Svoboda

unread,
Mar 8, 2012, 7:44:17 PM3/8/12
to clo...@googlegroups.com
Hello,

On 9 March 2012 00:47, Daniel Solano Gomez <clo...@sattvik.com> wrote:
> In general, Android differs from the standard JVM in how classes are
> packed into a JAR.

[..]

ah! thanx for explanation

> Just out of curiousity, which version Android are you testing this on?

termi...@192.168.178.22:~$ uname -a
Linux localhost 2.6.32.9-perf #1 PREEMPT Mon Sep 19 08:03:47 2011
armv7l GNU/Linux

> Perhaps the java implementation here isn't setting things up quite right?

you're right - there seems to be something wrong with the java implementation:

termi...@192.168.178.22:~$ java -version
com.spartacusrex.spartacuside.external.InvokeException: No JAR Files specified
at com.spartacusrex.spartacuside.external.java.main(java.java:65)
at dalvik.system.NativeStart.main(Native Method)
Usage : java -v -jar [List of Jar files] CLASSNAME


Thank you for the answer Daniel! BTW I've also played with your Neko.
I'm gonna post a message about it this weekend.

Bost

Daniel Solano Gomez

unread,
Mar 9, 2012, 10:50:26 AM3/9/12
to clo...@googlegroups.com
On Fri Mar 9 02:44 2012, Rostislav Svoboda wrote:
> On 8 March 2012 11:14, Jim - FooBar(); <jimpi...@gmail.com> wrote:
> > There is a clojure repl for android...
>
> Jim, my goal is to be able to write android apps in clojure. But to
> develop an app in clojure on a PC is pain: The android emulator eats a
> lot of memory and takes minutes to start, 'ant debug install' takes
> about 1 minute to complete. The JVM (1.7.0_03-b04) running this
> command crashes quite regularly. In short: a continuous development is
> simply impossible.

If that is what you're trying to accomplish, perhaps a slightly
different approach would be helpful. While developing the Clojure REPL,
I included a copy of the VimClojure server as part of the app. When the
app starts, I would have it start the server, which would listen on a
TCP port on the phone/emulator. I then used adb to forward a port from
the computer to the VimClojure port on the device.

As a result, I would be able to send expressions from my editor, Vim, to
the device, which would compile and reload them. This does require my
fork of Clojure, as the standard Clojure cannot do dynamic compilation
on Android.

It was still slow in comparison to doing compilation on the computer, a
few seconds or so. However, that's a huge improvement over the standard
compile/redeploy cycle using the standard tools.

I don't know what kind of editor/development environment you prefer, but
a similar approach where you embed a REPL in your application may be the
best for you. The main drawback to this approach is that you will
probably want to remove some of these development dependencies for a
released version of the app.

I hope this helps.

Sincerely,

Daniel


>
> So I bought myself a shiny new phone to eliminate some of these
> obstacles and I'm trying to set up a decent development environment on
> the android. In the 1st step I want to connect from the PC to the
> android (over telnet or ssh) and launch the clojure REPL from a bash
> running on the android. But as I wrote in the prev post the 'java -jar
> clojure-${ver}.dex.jar clojure.main' doesn't work.
>
> regards
>
> Bost
>

signature.asc
Reply all
Reply to author
Forward
0 new messages