Warnen Sie vor verbotenen Methoden von Drittanbietern

9

Hinweis: Diese Frage bezieht sich auf Code, der in Java oder C # geschrieben wurde.

Ich verwalte einige große Projekte, bei denen wir Probleme (nicht unbedingt Fehler) mit einigen Drittanbieter- / SDK-Methoden entdeckt und unsere eigenen Erweiterungen geschrieben haben, die stattdessen verwendet werden sollten. Wir möchten, dass Entwickler sich daran erinnern, dass die Verwendung dieser Methoden für dieses Projekt nicht empfohlen wird.

Wenn wir unsere eigenen Bibliotheken verwendet hätten, könnten wir diese Methode leicht entfernen oder als veraltet / veraltet markieren, aber wir können dies nicht für Bibliotheken tun, die wir nicht geschrieben haben.

Als Beispiel verwenden wir eine Bibliothek, die uns zwei Überladungen bietet:

acme.calculate(int quantity_, double priceInUsDollars_);
acme.calculate(int quantity_, string currencyCode_, double priceInCurrency_);

Wir möchten, dass Entwickler immer den ersten verwenden und den Preis in US-Dollar von unseren eigenen Standard-Wechselkurssystemen erhalten. Und es wäre schön, wenn die IDE (Eclipse / Visual Studio) die Entwickler warnen würde, wenn sie die erste verwenden. Eine Compiler-Warnung reicht ebenfalls aus.

Derzeit müssen wir uns auf die Codeprüfer verlassen, um solche Fehler zu erkennen, und wie Sie sehen, ist dies kein verlässlicher Ansatz.

