Android: Instantiating JNDI factory from reflection on Android forcing javax - android

I'm trying to port: Apache Qpid Client, JMS and JNDI -- to Android. I'm able to get a successful compile/build of my QpidDroid project when running the ant debug install targets after passing Dalvik the --core-library parameter to allow javax packages for JMS/JNDI. I'm hoping to do this before considering repackaging/refactoring javax classes into a different package namespace using jarjar.
I think this is legally legit because I'm using the old/first seperate JNDI jar currently provided by Oracle's website. I'm using the JMS jar that comes with Apache Geronimo in Qpid,.. but I think it's also available from Oracle as a seperate download. My dev environment uses Android platform 2.1 and jdk 1.6.
The problem is, it seems it currently cannot instantiate my custom jndi connection factory: PropertiesFileInitialContextFactory. This is a .java source file in my QpidDroid project(not a .class in a libs jar) (I extracted the class out of the qpidClient jar).
Would someone have any idea as to why it cannot be instantiated here? I was wondering if proguard might be breaking reflection,... but I'm building it with the debug ant task,.. so I'm thinking proguard shouldn't be running at all. The exception occurs when I run the installed app on the emulator. I have the Apache Qpid service running on the same machine with the default port that it uses.
01-18 18:05:16.966: W/System.err(296): [Root exception is java.lang.ClassNotFoundException: org.apache.qpid.jndi.PropertiesFileInitialContextFactory]javax.naming.NoInitialContextException: Cannot instantiate class: org.apache.qpid.jndi.PropertiesFileInitialContextFactory
01-18 18:05:17.006: W/System.err(296): at javax.naming.spi.NamingManager.getDefaultInitialContextFactory(NamingManager.java:720)
01-18 18:05:17.006: W/System.err(296): at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:768)
01-18 18:05:17.016: W/System.err(296): at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:169)
01-18 18:05:17.016: W/System.err(296): at javax.naming.InitialContext.<init>(InitialContext.java:146)
01-18 18:05:17.016: W/System.err(296): at org.rif.QpidDroid.Hello.runTest(Hello.java:56)
Thanks for any tips!

I think I found the problem -- Android has bugs in it with Reflection prior to version 2.3
http://code.google.com/p/android/issues/detail?id=6636
I ported my QpidDroid project to Android 2.3 and it looks like JNDI is successfully creating the InitialContext now with the QPID connection params

Related

Does the chromeview project need to be built from source before attempting to use cordova-android-chromeview?

