Closed GoogleCodeExporter closed 9 years ago
As also reported by Atsushi Eno, the class generation and loading scheme used
by BridJ (ASM + ClassLoader.defineClass) does not work on Android.
Fortunately, others have implemented class-to-dex conversion code, as for
instance in Clojure (Eclipse Public License 1.0) :
https://github.com/exterm/clojure/blob/android_runtime_bytecode/src/jvm/clojure/
lang/Android.java
Also see this Android issue for other options :
http://code.google.com/p/android/issues/detail?id=6322
What needs to be seen is whether available code is licensed or licensable as
BSD (or can be legally included in BridJ with a composite license), or if we
need to reimplement that wheel :-)
Original comment by olivier.chafik@gmail.com
on 10 Jun 2011 at 8:29
Another example of Dex wrapper :
https://github.com/headius/dexclient/blob/master/src/DexClient.java
Original comment by olivier.chafik@gmail.com
on 10 Jun 2011 at 2:36
Hello,
This should be mostly fixed by revision #2085 (class-to-dex conversion using
shipped dex tool) and revision #2086 (loading of binary from path).
What I don't know, though, is whether it's actually needed to embed dx.jar into
BridJ or if it's already available at run-time on any Android device (it adds
up quite a bit of space to the JAR, most of which could be stripped away, but
still...)
Cheers
--
Olivier
Original comment by olivier.chafik@gmail.com
on 12 Jun 2011 at 5:34
There's still a couple of issues to fix. I still don't get the latest code
working, will continue investigation...
- org/bridj/android_arm32_arm/** should be also excluded from
SNAPSHOT-android.jar, as it is not allowed for eclipse android app project to
have shared libraries in referenced .jar (it is probably apkbuilder limitation).
- rev. #2086 first tries to load (lib)bridj_android(.so) and then
(lib)bridj(.so), but the first attempt results in
java.lang.UnsatisfiedLinkError ("Library bridj_android not found"). Since it is
an Error, the following catch block doesn't work. I temporarilly removed the
first attempt
- I'm still getting some SEGV https://gist.github.com/1022341 I'm wondering
what line #3 "unable to find field
Lorg/bridj/MethodCallInfo;.javaCallback:Lorg/bridj/Callback;" indicates.
Original comment by atsushi...@gmail.com
on 13 Jun 2011 at 5:15
I looked for dx.jar on my HTC Desire, but could not find it. Since it is rather
a dev. tool that does not premise to be placed on a device, I think it is not
part of the set of "shipped in device" files.
Original comment by atsushi...@gmail.com
on 13 Jun 2011 at 5:20
Hello Atsushi,
Thanks for your feedback :-)
- Good call for the Error, I've updated the code...
- For the library bundling issue, I'm testing things out... I'm not getting
warnings yet (with sdk r10, all in command-line), but maybe renaming the .so
into .so_ might do the trick otherwise... ? (See my current test code :
http://code.google.com/p/nativelibs4java/source/browse/trunk/libraries/Runtime/B
ridJ/src/main/cpp/android-test/?r=2103). My goal right now is first to test an
all-integrated program on the emulator, then to prepare a separate BridJ shared
Android library which programs can depend upon.
- The MethodCallInfo vs. javaCallback issue would be that you haven't updated
the binary / the code with which you build the binary : there was a very recent
change that had me recompile all binaries (including Android's
http://code.google.com/p/nativelibs4java/updates/list).
Cheers
--
zOlive
Original comment by olivier.chafik@gmail.com
on 13 Jun 2011 at 9:40
Hello Atsushi,
It now WORKS ! (at least, on my emulator)
I've added a small test project (derived from helloworld-jni sample) that
builds it own library with the NDK + SDK :
http://code.google.com/p/nativelibs4java/source/browse/trunk/libraries/Runtime/B
ridJ/src/main/cpp/android-test/
To build and deploy on a running emulator, go to that directory and type
'./build.sh package emulator start'
Native apps *must* be in lib/armeabi/*
BridJ can be included in any Ant-based Android project by putting its
bridj-x.x-android.jar file in a directory (say, "lib") and adding the following
property to the build.property file : jar.libs.dir=lib
This way, it will be in the classpath of the project (to build the Java files)
and will be converted properly by dex (and the libbridj.so resource will be
properly preserved).
TODO package BridJ as an .apk ?
TODO write a detailed example on the wiki
Cheers
--
zOlive
Original comment by olivier.chafik@gmail.com
on 13 Jun 2011 at 1:13
I have updated the wiki with instructions on how to use BridJ on Android :
http://code.google.com/p/bridj/wiki/Download
Original comment by olivier.chafik@gmail.com
on 13 Jun 2011 at 1:57
[deleted comment]
FYI, callbacks are still not working... Added code that generates a .zip file
with classes.dex as you did in your project, but it persists in saying it does
not find the class...
Original comment by olivier.chafik@gmail.com
on 13 Jun 2011 at 4:21
After couple of attempts to build, I got hello-jni sample working too (no
callbacks either). hello-jni.c needs a cosmetic fix:
Index: jni/hello-jni.c
===================================================================
--- jni/hello-jni.c (リビジョン 2111)
+++ jni/hello-jni.c (作業コピー)
@@ -33,6 +33,6 @@
int addTwoInts(int a, int b) {
return a + b;
}
-int passTwoIntsToCallback(int a, int b, int (cb*)(int, int)) {
+int passTwoIntsToCallback(int a, int b, int (*cb)(int, int)) {
return cb(a, b);
}
While I got hello-jni working, I'm now getting method resolution failure... any
idea why it happens?
E/CPPRuntime( 6021): Failed to get address of method public static native int
nativeandroid.unistd.jnaerated.unistdLibrary.access(org.bridj.Pointer,int)
W/dalvikvm( 6021): No implementation found for native
Lnativeandroid/unistd/jnaerated/unistdLibrary;.access (Lorg/bridj/Pointer;I)I
...
E/AndroidRuntime( 6021): FATAL EXCEPTION: main
E/AndroidRuntime( 6021): java.lang.UnsatisfiedLinkError: access
E/AndroidRuntime( 6021): at
nativeandroid.unistd.jnaerated.unistdLibrary.access(Native Method)
Original comment by atsushi...@gmail.com
on 14 Jun 2011 at 6:09
OK, I got a fix for my issue. I'm not sure why it is needed, but BridJ.java
first checks if the library is "c" (libc) and if it is, then it tries to load
"null" library (I mean, null path, 0 handle and 0 symbols). Thus bridj could
not find my unistd binding.
The attached patch fixes this issue.
Original comment by atsushi...@gmail.com
on 15 Jun 2011 at 9:06
Attachments:
Fixed the "class not found" issue too. It was due to incorrect parent
ClassLoader passed to DexClassLoader. The attached patch should fix it.
Original comment by atsushi...@gmail.com
on 15 Jun 2011 at 10:13
Attachments:
I'm still not getting hello-jni callback version working. It is because the
regex Pattern in BrisJ.getNativeLibrary() does not match the actual URL
returned by getResource(). My HTC Desire returns the resource path like this:
jar:file:/mnt/asec/com.example.hellojni-1/pkg.apk!/lib/armeabi/libhello-jni.so
Bridj.java seems to have a premised URL probably assumed by emulator.
Original comment by atsushi...@gmail.com
on 15 Jun 2011 at 10:23
Olivier, finally, I got callback working! :-)
Though my patch this time involves packageName hack. I added one additional
mandatory call for Android users to set packageName in BridJ class:
setAndroidAppPackage(getApplication().getPackageName()
I think it is not very imposing requirement - would you have better idea?
Original comment by atsushi...@gmail.com
on 15 Jun 2011 at 3:48
Attachments:
Hello Atsushi,
Thanks a lot for all your input !
I've applied your suggestions (up to comment 14) in revision #2114 and revision
#2115.
It should work with your URL as well as with that of the emulator, but *might*
or might not break with other actual devices.
Your latest patch is interesting, but I'd like to take some time to convince
myself it's compulsory ;-)
Cheers
--
zOlive
Original comment by olivier.chafik@gmail.com
on 15 Jun 2011 at 4:28
Building upon your proposal, maybe we'd benefit even more from setting the
Application directly, actually...
See http://developer.android.com/reference/android/app/Application.html
Application.getApplicationInfo().nativeLibraryDir would give us the information
we need in a very clean way...
Likewise, Application.getCacheDir() could replace the ugly cacheDir resolution
in AndroidClassDefiner's constructor...
We'd just have to enforce that AndroidSupport.setApplication(app) was called
before any library is registered (throwing an IllegalThreadStateException if it
hasn't been called yet).
What do you think about it ?
Original comment by olivier.chafik@gmail.com
on 15 Jun 2011 at 4:35
Ahh, that's an interesting discovery, but sadly ApplicationInfonativeLibraryDir
is available only after API Level 9 (gingerbread).
Original comment by atsushi...@gmail.com
on 15 Jun 2011 at 6:14
Hello Atsushi,
I still cannot get callbacks to work on the emulator, so I did some *blind*
refactoring (revision 2116)... Hope I didn't break everything on your side...
I added code that uses ApplicationInfo. nativeLibraryDir through reflection
when it is available, and uses the existing hacks otherwise.
Cheers
--
zOlive
Original comment by olivier.chafik@gmail.com
on 16 Jun 2011 at 8:25
That's a couple of nice changes, I love it :) Here is a patch to get correct
"/data/data/{packagename}" directory that I think works better. It uses
ApplicationInfo.dataDir (available since API Level 1).
It seems that Environment.getDataDirectory() only returns the File for "/data",
not "/data/data".
Original comment by atsushi...@gmail.com
on 16 Jun 2011 at 12:07
Attachments:
Hi Atsushi,
Excellent, thanks ! (see revision #2117).
Cheers
--
zOlive
Original comment by olivier.chafik@gmail.com
on 16 Jun 2011 at 4:06
[deleted comment]
Does this issue still need to be open? I find no issue in android support
itself.
Original comment by atsushi...@gmail.com
on 27 Jun 2011 at 9:23
Hi Atsushi,
Perfect then, let's close it !
Cheers
--
zOlive
Original comment by olivier.chafik@gmail.com
on 27 Jun 2011 at 11:07
Original issue reported on code.google.com by
olivier.chafik@gmail.com
on 9 Jun 2011 at 9:33