2013-07-02 6 views
6

Mam projektu z jednego pliku źródłowego, uszeregowane tutaj w całości:Dlaczego bnd dodaje dyrektywę uses dla pakietu używanego tylko w treści metody?

package com.acme.el; 

public class ExpressionUtils { 
    public static Object evaluate() { 
     new org.apache.commons.el.ExpressionEvaluatorImpl(); 
     return null; 
    } 
} 

funkcjonalność jest bez znaczenia dla kwestii. Kiedy budować projektu jako wiązkę OSGi przy użyciu Gradle, manifest zawiera następujące czynności:

Export-Package: com.acme.el;uses:="org.apache.commons.el";version="1.0" 

Co przegród mnie to, że dyrektywy uses. Tak jak zrozumiałem dyrektywę, ma ona na celu zdefiniowanie zależności od innych pakietów, które muszą być propagowane do innych pakietów importujących ten wyeksportowany pakiet - jeśli moje definicje klas lub sygnatury metod odnoszą się na przykład do klas w pakiecie org.apache.commons.el. Ale w tej klasie zależność od org.apache.commons.el jest całkowicie zawarta w ciele w ciele metody. Nie jest on ujawniony w interfejsie API i żaden inny pakiet importujący com.acme.el nie może uzyskać blokady instancji ExpressionEvaluatorImpl utworzonej w tej metodzie. Więc zależności nie trzeba propagować, prawda?

Czy źle zrozumiałem znaczenie dyrektywy uses, czy też jej użycie jest niepotrzebne?

Zrobiłem a minimal example GitHub repo for reproduction, które można klonować i importować jako projekt Gradle w środowisku Eclipse.

+0

Przeczytałem rozdział 3.7.5 Pakiety ograniczeń wersji OSGi v4.3.0, ale nie zrobiło mi to o wiele mądrzejszego. Mówi się tylko o tym, kiedy używać dyrektywy 'uses', reszta omawia, w jaki sposób framework powinien obsługiwać te dyrektywy: _ [...] Na przykład, gdy rozszerzają klasy z innego pakietu , lub te inne klasy pojawiają się w podpisach metod. Można zatem powiedzieć, że pakiet ** używa ** innych pakietów. Te zależności między pakietami są modelowane za pomocą dyrektywy uses w nagłówku Export-Package._ –

+0

Twoje zrozumienie ograniczenia "uses" jest poprawne, więc nie jest dla mnie jasne, dlaczego ograniczenie jest generowane przez bnd w tym przypadku. Jeśli masz absolutną pewność, że nie ma innych odniesień do pakietu w innym miejscu, być może znalazłeś błąd; zgłoś go na https://github.com/bndtools/bnd/issues –

+0

Tak, jestem absolutnie pewien - stworzyłem minimalny przykład zawierający tylko jedną klasę wymienioną w pytaniu, którą sam widzisz na połączonym GitHub repo. :) –

Odpowiedz

8

Jeśli w pliku bnd ustawisz wartość -experiments: true, powinieneś uzyskać poprawne użycie: klauzula, tylko w oparciu o publiczne odwołania do API.

Problem polega na tym, że bnd od początku używał wszystkich importów do obliczenia ograniczeń zastosowań. Było to zdecydowanie najłatwiejsze i nikt, jak dotąd, nigdy nie narzekał na to. Jednak stworzyłem kod do skanowania publicznego API, ale nigdy nie czułem się wystarczająco pewny, aby usunąć go z fazy eksperymentalnej ... Obecny model stwarza zbyt wiele ograniczeń użytkowania, ale generalnie powinien być bezpieczny.

Ten kod nie był wystarczająco testowany i nie mam pewności, że zmiana tego obliczenia nie spowoduje problemów w istniejących kompilacjach. Więc jestem tu trochę związany.

+0

Tak, rozumiem, że musi być o wiele trudniejsze. Obecnie próbuję przenieść 10-letnią wojnę korporacyjną do OSGi, a niektóre konflikty starsze powodują konflikty podczas propagacji. Podejrzewam, że to nie jest taki problem, jeśli twoje projekty zależą od nieprzerwanych bibliotek itd. D –

+0

Czy masz pomysł, jak mogę włączyć tę flagę w kompilacji Gradle? Przejrzę oczywiście dokumentację bnd, ale jeśli już wiesz, wstyd byłoby nie dzielić się wiedzą, prawda? :) –

+0

Nie wiem, jak gradle używa bnd ... ale w maven zrobiłbyś <_experiments> true. Zakładam gradle ma podobny model do tłumaczenia instrukcji/makr Bnda? –