Wegen eines Problems mit dem Paketnamen aux
unter Windows verschiebe ich eine Hilfsklasse innerhalb der Pakethierarchie meiner Bibliothek von
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?
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
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:
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.
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.
Tags und Links scala binary-compatibility package-private migration-manager