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

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.

Related

ServiceLoader.load is not finding the META-INF/services

So I want to build an extensible android application where developers can add 'CustomDevice' classes and the main program will run them automatically without editing existing code.
I've read about Service Provider interface and thought that would be a nice way to go about it.
So I tested it and created an interface called 'ICustomDevice' which custom device classes are expected to implement.
I've created a class called 'DummyDevice' that implements ICustomDevice.
Both DummyDevice and ICustomDevice are in the same package "CustomDevicePackage".
So in my main program I run the following.
ServiceLoader<ICustomDevice> loader = ServiceLoader.load(ICustomDevice.class);
Iterator<ICustomDevice> devices = loader.iterator();
System.out.println("Does it have devices? " + devices.hasNext());
It always returns false, which means it's not finding the 'DummyDevice'
In my eclipse project I created a folder at 'src' called META-INF and under it, a subfolder called 'services'.
'Services' has a file named 'CustomDevicePackage.ICustomDevice' with a line of content 'CustomDevicePackage.DummyDevice'.
Am I doing it right? Every example I see about SPI is about loading JARS.
I'm not loading a JAR, I'm trying to run a class in the same Project. Does this method only works for loading JARs? I want my program to support loading local subclasses and external JARs alike.
I am adding this as an answer but leaving the prior "answer" to provide extended code detail for this workaround. I am working on reporting the prior answer results as a bug to Google.
Because the Android implementation of java.util.ServiceLoader is broken (always populating internal java.security.AccessControlContext field with AccessController.getContext() even if System.getSecurityManager() == null), the workaround is to create your own ServiceLoader class by copying the code found at OpenJDK for Java 8 into your class, add specific imports required from java.util without using import java.util.*;, and call that ServiceLoader in your code (you will have to fully reference the ServiceLoader you created to over ambiguity).
This isn't elegant but it is a functional workaround that works! Also, you will need to use a ClassLoader in your ServiceLoader.load() call. That ClassLoader will either have to be YourClass.class.getClassLoader() or a child ClassLoader of the class' ClassLoader.
Though it's an old post, This may be still be of some help to others:
When I was running or debugging a project that contained a ServiceLoader Class, I had to put the META-INF/services folder into the src/ folder in Eclipse.
If I tried to export the project as Runnable jar and tried to use the class with the service loader, it never worked.
When I checked the jar, unzipping it, I found the folder under src/META-INF/services though.
Only when I also added the META-INF folder directly in the root directory of the jar, it started to work.
I haven't found a fix though inside Eclipse, that makes sure it gets exported right...maybe an ANT script can solve this issue, but so far no attempts made...
This is an answer:
At some point, Android removed the AccessControlContext field in ServiceLoader and ServiceLoader now works. As my comments indicate, this was reproduceable using the "out-of-the-box" OREO (API 26) Intel Atom x86 emulator with Android Studio (also fresh download). 24 hours later, ServiceLoader no longer contained the acc field (as shown in the Android Studio debugger with the same emulator). The Android SDKs dating back to API 24 do not show the acc field.
Per the Android developer currently maintaining the ServiceLoader code:
He is not aware of ServiceLoader ever having the acc field in Android (it did as we were able to reproduce) and thought the debugger/emulator might have been using JDK code (but I showed the OpenJDK code works correctly). Somewhere along the way, the errant code was updated and I am no longer able to reproduce.
Be sure your OS is up-to-date and you should no longer see this phenomena.

UnsatisfiedLinkError Arcgis 10.2.3 Android ArcGISRuntime.setClientId

