0

I am embedding Apache Felix into an Android application. In that application, I am trying to use a service provided by a bundle. The bundle is successfully installed and started, but at the line that uses the service which is:

 System.out.println( ((AndroidService) services [0]).startActivity());

I get the following error:

 java.lang.ClassCastException: androidapi_bundle.AndroidServiceImpl cannot be cast to com.example.android_services.AndroidService

I have the following in my bundle:

1- Activator class

package androidapi_bundle;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import com.example.android_services.AndroidService;
import android.util.Log;


public class Activator implements BundleActivator {

    private static BundleContext context;

    static BundleContext getContext() {
        return context;
    }


    public void start(BundleContext bundleContext) throws Exception {
        Activator.context = bundleContext;

        System.out.println("This is a java message inside the start method of AndroidAPI_Bundle");
        Log.d("Zitona Log","This is android message inside the start method of AndroidAPI_Bundle");


        context.registerService(
                AndroidService.class.getName(), new AndroidServiceImpl(),null);
    }


    public void stop(BundleContext bundleContext) throws Exception {
        Activator.context = null;

        Log.d("Zitona Log","AndroidAPI_Bundle stopped!");
    }

}

2- com.example.android_services which has AndroidService.java interface:

package com.example.android_services;

public interface AndroidService {

    public String startActivity();


}

3- its implementation class AndroidServiceImpl.java :

package androidapi_bundle;

import com.example.android_services.*;

public class AndroidServiceImpl implements AndroidService {

    @Override
    public String startActivity()
    {
        return "Activity started";

    }


}

Now, in my android app I also have AndroidService.java interface, and the following is the code that uses the service:

@SuppressWarnings({ "rawtypes", "unchecked" })

ServiceTracker m_tracker = new ServiceTracker(
        m_activator.getContext(),AndroidService.class.getName(), null);

    m_tracker.open();

    System.out.println("8");

    Object[] services = m_tracker.getServices();

    System.out.println("9");
    System.out.println( ((AndroidService) services [0]).startActivity());


   System.out.println("10");

After "9" is displayed I get the error. Where did I go wrong?

Below is my bundle MANIFEST:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: AndroidAPI_Bundle
Bundle-SymbolicName: AndroidAPI_Bundle
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: androidapi_bundle.Activator
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Import-Package: org.osgi.framework;version="1.3.0", android.util, com.example.android_services
Export-Package: com.example.android_services

Update:

I realized that I have this line of code:

   m_configMap.put(FelixConstants.FRAMEWORK_SYSTEMCAPABILITIES_EXTRA, "com.example.android_services");

so I changed it to:

    m_configMap.put(FelixConstants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "com.example.android_services");

Now I am getting this error:

 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.apache_felix_android/com.example.apache_felix_android.MainActivity}: java.lang.NullPointerException
Traveling Salesman
  • 2,209
  • 11
  • 46
  • 83

1 Answers1

-1

The only way you can get this is if both the activator bundle and the app bundle have an internal copy of the service class and neither exports it. So you will need to show your manifests and bundle contents.

Update What on earth are you mucking with advanced options like system packages (and then using Felix classes instead of OSGi's constant class) when you seem to have very basic problems. Why not start with a clean simple bndtools, make your app work in there using an IDE, and then when it works port it to Android? This all looks awfully masochistic way to learn OSGi?

Peter Kriens
  • 15,196
  • 1
  • 37
  • 55
  • I added MANIFEST.MF of my bundle in the question. I do export and import com.example.android_services. – Traveling Salesman Aug 19 '13 at 14:15
  • In my code I have the following line of code: m_configMap.put(FelixConstants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "com.example.android_services"); Now with what I am telling you, I get another error actually which is: 08-19 14:09:57.873: E/AndroidRuntime(17170): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.apache_felix_android/com.example.apache_felix_android.MainActivity}: java.lang.NullPointerException at the same line "9" – Traveling Salesman Aug 19 '13 at 14:18
  • Please see my update in the question if the comment is not clear. – Traveling Salesman Aug 19 '13 at 14:21
  • The null pointer exception is a completely different error from the ClassCastException... you shouldn't just piggy back it on the same question because it has no relation to the title or 90% of the question text. – Neil Bartlett Aug 19 '13 at 14:27
  • Having said that... it's clear that the NPE happens because the service hasn't been published yet. When using services you can't just assume they are always available. You should use ServiceTracker to wait for the service, or get a callback when it becomes available. Or better yet, use Declarative Services. – Neil Bartlett Aug 19 '13 at 14:28
  • Thanks. I am new to ServiceTracker, so can you just show me a simple code for solving the problem? – Traveling Salesman Aug 19 '13 at 14:31
  • Not really, I am getting a NullPointerException bceause my bundle did not start. That's because I have two consecutive lines of codes which are: m_configMap.put("org.osgi.framework.system.packages.extra","android.util"); m_configMap.put(FelixConstants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "com.example.android_services"); These should be only one line which is: m_configMap.put("org.osgi.framework.system.packages.extra","android.util, com.example.android_services"); Now everything worked just fine! Thanks – Traveling Salesman Aug 19 '13 at 14:44