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
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:
-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
$ 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
$ 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
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
jar files. Since we had
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!
Exception in thread "main" java.lang.NoClassDefFoundError: com/android/chimpchat/ChimpChat
Caused by: java.lang.ClassNotFoundException: com.android.chimpchat.ChimpChat
… 2 more
It turns out that when you use the
JRE will ignore the
-classpath directive and so it will again not be able to load any external
Instead of reinventing the wheel (We tried, we failed, it was painful. Still worth the shot!) we decided to install
version 8 on
Ubuntu 18.04 LTS side by side with
version 11 and just used that.
First, we checked the list of installed
jvm on our machine using the following command:
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
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
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
monkeyrunner was working as expected!!