I'm trying to run a JAR file I built using the following command line (from adb shell):
dalvikvm -cp /sdcard/MyJar.jar MyJar.main.Main
My Main class has only a single method main:
public static void main(String[] args)
{
// Connect to local db
SQLiteDatabase db = SQLiteDatabase.openDatabase(DB_PATH, null, SQLiteDatabase.OPEN_READWRITE);
}
When I run the command line it looks like the main function runs but then I get the following exception:
java.lang.UnsatisfiedLinkError: native_get_int
at android.os.SystemProperties.native_get_int(Native Method)
at android.os.SystemProperties.getInt(SystemProperties.java:74)
at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1846)
at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:820)
at MyJar.main.Main.main(Main.java:146)
at dalvik.system.NativeStart.main(Native Method)
My guess is that I need to load some kind of library to resolve this link error but I have no clue which library it is (this seems like a basic thing that probably should have been loaded by dalvikvm...).
Any ideas ?
Try running app_process instead of dalvikvm.
Vogar makes this kind of thing very easy. Check out the latest vogar from their SVN page, build it with ant, and then run this on your Linux desktop
~/Projects/vogar/bin/vogar --mode app_process ~/myapp/src/com/me/Main.java
Vogar will build your .java, create a .dex file, use adb to copy that to your device, and then execute VM on the device for you. We use it to develop Dalvik.
Related
I've been trying to employ Kawa Scheme for developing Android project. I've found two repositories on GitHub: one called 'android-kawa', and another called 'KawaDroid'. They're both a bit dated (last updates were around 2012). In the case of 'android-kawa' I was able to reach the author, but he said he did't remeber enough to help me.
In the 'android-kawa' repo there's a bunch of scripts for setting up and working with the project. One of the scripts downloads the Kawa 1.13 tarball, applies some patches and then attempts to build it.
However, the build isn't supported in Termux, bevaise the config.guess script doesn't recognize the system. This issue can be easily resolved by downloading the latest versions of config.guess and config.sub.
Another problem is the format of the JVM bytecode. When I use the latest Java compiler, the generated bytecode contains (I believe) instructions for JVM8+, which aren't supported by the dx command. This isn't a problem if I run Java inside of Termux, because it installs the regular JVM, but if I want to include the Kawa jar in my APK (which is something that I want), then it becomes an obstacle.
This, again, can be resolved by forcing the Java version to 7 in javac. (But then, the compiler complsins that Java 1.7 is deprecated. I guess this is why the buildAPKs project uses ecj instead of javac)
Also, when I ./configure Kawa, I can pass it the path to the android.jar file (./configure --with-android=...). I have two android.jar files on my system:
~ $ locate android.jar
/data/data/com.termux/files/usr/share/aapt/android.jar
/data/data/com.termux/files/usr/share/java/android.jar
I don't know where they came from or how they differ between one another, but I've been prefering the second one.
So, when I have the kawa.jar available - and when I try to compile it with the command
~/android-kawa $ java -cp $(dirname $(locate android.jar |tail -n 1)) -jar kawa/kawa-1.13.jar -C KawaHello/src/kawa/android/hello.scm
I get the following error:
internal error while compiling KawaHello/src/kawa/android/hello.scm
java.lang.NoClassDefFoundError: android/view/View
at gnu.kawa.android.defs.<clinit>(defs.scm)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized(Unsafe.java:1155)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:42)
at java.base/jdk.internal.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:185)
at java.base/java.lang.reflect.Field.acquireFieldAccessor(Field.java:1132)
at java.base/java.lang.reflect.Field.getFieldAccessor(Field.java:1113)
at java.base/java.lang.reflect.Field.get(Field.java:425)
at gnu.expr.ModuleInfo.setupModuleExp(ModuleInfo.java:195)
at kawa.standard.require.importDefinitions(require.java:308)
at kawa.standard.require.scanForDefinitions(require.java:219)
at kawa.lang.Syntax.scanForm(Syntax.java:65)
at kawa.lang.Translator.scanForm(Translator.java:1120)
at gnu.kawa.lispexpr.LispLanguage.parse(LispLanguage.java:64)
at gnu.expr.Compilation.process(Compilation.java:1908)
at gnu.expr.ModuleInfo.loadByStages(ModuleInfo.java:305)
at gnu.expr.ModuleInfo.loadByStages(ModuleInfo.java:290)
at gnu.expr.ModuleInfo.loadByStages(ModuleInfo.java:290)
at gnu.expr.ModuleInfo.loadByStages(ModuleInfo.java:290)
at gnu.expr.ModuleInfo.loadByStages(ModuleInfo.java:290)
at gnu.expr.ModuleInfo.loadByStages(ModuleInfo.java:290)
at kawa.repl.compileFiles(repl.java:823)
at kawa.repl.processArgs(repl.java:444)
at kawa.repl.main(repl.java:869)
Caused by: java.lang.ClassNotFoundException: android.view.View
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ... 24 more
I have obviously tried it without the -cp argument (with the same effect). The android/view/View.class entry is present in the list returned by jar -tf android.jar.
How can I further investigate in the root cause of the problem, and most importantly, how can I solve it?
It turned out that I have invoked Java incorrectly, and that it didn't see the android.jar file. It helped to invoke the compiler in the following way:
~/android-kawa $ java -cp $(locate android.jar |tail -n 1):kawa/kawa-1.13.jar kawa.repl -C KawaHello/src/kawa/android/hello.scm
(the difference is that I only have one -cp argument with jar files separated by :, and that I explicitly give the kawa.repl class name)
My project is a simple game with native C++ code and Java, which uses cmake to compile C/C++ code. I'm using address sanitizer to check my the code. I follow the instruction here
My OS is windows 10 64bit.
However, when I press debug on Android Studio, I got the message as
2020-03-19 13:50:56.946 5152-5152/? E/logwrapper: executing /data/app/com.indie.haiphan.Breakout-ZFFz_f8ETleajrgP6rg9gw==/lib/arm64/wrap.sh failed: No such file or directory
2020-03-19 13:50:56.946 5151-5151/? I/wrap.sh: executing /data/app/com.indie.haiphan.Breakout-ZFFz_f8ETleajrgP6rg9gw==/lib/arm64/wrap.sh failed: No such file or directory
2020-03-19 13:50:56.956 5151-5151/? I/wrap.sh: wrap.sh terminated by exit(255)
2020-03-19 13:50:56.957 873-873/? W/Zygote: Error reading pid from wrapped process, child may have died
I checked on my APK (with Analyze APK of Android Studio) the wrap.sh exist.
So my question is I can't debug with wrap.sh inside the APK?
Thanks
You probably have BOM or an extra carriage return at the end of the first line of your wrap.sh. Which is possible in windows.
To fix it you can use dos2unix tool.
See this: https://unix.stackexchange.com/a/27067/197738
In order to use NDK in my application, I included an external tool at Preferences -> Tools -> External Tools.
Here's what I did.
As I right-clicked a class and chose the external javah command to create a c class, it didn't work and left a following message.
Exception in thread "main" java.lang.IllegalArgumentException: Not a valid class name: /src/main/jni
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:129)
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:107)
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:64)
at com.sun.tools.javah.JavahTask.run(JavahTask.java:503)
at com.sun.tools.javah.JavahTask.run(JavahTask.java:329)
at com.sun.tools.javah.Main.main(Main.java:46)
Process finished with exit code 1
I properly created the jni folder under the main directory, and I'm still not clear why I keep getting this message.
Here's my development environment.
OS: OS X El Capitan
Android Studio: 2.2.2
I solved this problem by modifying the Parameters and Working Directory as follows.
Parameters: -classpath $Classpath$ -v -jni $FileClass$
Working Directory: $ProjectFileDir$/app/src/main/jni
I was only looking for an ssh terminal that didn't require rooting my phone when I stumbled across Terminal-IDE and I am THRILLED that I did! (More from its creator here.) It's an Android development environment designed to work on the portable computers known as "Android phones" and it includes what you might call an "accessable Linux operating system for non-rooted phones."
OK, now that you know what the platform is, the issue is that when I start the provided sshd and log into the phone remotely using ssh, I can't seem to get any of the java (Dalvik) machinery to work, while the same action typed locally works fine. A simple example is the Hello World Tutorial, wherein you run the java compiler thus:
# javac hello.java
The result from the local interface is a bright-shiny new hello.class. When done from the ssh login (running bash), it results in:
# javac hello.java
Dalvik VM unable to locate class 'com/spartacusrex/spartacuside/external/javac'
java.lang.NoClassDefFoundError: com/spartacusrex/spartacuside/external/javac
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: com.spartacusrex.spartacuside.external.javac
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
... 1 more
Of course, one looks to environment variables...
The following are in the local environment but are either not in the remote environment or are different:
LOOP_MOUNTPOINT=/mnt/obb
ASEC_MOUNTPOINT=/mnt/asec
ANDROID_PROPERTY_WORKSPACE=9,131072
ANDROID_SOCKET_zygote=10
ANDROID_BOOTLOGO=1
BOOTCLASSPATH=/data/data/com.spartacusrex.spartacuside/files/system/classes/android.jar:/system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/framework2.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar:/system/framework/HTCDev.jar:/system/framework/HTCExtension.jar:/system/framework/com.htc.framework.jar:/system/framework/filterfw.jar:/system/framework/com.htc.android.bluetooth.jar:/system/framework/wimax.jar:/system/framework/com.orange.authentication.simcard.jar
PATH=/data/data/com.spartacusrex.spartacuside/files/bin:/data/data/com.spartacusrex.spartacuside/files/local/bin:/data/data/com.spartacusrex.spartacuside/files/android-gcc-4.4.0/bin:/data/data/com.spartacusrex.spartacuside/files/system/bin:/data/data/com.spartacusrex.spartacuside/files/system/bin/bbdir:/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin
PWD=/data/data/com.spartacusrex.spartacuside/files/system/src/helloworld
EXTERNAL_STORAGE=/mnt/sdcard
The following are in the remote environment but are either not in the local environment or are different:
ANDROID_PROPERTY_WORKSPACE=10,32768
ANDROID_BOOTLOGO=1
USER=username
BOOTCLASSPATH=/data/data/com.spartacusrex.spartacuside/files/system/classes/android.jar:/system/framework/core.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar
PATH=/data/data/com.spartacusrex.spartacuside/files/bin:/data/data/com.spartacusrex.spartacuside/files/local/bin:/data/data/com.spartacusrex.spartacuside/files/android-gcc-4.4.0/bin:/data/data/com.spartacusrex.spartacuside/files/system/bin:/data/data/com.spartacusrex.spartacuside/files/system/bin/bbdir:/sbin:/system/sbin:/system/bin:/system/xbin
PS1=\[\033[01;32m\]$USER\[\e[1;31m\]\[\e[1;33m\]#\[\e[1;35m\]$HOSTNAME\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$
MKSH=/system/bin/sh
APK=/data/app/com.spartacusrex.spartacuside-1.apk
LOGNAME=username
EXTERNAL_STORAGE=/sdcard
Of course, my attention has flowed to "BOOTCLASSPATH". I'd never heard of BOOTCLASSPATH before, but it appears to be the replacement for just plain ole "CLASSPATH" we java coders are familiar with...
Proposed solutions are to be found on the code.google.com website under "issues", but none of them work.
The solution is to simply alter BOOTCLASSPATH to contain the same contents in the remote login as with the local one.
Of course, "out of the box," this should not be a problem one encounters. But, Terminal-IDE is a young environment and this is just one of the growing pains.
I have made some minor changes to /dalvik/vm/interp/Jit.cpp
(wrote some LOGD messages) and built dalvikvm using
$make dalvikvm
and the build was successful and got the executable in /out/
target/product/generic/system/bin/dalvikvm.
Now i started an emulator and pushed dalvikvm into /data and
executed a sample java program (with some 30 loops) using
$/data/dalvikvm -Xbootclasspath:/system/
framework/core.jar -classpath /data/CmdLine.jar TestAppActivity
(created CmdLine.jar from sample program by following
instructions given in http://davanum.wordpress.com/2007/12/04/command-line-java-on-dalvikvm/
)
now when i check the logcat there is no messages which i have
written using LOGD is displayed. Do we need to add any option to
dalvikvm command line to enable JIT? what could be the problem here?
Thanks
Jit is enabled by default if you are using android version above 2.2 i suppose. Your problem is the profiling of JIT has to be enabled in dvm. This can be don by looking into dalvikvm --help .... I think dalvikvm -Xjitprofile -Xjitverbose should do and before that export your environment variable to log the message too.
Try exporting the logs before running the dalvikvm something like this
export ANDROID_LOG_TAGS="ActivityManager:I MyApp:D *:S" the variables D -Debug S: lowest level V - verbose which is the level of log you need the application to be logged.
dalvikvm is just the starter binary. The important stuff lives in libdvm.so so you have to build and replace this rather than dalvikvm.