Recently, we tried to user monkeyrunner
on an Ubuntu 18.04 LTS
. We installed Android Studio
through snap
and we setup the Android SDK in ~/Andoid
. monkeyrunner
was installed in ~/Android/Sdk/tools/bin
. To our immeasurable disappointment we found out that when we tried to execute monkeyrunner
, it would give the following error:
$ ./monkeyrunner
-Djava.ext.dirs=/home/tux/Android/Sdk/tools/lib:/home/tux/Android/Sdk/tools/lib/x86_64 is not supported. Use -classpath instead.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
At first, we had no idea what that meant, so we used file
command on monkeyrunner
and we found out that monkeyrunner
is a bash
script.
$ file monkeyrunner
monkeyrunner: POSIX shell script, ASCII text executable
After reading the code, we read the following at the last lines:
#need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
#might need more memory, e.g. -Xmx128M
exec java -Xmx128M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir:$swtpath" -Djava.library.path="$libdir" -Dcom.android.monkeyrunner.bindir="$progdir" -jar "$jarpath" "$@"
First thing we did was to find the java
version that was used, since the command that was giving the problem was that. We found out that we had version 11
.
$ java -version
openjdk version "11.0.6" 2020-01-14
OpenJDK Runtime Environment (build 11.0.6+10-post-Ubuntu-1ubuntu118.04.1)
OpenJDK 64-Bit Server VM (build 11.0.6+10-post-Ubuntu-1ubuntu118.04.1, mixed mode, sharing)
After reading a bit, we found out that after Java
version 8
the command line directive -Djava.ext.dirs
it was deprecated and the recommendation to use -classpath
was added. In the past, java.ext.dirs
was used to instruct the JRE
from where to load additional class
and jar
files. Since we had Java
version 11
we had to try the recommendation to remove the -Djava.ext.dirs
directive and use -classpath
instead. So, we edited the file monkeyrunner
and changed the last line as follows:
exec java -Xmx128M $os_opts $java_debug -classpath "$frameworkdir/*:$swtpath" -Djava.library.path="$libdir" -Dcom.android.monkeyrunner.bindir="$progdir" -jar "$jarpath" "$@"
We tried executing the newly updated monkeyrunner
again, only to hit another wall!
$ ./monkeyrunner
Exception in thread "main" java.lang.NoClassDefFoundError: com/android/chimpchat/ChimpChat
at com.android.monkeyrunner.MonkeyRunnerStarter.(MonkeyRunnerStarter.java:60)
at com.android.monkeyrunner.MonkeyRunnerStarter.main(MonkeyRunnerStarter.java:188)
Caused by: java.lang.ClassNotFoundException: com.android.chimpchat.ChimpChat
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
… 2 more
It turns out that when you use the -jar
directive, JRE
will ignore the -classpath
directive and so it will again not be able to load any external class
or jar
files…
Solution
Instead of reinventing the wheel (We tried, we failed, it was painful. Still worth the shot!) we decided to install Java
version 8
on Ubuntu 18.04 LTS
side by side with Java
version 11
and just used that.
First, we checked the list of installed jvm
on our machine using the following command:
update-java-alternatives --list;
Where we got the following:
$ update-java-alternatives --list
java-1.11.0-openjdk-amd64 1111 /usr/lib/jvm/java-1.11.0-openjdk-amd64
java-1.8.0-openjdk-amd64 1081 /usr/lib/jvm/java-1.8.0-openjdk-amd64
It turned out we already had Java
version 8
but if we didn’t we would install it as follows:
sudo apt install openjdk-8-jdk;
and then it would again appear in the list mentioned above.
Then, we switched to the Java
version 8
using the following command and selecting the appropriate option:
sudo update-alternatives --config java;
$ sudo update-alternatives --config java
[sudo] password for tux:
There are 2 choices for the alternative java (providing /usr/bin/java).
Selection Path Priority Status
0 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 auto mode
1 /usr/lib/jvm/java-11-openjdk-amd64/bin/java 1111 manual mode
2 /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java 1081 manual mode
Press to keep the current choice[*], or type selection number: 2
update-alternatives: using /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java to provide /usr/bin/java (java) in manual mode
After switching Java
to Version 8
monkeyrunner
was working as expected!!