I'm having a problem with Arcgis SDK for Android which I've never had before.
It seems an issue with its native interface when I call this method:
ArcGISRuntime.setClientId
I have this method inside onCreate() (Application class), so it crashes at the beginning
This is the stack trace:
java.lang.UnsatisfiedLinkError: nativeIsClientIdValid
at com.esri.core.runtime.LicenseImpl.nativeIsClientIdValid(Native Method)
at com.esri.core.runtime.LicenseImpl.b(Unknown Source)
at com.esri.android.runtime.ArcGISRuntime$License.b(Unknown Source)
at com.esri.android.runtime.ArcGISRuntime$License.a(Unknown Source)
at com.esri.android.runtime.ArcGISRuntime.setClientId(Unknown Source)
at com.pkg.manager.AppManager.onCreate(AppManager.java:262)
And this is what I found on Arcgis documentation about this method:
public static LicenseResult setClientId (String clientId)
License an application for basic functionality. This will remove the watermark present in developer mode and must be called in a deployed application. Whenever standard licensed functionality is accessed, a RuntimeException will be thrown.
This method must be called before setting a license with either setLicense(LicenseInfo) or setLicense(String). Note that if any standard licensed functionality is accessed before calling this method, an exception will be thrown when this method is called and the application will remain in developer mode.
Parameters
clientId. client ID to set
Returns
LicenseResult.Invalid or LicenseResult.Valid
(https://developers.arcgis.com/android/api-reference/reference/com/esri/android/runtime/ArcGISRuntime.html)
Any ideas, thank you!
UnsatisfiedLinkError normally means the application can't load a native library it needs, even though the Java wrapper for that library is present. If the Java wrapper were also missing, your code wouldn't compile.
Did you switch from an earlier version of ArcGIS to ArcGIS 10.2.3 in this project? If so, it is possible that the project still has the native libraries from the old version of ArcGIS, which didn't have a setClientId method, even though the project has the Java libraries from the new version of ArcGIS, which do have setClientId.
Assuming you're in Eclipse, right-click the project and choose ArcGIS Tools > Fix Project Properties. That should replace the old native libraries with the 10.2.3 native libraries.
http://maroofi.github.io/ceal/ for removing watermark from screen

How to use EasyMock in android

I use easymock-3.2.jar in my android test project.
I find it in its Home:
2013-07-11: EasyMock 3.2 is available. Add #Mock annotations and Android support.
However , I got exception when I use it.
java.lang.NoClassDefFoundError: org.easymock.EasyMock
I googled a lot , and add
dexmaker-1.0.jar
objenesis-1.2.jar
cglib-nodep-2.2.2.jar or cglib-2.2.jar
But the exception still be there.Who can help me?
Thanks a lot.
Put the library
easymock-3.2.jar
dexmaker-1.0.jar
dexmaker-mockito-1.0.jar
in tests/libs. And it will work.
Be careful , it's in tests/libs , not in tests/lib.
It will throw
java.lang.NoClassDefFoundError: org.easymock.EasyMock
if you position them in tests/lib.
The first step is to get EasyMock. You can get the latest version from Easymock’s download page. Choose the latest version and you will get a zip file. You only need easymock-3.2.jar (3.2 will change depending on the version you choose). You will also need dexmaker for Easymock to work on Android. You can get the jar from Dexmaker’s website. Once you have both jar files put them in /tests/libs. Now you have EasyMock available in your tests.
for more detail follow below link
http://ncona.com/2013/11/writing-unit-test-for-android-with-easymock/

Problems with build.xml when using the Android ADK to communicate with an Arduino Mega ADK

So a few days ago I got my hands on an Arduino Mega ADK board, and the last couple of nights I have been setting up my development environment, getting to grips with the tools etc. The tools and libraries all work fine, for example I can get a program written in the Processing IDE to compile and run on an Asus Eee Pad Transformer TF101 running Android 4.03. But when I get it to try to compile and run one of the pre-written examples, it gives me a compiler error:
Android SDK Tools Revision 20
Installed at C:\NVPACK\android-sdk-windows
Project Type: Application
Project Target: Android 2.3.3
API level: 10
Library dependencies:
No Libraries
API<=15: Adding annotations.jar to the classpath.
Merging AndroidManifest files into one.
Manifest merger disabled. Using project manifest only.
No AIDL files to compile.
No RenderScript files to compile.
Generating resource IDs...
Generating BuildConfig class.
BUILD FAILED
C:\NVPACK\android-sdk-windows\tools\ant\build.xml:680: The following error occurred while executing this line:
C:\NVPACK\android-sdk-windows\tools\ant\build.xml:693: Compile failed; see the compiler error output for details.
Total time: 7 seconds
And that's all the console seems to output as well, which is rather frustrating! As far as I'm aware all of my SDK versions, tools and plugins are all up to date. I've tried this using a Linux partition I have on my hard drive and it produces the same error message, although it mentions a problem with the package com.Android.future.UsbAccessory. Given what I've seen, it seems that the problem is with the tools, either my directory structure doesn't match up to what the correct setup is, or something else is wrong :S. If anyone has had similar problems, some help would be smashing! (For the record, my setup was done using the instructions on the Arduino website, although I already had the Android SDK tools installed).
Will Scott-Jackson
It sounds like your haven't added in the support library to your project and/or you haven't downloaded it into your Android SDK.
The ADK1 demokit app targets API Level 10 (Android 2.3.3); That means you need to use the support libraries in your project and that's why the compiler is complaining about level 10 library dependencies not being available. The support libraries are a separate download in the SDK Manager, so you might not have them in your development environment.
In Android API Level 12 and higher, the USB Accessory protocol was added to the framework API, so there are two different ways to use the accessory protocol. So, you don't have to use the support libraries if you are targeting Honeycomb and higher versions, but you'll have to update the demokit app code to make this work.
Hope this helps.
So I've double checked my setup and started working on a project I had in mind, it seems to import the libraries appropriately. So far so good, but when I input:
ArduinoAdkUsb arduino;
void setup() {
arduino = new ArduinoAdkUsb(this);
//Other UI initialisation etc.
}
I get this error:
##name## ##version## by ##author##
FATAL EXCEPTION: Animation Thread
java.lang.NoClassDefFoundError: com.android.future.usb.UsbManager
at cc.arduino.ADKCommunication.<init>(Unknown Source)
at cc.arduino.ArduinoAdkUsb.<init>(Unknown Source)
at
processing.android.test.sketch_120730a.
sketch_120730a.setup(sketch_120730a.java:48)
at processing.core.PApplet.handleDraw(Unknown Source)
at processing.core.PGraphicsAndroid2D.requestDraw(Unknown Source)
at processing.core.PApplet.run(Unknown Source)
at java.lang.Thread.run(Thread.java:856)
After the app has been built and installed onto the Android tablet I am using. Any thoughts how I can over come this? From what I can tell, this has no problem finding com.android.future.usb.manager to compile and install the program, but once it tries to run it can find it.
Based on this tutorial from http://stream.tellart.com/controlling-arduino-with-android/
In the examples RGB_Arduino the name, version and author variables are set at the top of the sketch.
Try adding in this section of code at the top of your arduino sketch just underneath the library imports
// accessory descriptor. It's how Arduino identifies itself to Android
char applicationName[] = "Mega_ADK"; // the app on your phone
char accessoryName[] = "Mega_ADK"; // your Arduino board
char companyName[] = "Freeware";
// make up anything you want for these
char versionNumber[] = "1.0";
char serialNumber[] = "1";
char url[] = "http://labs.arduino.cc/adk/"; // the URL of your app online
//initialize the accessory:
AndroidAccessory usb(companyName, applicationName,
accessoryName,versionNumber,url,serialNumber);

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