Eine private Paketklasse verschieben - sollte ich diese Binärdatei für inkompatibel halten?

8

Wegen eines Problems mit dem Paketnamen aux unter Windows verschiebe ich eine Hilfsklasse innerhalb der Pakethierarchie meiner Bibliothek von

%Vor%

bis

%Vor%

Die Klasse ist für die Bibliothek privat, d. h. private[scalainterpreter] object Helper .

Unter Verwendung des TypeSafe-Migrations-Managers wird jetzt offensichtlich gemeldet, dass die Änderung nicht kompatibel ist:

%Vor%

Aber ich vermute, dass, wenn der Client-Code nicht in eines der Objekte aufruft, die Interfaces immer noch kompatibel sind, und ich daher eine kleinere Versionserweiterung verwenden kann, um die Änderung anzuzeigen und diese beiden Versionen austauschbar zu verwenden.

>

Korrekt?

    
0__ 28.08.2012, 19:35
quelle

3 Antworten

1

Es ist leicht zu sehen, wie Inlining den Client-Code zerstören kann, da der inline-Code im Wesentlichen in die Client-Schnittstelle mündet. In diesem Beispiel wird wirklich nach einem Verknüpfungsfehler gefragt. Wir können experimentieren und Dinge wie javap | tun grep Helper, aber auf einem Level muss man scalac seine Arbeit machen lassen.

%Vor%

Probe, die unschuldig dem Klienten widersteht:

%Vor%

Ändern des Pakets package-private class:

%Vor%

Javap zeigt warum. [Der Anruf ist zwar inline, aber er möchte das Modul trotzdem initialisieren.]

Ich habe die Diskussionen nicht verfolgt, aber zum Beispiel gibt es Links bei: Ссылка und andere Diskussionen über die ML darüber, welche Erwartungen an die Binärkompatibilität gelten. Zypern

    
som-snytt 06.09.2012, 16:52
quelle
3

Sie geben nicht an, ob Helper bereits vor dem Verschieben Paket-privat war. Also werde ich beide Fälle behandeln:

  • Wenn es bereits Paket privat war:

    Ich vermute, dass der Migrationsmanager eine Inkompatibilität nur meldet, weil er konservativ bleiben muss: Pakete sind in scala (wie in Java) geöffnet, was bedeutet, dass Client-Code sehr wohl ein Klassenpaket scalainterpreter definieren kann. Wenn Sie also Helper verschieben, würden Sie diese Klasse tatsächlich unterbrechen.

    Aber lasst uns pragmatisch sein: de.sciss.scalainterpreter.aux ist euer Paket (und das sollten ihre Unterpakete sein), und niemand sollte dort seine eigenen Klassen definieren. Mit dieser zusätzlichen Voraussetzung ist das Verschieben von Helper tatsächlich eine binärkompatible Änderung in Richtung Client scala -Code.

    Wie beim client java -Code ist das ein bisschen anders, denn selbst wenn Helper package private ist, ist seine Sichtbarkeit immer public , was die JVM betrifft, und somit der Java-Compiler wird dem Client-Code gerne den Zugriff auf Helper gewähren (daher kann der Client-Java-Code sehr wohl bereits auf Helper zugreifen, obwohl das Paket privat deklariert ist).

  • Wenn das Paket vor dem Verschieben nicht privat war:

    Nun, Pech gehabt. Der Client-Code könnte sehr gut auf Helper zugreifen, und der Umzug wird das sicherlich brechen. Als Nebenbemerkung können Sie einen kleinen Trick anwenden, um die Quellkompatibilität für die Änderung zu ändern, aber leider nicht binärkompatibel. Fügen Sie einfach die folgende Datei hinzu:

    %Vor%

Mit dem oben genannten können Sie immer noch auf Helper als de.sciss.scalainterpreter.aux.Helper zugreifen, und kompiliert immer noch unter Windows (im Gegensatz zum Definieren eines Pakets aux , das wegen der reservierten Bedeutung als Dateiname nicht kompiliert wird). Aber auch dies ist nicht binärkompatibel, nur quellkompatibel.

    
Régis Jean-Gilles 06.09.2012 15:30
quelle
0

Einfach gesagt, kein Grund, warum es nicht sein würde. Verknüpfung geschieht um Signaturen; Da das betreffende Objekt auf die Kompilierungseinheit beschränkt ist, können Clients es nicht verwenden (oder vielmehr verwenden), und die Binärkompatibilität ist daher kein Problem.

    
Tomer Gabel 06.09.2012 15:06
quelle