I am trying to build the example project on the cordova-android-chromeview project and I'm having a few issues. The most recent being that when deployed to the device, I receive the following runtime error:
04-25 10:29:29.593: D/CordovaActivity(1951): CordovaActivity.onCreate()
04-25 10:30:46.433: I/LibraryLoader(1951): loading: webviewchromium
04-25 10:30:46.443: D/dalvikvm(1951): Trying to load lib /data/app-lib/com.myapp.special-1/libwebviewchromium.so 0xb1d53778
04-25 10:30:46.443: D/dalvikvm(1951): Added shared lib /data/app-lib/com.myapp.special-1/libwebviewchromium.so 0xb1d53778
04-25 10:30:46.463: I/LibraryLoader(1951): loaded: webviewchromium
04-25 10:31:08.943: W/dalvikvm(1951): No implementation found for native Lorg/chromium/content/app/LibraryLoader;.nativeLibraryLoaded:([Ljava/lang/String;)I
04-25 10:37:40.423: W/jdwp(1951): Debugger is telling the VM to exit with code=1
If I read this correctly, it seems that some libraries that the app is expecting are not exposed to it. I'm not exactly sure how to track down which native files are expected. Nor am I sure how to generate ( or reference? ) the missing libraries.
I am using:
https://github.com/pwnall/chromeview
https://github.com/thedracle/cordova-android-chromeview
Building for Android 4.4
I am trying to run the Example project that came with cordova-android-chromeview using this syntax: ./bin/create ~/Desktop/myapp com.myapp.special MyApp
Is it possible that chromeview simply needs to be built from the chromium source? I hope not, but that's my current thinking.
Thanks in advance, any help would be appreciated.
First change Target to anything between 4.0 and 4.3. ChromeView does not work on Android 4.4 because there WebView is already driven by ChromeView.
If that does not help, make sure you copied the webviewchromium.pak to your project's asset folder.
Changing build target to Android 4.3 did the trick for me.

NUnitLite in Xamarin (Android). Unable to load Mono.Data.Sqllite.dll

I'm currently experimenting with Xamarin for the first time, as well as NUnitLite for the first time. I've set up a small Android project and a test project. In the Android project I make use of SqlLite, and in my test project I want to write some integration tests for my database insert/update/select methods.
However, when I run tests which includes a call to my class "GroupRepository" (which includes a type from the Mono.Data.Sqllite.dll in its constructor) I get the following exception. Note that I've also added the mentioned dll to my test-project.
TestInsertWithLegalValues (IntegrationTests.Repository.RepositoryTests.TestInsertWithLegalValues)
System.IO.FileLoadException : Could not load file or assembly 'Mono.Data.Sqlite, version=2.0.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756' or one of its dependencies. Strong name validation failed. (Exception from HRESULT: 0x8013141A)
----> System.Security.SecurityException : Strong name validation failed. (Exception from HRESULT: 0x8013141A)
at Repository.GroupRepository..ctor()
at IntegrationTests.Repository.RepositoryTests.SetUp()
--SecurityException
The Android project targets API 8 using Xamarin 2.0. The test project is a Windows Console Application .NET 4.5.
Why is this failing the way it is?
Thanks for any input!

Android Terminal-IDE: Solution to remote login java (Dalvik) compilation error?

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.

OSGi (Felix) on Android: NoClassDefFoundError: sun/reflect/ConstructorAccessorImpl

I try to run a bundle that obviously uses sun.reflect package.
First some more backgroundinformation: I'm using Apache Felix on Android.
And i also added sun.reflect as a system extra package.
String extrapackets = "sun.reflect; version=\"1.0.0\"";
config.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, extrapackets);
config.put("felix.bootdelegation.implicit", "false");
"sun.reflect" is also shown in the exportinglist of the system bundle (using headers cmd).
And it is imported by my bundle. It also got correct versionnumbers at the export and importing stuff.
Errormsg:
java.lang.NoClassDefFoundError: sun/reflect/ConstructorAccessorImpl
at sun.misc.Unsafe.defineClass(Native Method)
at sun.reflect.ClassDefiner.defineClass(ClassDefiner.java:45)
at sun.reflect.MethodAccessorGenerator$1.run(MethodAccessorGenerator.java:381)
at java.security.AccessController.doPrivileged(Native Method)
at sun.reflect.MethodAccessorGenerator.generate(MethodAccessorGenerator.java:377)
at sun.reflect.MethodAccessorGenerator.generateConstructor(MethodAccessorGenerator.java:76)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:30)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
...
In case anyone else runs across this issue, there may be a quicker fix.
I hit this bug when using reflection in OSGi running on a Sun/Oracle JVM. It turns out this is a known issue. The suggested fix of setting -Dsun.reflect.noInflation=true at the JVM level will cause the class not to be referenced, at the cost of ignoring an optimization.
I tried the fix, and it worked for me.
As far as I know, the sun.* packages are internal packages used in the Oracle JVM you install on your computer. Android, on the other hand, does not use Sun's (now Oracle's) implementation of the JVM. Android offers an API similar to Java SE, but has its own implementation of the VM (called Dalvik VM).
So, you won't find the sun.* packages on Android. You need to get the source code of the bundle you using, and compile it against the Android libraries (using an Android project in eclipse, or using Ant). Then, repackage it into a jar, and then you can deploy it without it referencing the sun.* packages.
Kartik
Did you also import the package in your bundle? Just adding it to your systembundles.extra is not enough.

Problems using the EWS Java API on Android

