1

I have an OSGI Bundle which is an eclipse plugin project. In this bundle, I am trying to use the android API to print a message on LogCat. The way I was led in these two questions 1 , 2 to achieve that is to get a real implementation of Android API and to prepare it as separate bundle which exports android.util so that my bundle import android.util and use it. Okay, I did all these steps. I used this android source code, and Below is my bundle's Activator class:

package bundle_androidapi;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;


import android.util.Log;

public class Activator implements BundleActivator {

    private static BundleContext context;

    static BundleContext getContext() {
        return context;
    }

    /*
     * (non-Javadoc)
     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
     */
    public void start(BundleContext bundleContext) throws Exception {
        Activator.context = bundleContext;


        System.out.println("Hello World. I am the OSGI_Android_Bundle!");

        Log.d("Zaid Log", "Hello World. I am the OSGI_Android_Bundle!!");
    }

    /*
     * (non-Javadoc)
     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
     */
    public void stop(BundleContext bundleContext) throws Exception {
        Activator.context = null;


        System.out.println("Goodbye World. I am the OSGI_Android_Bundle!");

        Log.d("Zaid Log", "Goodbye World. I am the OSGI_Android_Bundle!!");
    }

}

At the line that uses Log.d(), I get the following errors:

!ENTRY Bundle_AndroidAPI 4 0 2013-08-14 15:10:53.638
!MESSAGE FrameworkEvent ERROR
!STACK 0
org.osgi.framework.BundleException: Exception in bundle_androidapi.Activator.start() of bundle Bundle_AndroidAPI.
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:734)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683)
    at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381)
    at org.eclipse.osgi.framework.internal.core.AbstractBundle.resume(AbstractBundle.java:390)
    at org.eclipse.osgi.framework.internal.core.Framework.resumeBundle(Framework.java:1177)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:559)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:544)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.incFWSL(StartLevelManager.java:457)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.doSetStartLevel(StartLevelManager.java:243)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:438)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:1)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)
Caused by: java.lang.UnsatisfiedLinkError: android.util.Log.println_native(IILjava/lang/String;Ljava/lang/String;)I
    at android.util.Log.println_native(Native Method)
    at android.util.Log.d(Log.java:138)
    at bundle_androidapi.Activator.start(Activator.java:27)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:711)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:702)
    ... 12 more
Root exception:
java.lang.UnsatisfiedLinkError: android.util.Log.println_native(IILjava/lang/String;Ljava/lang/String;)I
    at android.util.Log.println_native(Native Method)
    at android.util.Log.d(Log.java:138)
    at bundle_androidapi.Activator.start(Activator.java:27)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:711)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:702)
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683)
    at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381)
    at org.eclipse.osgi.framework.internal.core.AbstractBundle.resume(AbstractBundle.java:390)
    at org.eclipse.osgi.framework.internal.core.Framework.resumeBundle(Framework.java:1177)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:559)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:544)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.incFWSL(StartLevelManager.java:457)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.doSetStartLevel(StartLevelManager.java:243)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:438)
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:1)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)

Can someone tell me how can I get rid of the above errors.

Below is my MANIFEST.MF:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Bundle_AndroidAPI
Bundle-SymbolicName: Bundle_AndroidAPI
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: bundle_androidapi.Activator
Import-Package: org.osgi.framework;version="1.3.0", android.util
Bundle-RequiredExecutionEnvironment: JavaSE-1.6

Note: I am trying since 1 week to get my bundle to use andorid API, but I keep failing. My target is not just a Log message to be printed, but to have my bundle using Android API successfully, so am I following the right way? Is there a reason, why I keep failing and getting these errors? Thanks.

Community
  • 1
  • 1
Traveling Salesman
  • 2,209
  • 11
  • 46
  • 83

1 Answers1

0

Please read the JavaDocs for UnsatisfiedLinkError: "Thrown if the Java Virtual Machine cannot find an appropriate native-language definition of a method declared native."

In other words, the native implementation of the println_native method is missing from your bundle. Also I note that you do not have a Bundle-NativeCode header that would enable OSGi to find the native code, if it were present.

UPDATE

In the comment thread it was agreed that we should not even be trying to deploy a bundle that contains this API, because the API is already supplied by the Android platform. So the above advice is moot.

There was some confusion about build dependencies versus runtime dependencies. The android.jar can be added to the project build dependencies in order to compile the bundle, but it does nothing at runtime exception throw "Stub!" exceptions. However that's okay because it's not needed in the runtime.

