Пакет с использованием Android API показывает java.lang.UnsatisfiedLinkError: android.util.Log.println_native

У меня есть пакет OSGI, который представляет собой проект плагина eclipse. В этом комплекте я пытаюсь использовать Android API для печати сообщения на LogCat. То, как меня привели к этим двум вопросам 1 , 2 для этого нужно получить реальную реализацию Android API и подготовить ее как отдельный пакет, который экспортирует android.util, чтобы мой пакет импортировал android.util и использовал его. Хорошо, я сделал все эти шаги. Я использовал это исходный код Android, а ниже приведен класс активатора моего пакета:

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!!");
    }

}

В строке, которая использует Log.d(), я получаю следующие ошибки:

!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)

Может кто-нибудь сказать мне, как я могу избавиться от вышеуказанных ошибок.

Ниже мой 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

Примечание. Уже неделю я пытаюсь заставить свой пакет использовать API andorid, но у меня ничего не получается. Моя цель — не просто распечатать сообщение журнала, а успешно использовать Android API моего пакета, так что я иду правильным путем? Есть ли причина, по которой я продолжаю терпеть неудачу и получать эти ошибки? Спасибо.


person Traveling Salesman    schedule 14.08.2013    source источник


Ответы (1)


Пожалуйста, прочитайте JavaDocs для UnsatisfiedLinkError: «Вызывается, если виртуальная машина Java не может найти подходящее определение на родном языке для метода, объявленного native».

Другими словами, в вашем комплекте отсутствует нативная реализация метода println_native. Также отмечу, что у вас нет заголовка Bundle-NativeCode, который позволил бы OSGi найти нативный код, если бы он присутствовал.

ОБНОВЛЕНИЕ

В ветке комментариев было решено, что нам не следует даже пытаться развернуть пакет, содержащий этот API, потому что API уже предоставлен платформой Android. Так что приведенный выше совет неактуален.

Возникла некоторая путаница в отношении зависимостей сборки и зависимостей времени выполнения. android.jar можно добавить к зависимостям проекта build для компиляции пакета, но он ничего не делает во время выполнения исключения, вызывающего "Stub!" исключения. Однако это нормально, потому что это не нужно во время выполнения.

person Neil Bartlett    schedule 14.08.2013
comment
Спасибо, но это сложно. Если мне нужно позаботиться о стольких вещах в моем пакете, чтобы заставить работать каждую отдельную строку, то запуск пакетов на Android будет сложной задачей. Как вы думаете? - person Traveling Salesman; 14.08.2013
comment
Это нужно только в пакете, который экспортирует Log API. - person Neil Bartlett; 14.08.2013
comment
Мой большой вопрос: почему эти ошибки не отображаются при запуске обычного приложения для Android. Почему это так сложно на Bundles? Разве это не способ, с помощью которого вы можете преобразовать приложение Android в пакет, и в этом случае вам не нужно заботиться об этих нативных методах или отсутствующем исходном коде Android API? - person Traveling Salesman; 14.08.2013
comment
Я думаю, потому что пакеты util экспортируются платформой, как я сказал в своем другом вопросе. Так что вам не нужно делать то, что вы делаете. - person Neil Bartlett; 14.08.2013
comment
Извините, @Neil, о каком вопросе вы говорите, когда сказали мой другой вопрос? Я не видел вопроса к вам по этому поводу. - person Traveling Salesman; 14.08.2013
comment
Я имею в виду, что в моем ответе вам один из ваших других вопросов. - person Neil Bartlett; 14.08.2013
comment
Я думаю, что вы имели в виду, что мне не нужно делать то, что я делаю, когда это приложение для Android, но для пакета я должен решить эти проблемы. Это то, что я понимаю от вас сейчас. В любом случае, я буду искать снова и снова, чтобы применить то, что вы говорите в этом ответе. - person Traveling Salesman; 14.08.2013
comment
Еще один момент: куда именно я должен добавить отсутствующую реализацию println_native? Вы сказали в моей связке, но какой связке из двух? И где именно? То же самое для Bundle-NativeCode. Буду признателен, если вы обновите свой ответ более подробно. - person Traveling Salesman; 14.08.2013
comment
Я имею в виду, что вам вообще не нужен пакет, обертывающий пакет android.util, потому что он уже предоставлен платформой. Вам не нужно искать реализации без заглушек, вам не нужно никуда добавлять нативный код. Просто используйте реализацию, уже предоставленную платформой. (Я на 99% уверен, что это правда, потому что вы сказали, что когда это простое приложение для Android, у вас нет этих проблем с доступом к API.) - person Neil Bartlett; 14.08.2013
comment
Я высоко ценю то, что вы только что сказали, и я понимаю это. Но чтобы отобразить сообщение журнала в комплекте, вам нужно импортировать android.util (даже в обычное приложение для Android). В этом случае, где я должен хранить Android API с android.util, который я импортирую? В моей пачке? Я так и сделал и получил ошибку «java.lang.NoClassDefFoundError», которую я показал в вопросе 1. - person Traveling Salesman; 14.08.2013
comment
Вот что я пытаюсь сказать... вам не нужно хранить его где-либо, потому что он уже является частью платформы. - person Neil Bartlett; 14.08.2013
comment
Это выдаст мне синтаксическую ошибку, и пакет не запустится, потому что я использую метод из Android API и нигде не сохраняю Android API. - person Traveling Salesman; 14.08.2013
comment
см. это: dz.prosyst.com/pdoc/mbs_mobile_2 .0.3/android/разработчик/ - person Traveling Salesman; 14.08.2013
comment
Рискую повториться... вам не нужно где-либо хранить Android API. Он уже есть на устройстве!! Android хранит его для вас. Извините, что не могу придумать, как сказать это яснее. Может кто еще попробует. - person Neil Bartlett; 14.08.2013
comment
Я не буду больше обсуждать это, но я уверен, что я близок к достижению своей цели, поэтому я обещаю полный подробный ответ на этот вопрос и на все мои предыдущие вопросы, когда я заставлю все работать на Android-устройстве. - person Traveling Salesman; 14.08.2013
comment
Попробую еще один ракурс. Если это имеет смысл, дайте мне знать, и я обновлю свой ответ. Необходимо различать зависимости сборки и зависимости запуска. Eclipse (из коробки) не знает об API-интерфейсах Android, поэтому вам нужно добавить android.jar в зависимости от сборки, чтобы скомпилировать пакет. Но этот jar предназначен ТОЛЬКО для сборки и вообще ничего не делает во время выполнения, кроме как бросает Stub! исключения. Однако вам это не нужно во время выполнения, поскольку API уже есть как часть платформы. - person Neil Bartlett; 14.08.2013
comment
Да, теперь это имеет смысл для меня, и это то, над чем я сейчас работаю. Наконец-то мы договорились :) - person Traveling Salesman; 15.08.2013
comment
Отлично, поэтому нам нужно перенести это обсуждение в чат, потому что оно слишком длинное, и я обновлю свой ответ. - person Neil Bartlett; 15.08.2013
comment
давайте продолжим это обсуждение в чате - person Neil Bartlett; 15.08.2013