I am trying to use the EWS Java API v1.1.5 (http://archive.msdn.microsoft.com/ewsjavaapi) in an Android application, and have run into a number of issues.
I downloaded the source, and followed the instructions provided to compile the EWS Java API in Eclipse. In those instructions you are told to download and
add the following pre-requiste jar file dependencies:
commons-codec-1.4.jar
commons-httpclient-3.1.jar
commons-logging-1.1.1.jar
jcifs-1.3.15.jar
I did this, and followed the build instructions with produced the following jar files:
EWSAPI-1.1.0.jar
EWSAPIWithJars-1.1.0
Next, I built a brand new Android application, added the appropriate permissions to the manifest, and then added the following source to the primary activity's OnCreate:
ExchangeService service = new ExchangeService();
ExchangeCredentials credentials = new WebCredentials("emailaddress", "password");
service.setCredentials(credentials);
try
{
service.autodiscoverUrl("emailaddress", this);
}
catch (Exception e)
{
e.printStackTrace();
}
I first tried running this application with the EWSAPI-1.1.0.jar file as a dependency. When I did that, I obtained the following fatal error:
Uncaught handler: thread main exiting due to uncaught exception
java.lang.NoClassDefFoundError:
org.apache.commons.httpclient.MultiThreadedHttpConnectionManager at
microsoft.exchange.webservices.data.ExchangeServiceBase.(Unknown
Source) at
microsoft.exchange.webservices.data.ExchangeServiceBase.(Unknown
Source) at
microsoft.exchange.webservices.data.ExchangeService.(Unknown
Source) at
com.meshin.exchange.ExchangeDiscoveryActivity.onCreate(ExchangeDiscoveryActivity.java:40)
From what I've researched, it seems like this error is being generated because Android comes with the Apache HttpClient 4.0, which doesn't appear
to have the MultiThreadedHttpConnectionManager class anymore.
If I instead remove the EWSAPI-1.1.0.jar, and instead use the EWSAPIWithJARS-1.1.0.jar file as a dependency, I get the following error:
VFY: unable to resolve static method 908: Ljavax/xml/stream/XMLOutputFactory;
newInstance()Ljavax/xml/stream/XMLOutputFactory;
VFY: dead code 0x0008-006a in L
microsoft/exchange/webservices/data/EwsUtilities;.formatLogMessage
(Ljava/lang/String;Ljava/lang/String;) Ljava/lang/String;
VFY: unable to find class referenced in signature (Ljavax/xml/stream/XMLStreamWriter;)
And then eventually...
FATAL EXCEPTION: main java.lang.VerifyError:
microsoft.exchange.webservices.data.AutodiscoverService at
microsoft.exchange.webservices.data.ExchangeService.getAutodiscoverUrl(Unknown
Source) at
microsoft.exchange.webservices.data.ExchangeService.autodiscoverUrl(Unknown
Source) at
com.meshin.exchange.ExchangeDiscoveryActivity.onCreate(ExchangeDiscoveryActivity.java:41)
I am assuming because now I am including the HttpClient 3.1 jar and it is conflicting with the HttpClient 4.0 jar included with the Android libraries.
My question is if there is a way for me to use the EWS Java API in an Android project without having to re-write the parts of it which reference
HttpClient 3.1-specific things which are no longer in 4.0.
You can use microsoft's EWS api for android by doing the following steps,
download the source code available in the URL,
http://archive.msdn.microsoft.com/ewsjavaapi
EWSJavaAPI_1.1.5.zip
Make the changes to above api to work for JDK 1.4 in eclipse like remove override annotations e.t.c
Download source code of javax.* package available in below URL,
http://www.java2s.com/Code/JarDownload/jsr173/jsr173_1.0_src.jar.zip
Download source code of stax api available in below URL,
http://dist.codehaus.org/stax/distributions/stax-src-1.2.0.zip
Keep all the sources under the single java project in eclipse
Open the project explorer and select the package which are starts with "javax" and rename to your company name eg: com. Note: Eclipse will ask for all the naming contexts will change then click OK.
Export all the java sources to one single jar file.
Then You good to go to use the jar in Android application with out any problems.
I used the same way explained above and it worked in android application 100% perfectly.
This isn't a useful answer but I've also been struggling to look at the EWS API over the last couple of weeks, with no success.
The main issue I've found is it references a lot of the javax APIs which aren't on Android. There's a hack you can find that explains how to "re-class" these but I've not got it working yet; in addition, the DnsClient references some namespaces that jarsearches only return for rt.jar - the main runtime. And including this in an Android app would just be crazy!
Before finding the API I was trying to use KSOAP to communicate with EWS but again ran into problems - you need to be able to do NTLM and SSL and I couldn't find any way of combining all these with KSOAP in any simple way.
The EWS API looks the way to go (why re-invent the wheel) but getting it working on Android looks very tricky (if not impossible)
Please check this library for the solution

Categories

Resources