Neil Bartlett
  • 23,743
  • 4
  • 44
  • 77
  • Thanks, but this is complicated. If I have to take care of so many stuff in my bundle in order to make each single line works, then it will be a hard job to start bundles on Android. What do you think? – Traveling Salesman Aug 14 '13 at 12:40
  • You only need this in the bundle that exports the Log API. – Neil Bartlett Aug 14 '13 at 12:51
  • My big question is, why these errors do not show when you run a normal android app. Why it's so complicated on Bundles? Isn't that there is a way in which you can transform android application to a bundle, which in this case you don't have to take care of these "native" methods or the missing source code of Android API? – Traveling Salesman Aug 14 '13 at 12:52
  • I think because the util packages are exported by the platform, like I said in my other question. So you don't need to do what you're doing. – Neil Bartlett Aug 14 '13 at 12:53
  • Sorry @Neil, which question you are talking about when you said "my other question"? I didn't see a question for you about this. – Traveling Salesman Aug 14 '13 at 12:56
  • I mean, in my answer you one of *your* other questions. – Neil Bartlett Aug 14 '13 at 12:57
  • I think what you meant by I don't need to do what I am doing, is when it is an android App, but for the bundle, I have to solve these issues. This is what i understand from you now. Anyway, I am going to search again and again, to apply what you are saying in this answer. – Traveling Salesman Aug 14 '13 at 13:13
  • One more thing: Where exactly should I add the missing implementation of the println_native? You said in my bundle, but which bundle of the two? And where exactly? Same for Bundle-NativeCode. I'd appreciate it if you update your answer with more details. – Traveling Salesman Aug 14 '13 at 13:18
  • What I mean is, you don't need to have a bundle wrapping the `android.util` package at all, **because it's already provided by the platform**. You don't need to search for non-stub implementations, you don't need to add native code anywhere. **Just use the implementation already provided by the platform**. (I'm 99% sure this is true because you said when it's a plain Android app you don't have these issues accessing the API.) – Neil Bartlett Aug 14 '13 at 13:46
  • I highly appreciate what you just said, and I understand it. But in order to show the Log message in the bundle, you have to import android.util (even in a normal android app). In this case, where should I keep the android API which has android.util that I am importing? In my bundle? I did so, and I got “java.lang.NoClassDefFoundError” error, which I showed in question 1. – Traveling Salesman Aug 14 '13 at 14:09
  • This is what I'm trying to say... *you* don't have to keep it anywhere because it's already part of the platform. – Neil Bartlett Aug 14 '13 at 15:46
  • Which will give me a syntax error, and the bundle won't run, because I am using a method from Android API, and I am not keeping Android API anywhere. – Traveling Salesman Aug 14 '13 at 15:50
  • see this: http://dz.prosyst.com/pdoc/mbs_mobile_2.0.3/android/developer/android_tooling.html#android_jar – Traveling Salesman Aug 14 '13 at 15:51
  • At the risk of repeating myself... *you* don't need to keep the Android API anywhere. It's already there on the the device!! Android "keeps" it for you. Sorry that I can't think of ways to say this any more clearly. Maybe somebody else can try. – Neil Bartlett Aug 14 '13 at 17:14
  • I won't discuss this anymore, but I am sure that I am close to reach my target, so I promise a full detailed answer to this question and to all my previous questions, when I get everything to work on Android device. – Traveling Salesman Aug 14 '13 at 18:08
  • 1
    I'll try one more angle. If this makes sense, please let me know and I'll update my answer. You need to distinguish between **build** dependencies and **run** dependencies. Eclipse (out of the box) doesn't know about the Android APIs so you have to add android.jar to your build dependencies in order to compile you bundle. But that jar is ONLY for building, and does nothing at all at runtime except throw "Stub!" exceptions. However you **don't need it** at runtime because the APIs are already there as part of the platform. – Neil Bartlett Aug 14 '13 at 19:02
  • Yeah, now that makes perfect sense to me, and that's what I am working on it now. We finally agreed :) – Traveling Salesman Aug 14 '13 at 21:19
  • Great so we need to move this discussion to chat because it's got way too long, and I'll update my answer. – Neil Bartlett Aug 14 '13 at 22:50
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/35482/discussion-between-neil-bartlett-and-traveling-salesman) – Neil Bartlett Aug 14 '13 at 22:54