Ein möglicher Weg, auf den ich vorbereitet bin, besteht darin, meinen eigenen Check Style Check zu schreiben ( http://checkstyle.sourceforge.net/writingchecks.html ). Aber ich fragte mich, ob es etwas Einfaches gab, das ich verwenden konnte. Kennt jemand Möglichkeiten, um eine IDE / Compiler-Warnung der von mir beschriebenen Art zu erreichen?

Nicht-IDE / Compiler-Lösungen sind herzlich willkommen.

Apoorv Khurasia
quelle
1
Warum können Sie die Quelle nicht in Bibliotheken von Drittanbietern ändern? Sie haben es, nehme ich an? (Wenn nicht, ist das das eigentliche Problem, auf das Sie sich konzentrieren müssen. Tun Sie das niemals.)
Mason Wheeler
3
@ MasonWheeler Leider können wir das eigentlich nicht. Es ist eine kompilierte Binärdatei (.dll, .jar), die wir verwenden. Außerdem gibt es Fallstricke bei diesem Ansatz, da wir spätestens
loslegen
4
@MasonWheeler: Der Zugriff auf den Quellcode einer Drittanbieter-Bibliothek ist etwas, aus dem Sie häufig nicht frei wählen können. Es gibt viele Closed-Source-Bibliotheken auf dem Markt, für die es keine nützliche Open-Source-Alternative gibt.
Doc Brown
Können Sie die Klassen in ihrer Bibliothek erben und den Methoden, die sie nicht aufrufen sollen, eine Überschreibung hinzufügen, die als veraltet markiert ist?
CaffGeek
@ DocBrown: Ich habe nicht Open Source gesagt. Ich sagte Quelle zur Verfügung. Es gibt viele proprietäre Bibliotheken, die Ihnen die Quelle (unter einer proprietären Lizenz) beim Kauf geben. Wir haben die Richtlinie, niemals Bibliotheken von Drittanbietern ohne verfügbare Quelle zu verwenden, und wir haben nie eine Situation gefunden, in der wir dies tun mussten.
Mason Wheeler

Antworten:

7

Mit einem Tool wie NDepend / JavaDepend können Sie benutzerdefinierte CQL-Abfragen schreiben, um Warnungen für diese ganz bestimmten Fälle zu generieren.

Sie sagten in der Frage, dass die IDE / der Compiler die Entwickler warnen soll. Ich denke, da NDepend / JDepend eng in die IDE integriert sind, kann dies Ihr Problem lösen.

MattDavey
quelle
3
Das ist ein guter Anruf. Und Sie können mit NDepend (nie verwendetes JavaDepend) problemlos ein Schema erstellen, bei dem Warnungen / Warnungen bei Verstößen gegen Checkins ausgelöst wurden oder bei denen die Checkins abgelehnt wurden, abhängig von den anderen beteiligten Tools (Quellcodeverwaltung, Build).
Erik Dietrich
Das klingt vielversprechend. Ich werde es morgen versuchen und dich wissen lassen. Danke Matt.
Apoorv Khurasia
Es sieht so aus, als hätten sie ihren Produktnamen von JavaDepend in JArchitect geändert, aber das Programm sieht immer noch ziemlich interessant aus.
Dalin Seivewright
4

Der "White-List-Ansatz": Schreiben Sie eine Wrapper-Bibliothek in die Bibliothek mit im Wesentlichen denselben Schnittstellensignaturen wie die Bibliothek selbst, lassen Sie jedoch die verbotenen Funktionen aus. Der Wrapper sollte jeden Methodenaufruf an den entsprechenden Bibliotheksaufruf delegieren. Dann lassen Sie Ihre Entwickler nur / Link zu diesem Wrapper anstelle der ursprünglichen Bibliothek verwenden. Der Wrapper ist möglicherweise auch ein guter Ort für Ihre Bibliothekserweiterungen.

Natürlich kann dies unpraktisch werden, wenn die Bibliothek eine sehr große API mit mehreren hundert Funktionen hat. Dann möchten Sie einen "Black List-Ansatz" wie die von Ihnen vorgeschlagene "Check Style" -Lösung implementieren.

Doc Brown
quelle
Ja. Es ist eine riesige Bibliothek. Schlimmer noch, wir haben viele solcher Bibliotheken (in C #, Java-Projekten). Ich denke auch an Ameisenprüfungen nach der Kompilierung.
Apoorv Khurasia
2
Dies war auch mein erster Gedanke, aber als er die Frage des OP ein zweites Mal las, schien er eher nach "Warnungen" als nach einer restriktiveren Architektur zu suchen. Ich denke, dies ist ein Problem eher der statischen Analyse als des Schreibens von mehr Code ...
MattDavey
@ MattDavey Das ist wahr.
Apoorv Khurasia
Es gibt Wrapper-Generator - Programme ( zB , sourceforge.net/projects/wrappergen ) , die für Sie den mühsamen Teil tun. Dann ist es nur eine Methode, die von Hand gelöscht oder kommentiert werden muss.
Ross Patterson
@ RossPatterson-Wrapper sind nicht nur eine einmalige Kapitalinvestition. In einigen Fällen können sie zu einem Alptraum werden.
Apoorv Khurasia
2

Eine der Stärken von Java's Reflection besteht darin, dass Sie die Methodeneigenschaften zur Laufzeit ändern können. Eine der Verwendungsmöglichkeiten besteht darin, eine private Methode öffentlich zu machen, um sie trotzdem verwenden zu können. Es könnte sehr gut umgekehrt funktionieren, wenn Sie unerwünschte Methoden zur Laufzeit privat machen. Obwohl es bei der Kompilierung nicht angezeigt wird, wird es angezeigt, sobald das Projekt getestet wurde.

Dieser Artikel zeigt, wie Methodeneigenschaften zur Laufzeit geändert werden. Hier ist der interessante Teil:

Class theClass = MyClass.class;
Class[] paramTypes = { Integer.TYPE, String.class };
Method method = theClass.getDeclaredMethod("myMethodName", paramTypes);
method.setAccessible(false); // this makes the metod private
System.out.println("Making method  myMethodName(int,String) private");
XGouchet
quelle
1
Vielen Dank. Ich werde zuerst die Lösung von MattDavey ausprobieren, da ich damit statische Analysen durchführen kann. Das heißt, wenn alle statischen Ansätze fehlschlagen, werde ich Ihre Lösung versuchen.
Apoorv Khurasia
1
Das wird nicht funktionieren, denke ich. Bei kompiliertem Code werden Sichtbarkeitsregeln zuletzt beim Laden überprüft, wenn Bytecodes überprüft werden. Nachfolgende Änderungen unter Verwendung der reflektierenden APIs wirken sich nur auf andere reflektierende Aufrufe aus.
Stephen C
0

Wir möchten, dass Entwickler sich daran erinnern, dass die Verwendung dieser Methoden für dieses Projekt nicht empfohlen wird.

Da mussten Sie in einigen Fällen bereits Ersatzmethoden erstellen. Ich würde eine Wrapper-Klasse für die gesamte Bibliothek erstellen und nur Ihre Wrapper-Klasse verwenden.

Wenn die Bibliothek aktualisiert wird, müssten Sie Ihren Code trotzdem aktualisieren. Die Wrapper-Klasse ist einfach zu aktualisieren.

Es vermeidet, dass Entwickler die falsche Methode verwenden, obwohl ... ich wage zu sagen, dass ein Entwickler sich daran erinnern sollte, welche Methoden er nicht verwenden soll.

Ramhound
quelle
3
Nein, es ist nicht vernünftig zu erwarten, dass sich ein Entwickler daran erinnert, dass er in einer Bibliothek, die er verwendet, einfach keine vollkommen logischen Methoden verwenden soll. Ein oder zwei vielleicht, aber in der Regel können sich Menschen einfach nicht zuverlässig an so etwas erinnern. Heck, hochqualifizierte und absolut motivierte Piloten können sich nicht darauf verlassen, dass sie sich an alle Details erinnern, um das Flugzeug sicher vom Boden zu bringen - deshalb gibt es Checklisten für das Cockpit!
Michael Kohne
Genau das will ich. Verwenden Sie diese Funktion und die IDE generiert eine Warnung.
Apoorv Khurasia
@MichaelKohne - Als ich ein ähnliches Problem wie der Autor hatte, hatte ich kein Problem damit, mich daran zu erinnern, welche Methoden ich verwenden sollte. Die fragliche Bibliothek bestand leicht aus 100 verschiedenen Methoden.
Ramhound