2016-09-14 2 views
2

Bundle-A:OSGi classloading: Warum importiert BND Klassen, die nicht direkt referenziert werden?

FooA.java

package com.foo.a; 

import com.foo.b.FooB; 

class FooA { 
    FooB b = new FooB(); 
} 

Bundle-B:

FooB.java:

package com.foo.b; 

import com.foo.c.FooC; 

class FooB { 

    public FooC foo() { 
     ... 
    } 
} 

Bundle-C: ...

Kurz gesagt, ich habe 3 Bündel - A, B und C.

Bündel A Referenzen Bündel B direkt, und Bündel B Referenzen C. Wie Sie sehen, verwendet FooA nicht die Methode in FooB, die FooC zurückgibt, so FooC wird nicht direkt in Bundle A referenziert.

Warum ist BND inklusive OSGi-Import-Paket zu com.foo.c? So wie ich es verstehe - Bündel A braucht nur Bündel B, um sich selbst auflösen zu können. Bündel B hingegen braucht C. Aber warum sollte A C direkt benötigen, wenn es dort nicht gebraucht wird?

Antwort

2

Ich denke, dass bnd importiert alle Klassen, die für die Klassen sichtbar sind, die Sie verwenden. Wenn Sie die Klasse FooB verwenden, benötigen Sie möglicherweise Zugriff auf alle Klassen, die sie als Parameter benötigen oder als Ergebnisse zurückgeben können.

Wenn Sie die Abhängigkeit vermeiden möchten, können Sie eine Schnittstelle erstellen, die nur die Methoden anzeigt, die Sie wirklich benötigen. Sie können dann einen Service mit dieser Schnittstelle in Bundle B erstellen und nur über die Schnittstelle von Bundle A auf den Service zugreifen.

+0

Okay, ich verstehe die Idee mit der Einführung der Schnittstelle. Aber ich suche keine Lösung für dieses spezielle Problem. Was ich versuche, ist, das Problem zu verstehen - warum nimmt BND dieses Paket auf? Wird das Paket wirklich benötigt? Wenn ich den Import manuell lösche, würde dies das Classloading unterbrechen? Warum? A verwendet C nicht direkt ... – mdzh

+0

Es kommt darauf an, ob Java C benötigt, um Klasse A zu instanziieren oder in Ihrem Fall zu verwenden. Es wäre interessant zu sehen, was passiert, wenn Sie den Import entfernen. Wenn es noch funktioniert, kann vielleicht bnd verbessert werden, aber im Allgemeinen ist es ziemlich genau. Noch sollten Sie wirklich versuchen, Schnittstellen und Dienstleistungen zu benutzen ... es ist die einzige Weise, Ihre Module wirklich zu entkoppeln. –

2

Werfen Sie einen Blick auf den Bytecode der FooA-Klasse. Du wirst FooC irgendwie darin sehen. Verwenden Sie ein Java Decompiler-Tool, um zu sehen, warum es verwendet wird. Einige Decompiler erstellen Code, der ein wenig mehr Informationen als der ursprüngliche Java-Code zeigt. Ich do siehe nicht hier, why, aber hier ist another example:

Guess Sie die following function verfügen:

public class ListProvider { 

    public static ArrayList getMyList() { return null; } 

} 

And andere class calls ihn like dies:

List myVar = ListProvider.getMyList(); 

Sie werden siehe ArrayList im Bytecode der anderen Klasse. Der Grund dafür ist, dass die Funktionssignatur, die im Bytecode leven verwendet wird, auch den Rückgabetyp enthält.

Verwandte Themen