しかし、この問題は、バンドル ${importer} の MANIFEST.MF の Import-Package に ${package} をリストしても解決できない。Felix のコードに問題があるからだ。
【解決方法1】
本質的ではないが、てっとり早い問題解決方法は、バンドルを DEX 変換するときに --keep-classes オプションをつけること。
dx --dex --keep-classes --output=
【解決方法2】
--keep-classes オプションを付けずに DEX 変換された JAR ファイルの場合、JAR ファイルの中に元の *.class ファイル群が含まれていない。そのため、org.apache.felix.framework.ModuleImpl の findClass(String) メソッド内の「bytes = contentPath[i].getEntryAsBytes(actual)」というコードで bytes が null に設定されてしまう。これにより、後続の「if (bytes != null)」条件文が false になり、「getDexFileClass((JarContent)content, name, this)」が呼び出されない。しかし、DEX 変換された JAR の場合、bytes が null かどうかはどうでもよいので、つまり、JAR ファイルの中に xxx.class というファイルが存在するかどうかはどうでもよいので(なぜなら代わりに classes.dex が含まれているので)、この if 文のチェックは不要だ。実際、bytes が null でも構わずに当該 if ブロックの中を実行するようにコードを変更すると、めでたく Felix on Android にインストールした OSGi バンドルをスタートさせることができる。
Solutions for the problem where bundles won't start on "Felix on Android"
If an OSGi bundle is installed on Felix (http://felix.apache.org/) on Android and tried to be started, an error occurs which says "*** Class '${class}' was not found because bundle ${importer} does not import '${package}' even though bundle ${exporter} does export it. To resolve this issue, add an import for '${package}' to bundle ${importer}." This error message means "The bundle ${exporter} exports the package ${package} (= the package ${package} is listed on Export-Package in MANIFEST.MF of the bundle ${exporter}) but the bundle ${importer} does not import the package ${package} (= the package ${package} is not listed on Import-Package in MANIFEST.MF of the bundle ${importer}), so the class ${class} cannot be found. To resolve this issue, the bundle ${importer} should import the package ${package} (= the package ${package} should be listed on Import-Package in MANIFEST.MF of the bundle ${importer})."
However, this issue is not solved even after listing ${package} on Import-Package in MANIFEST.MF of the bundle ${importer}. It is because Felix code has a problem.
[ Solution 1 ]
Not essential, but a quick solution is to add --keep-classes option when you DEX-convert a bundle.
dx --dex --keep-classes --output=BundleForAndroid
[ Solution 2 ]
If a JAR file is converted into DEX without --keep-classes option, original *.class files are not contained in a resultant JAR file. So, the code "bytes = contentPath[i].getEntryAsBytes(actual)" in findClass(String) of org.apache.felix.framework.ModuleImpl sets null to bytes. Because of this, the following conditional statement "if (bytes != null)" is evaluated as false and getDexFileClass((JarContent)content, name, this) is not called. However, for a DEX-converted JAR file, because it does not matter whether bytes is null or not, in other words, because it does not matter whether xxx.class exists in the JAR file or not (because classes.dex is contained alternatively), the check of the if statement is unnecessary. As a matter of fact, if the code is changed so that the content in the if block can be executed even when bytes is null, an OSGi bundle installed on Felix on Android can be happily started.