Zum Hauptinhalt springen

Wie man Legacy-Eclipse-Anwendungen zu Web und Visual Studio Code migriert

Andreas Mülder Andreas Mülder 9 Min. Lesezeit
Wie man Legacy-Eclipse-Anwendungen zu Web und Visual Studio Code migriert

In den letzten zwei Jahren haben wir itemis CREATE, ein mittelgroßes bis großes Projekt (280.000 Lines of Code), von einer eigenständigen Eclipse-Anwendung auf das Web und Visual Studio Code migriert. Hier sind die Lessons learned aus dieser Umstellung.

Der Rückgang von Eclipse

Eclipse, einst eine dominante integrierte Entwicklungsumgebung (IDE) für Java und andere Programmiersprachen, hat in den letzten 15 Jahren an Popularität verloren. Laut dem Stack-Overflow-Survey 2023 nutzen nur noch 9,9 % der professionellen Softwareentwickler Eclipse. Visual Studio Code hingegen ist mit einer Nutzungsrate von 74 % zur beliebtesten IDE geworden.

Es gibt mehrere Gründe für die sinkende Popularität von Eclipse. Konkurrierende IDEs wie IntelliJ IDEA und Visual Studio Code haben durch ihre bessere Performance und überlegene User Experience an Bedeutung gewonnen. Eclipse wurde dafür kritisiert, umständlich, langsam und ressourcenintensiv zu sein, mit einer weniger intuitiven Oberfläche und umständlichem Plugin-Management. Darüber hinaus haben Verschiebungen bei modernen Programmiersprachen und Frameworks zum weiteren Niedergang von Eclipse beigetragen.

Deshalb haben wir beschlossen, unser Eclipse-basiertes Produkt itemis CREATE auf eine moderne Webanwendung und Visual Studio Code umzustellen. Die größte Herausforderung bestand darin, so viel wie möglich vom bestehenden Code wiederzuverwenden.

Die bestehende Eclipse-Anwendung

In den letzten 1,5 Jahren haben wir unser Produkt itemis CREATE erfolgreich in die Cloud und nach Visual Studio Code migriert. itemis CREATE bietet verschiedene Komponenten, darunter einen grafischen Editor mit zusätzlichen Views für die Modellierung von Software-Verhalten, eine Simulationsengine, eine Validierungs- und Testengine sowie mehrere Code-Generatoren; C, CPP, C#, Java, Python und vieles mehr.

itemis CREATE als Eclipse-Anwendung

Die Codebasis umfasst 119 Plugin-Projekte mit insgesamt ca. 280.000 Lines of Code, ohne generierte Artefakte. Sie ist überwiegend in Java (zwei Drittel) und Xtend (ein Drittel) geschrieben. Wir nutzen intensiv verschiedene Eclipse-Frameworks und -Technologien, hauptsächlich Xtext, Eclipse Modeling Framework (EMF), Graphical Modeling Framework (GMF) sowie SWT/JFace für Benutzeroberflächen.

Übergang zu einer Client-Server-Architektur

Dies ist ein High-Level-Überblick über unsere Client-Server-Architektur, die für unsere neue Webanwendung und das Visual Studio Code Plugin verwendet wird. Unser vorrangiges Ziel war es, so viel Code wie möglich aus unserer bestehenden Eclipse-Anwendung wiederzuverwenden. Für itemis CREATE nutzen wir die Code-Generatoren, die Simulationsengine sowie die Validierungs- und Testengine wieder, die nun in einem Web-Backend gekapselt sind und über eine REST API und WebSocket-Kommunikation Zugang zur bestehenden Codebasis ermöglichen.

High Level Architecture View

Für die Besonderheiten einer Webanwendung sind mehrere zusätzliche Web-Services erforderlich, z. B. für Authentifizierung und Autorisierung sowie das Laden und Speichern von Modellen. Die Webanwendung selbst ist komplett neu und wurde mit VueJS gebaut. Um die Webanwendung in Visual Studio Code zu integrieren, haben wir eine Visual Studio Code Extension entwickelt, die Teile der Webanwendung über die Webview API einbindet. Schauen wir uns die einzelnen Komponenten im Detail an.

Status Quo: Die bestehende Codebasis

Der Schlüssel liegt in einer klaren Trennung zwischen UI- und Nicht-UI-Code. Plugins, die von SWT/JFace oder dem Graphical Modeling Framework abhängen, können nicht in Webanwendungen wiederverwendet werden und müssen vollständig neu gebaut werden.

Im Gegensatz dazu ist das Wiederverwendungspotenzial nicht-UI-bezogener Plugins recht hoch. Frameworks wie das Eclipse Modeling Framework und sogar Xtext über das Language Server Protocol lassen sich mit einigen Refactorings leicht wiederverwenden.

Die Webanwendung neu aufbauen

Diese Aufgabe ist zwar aufwendig, aber entscheidend, um die veraltete Eclipse-UI auf ein modernes und benutzerfreundlicheres Design zu aktualisieren. Moderne Single-Page-Application (SPA)-Frameworks wie Angular, React und Vue vereinfachen die Entwicklung ansprechender Benutzeroberflächen im Vergleich zu Eclipses SWT und JFace erheblich. Zahlreiche UI-Widget-Bibliotheken wie Vuetify, React Material UI oder PrimeNG ermöglichen die Erstellung reichhaltiger Benutzeroberflächen. SWT/JFace dagegen bietet nur ein begrenztes Komponentenspektrum und wirkt veraltet.

Dasselbe Prinzip gilt für Plugins, die mit dem Graphical Editing Framework (GEF) oder dem Graphical Modeling Framework (GMF) erstellt wurden. Glücklicherweise gibt es hervorragende Frameworks für den Aufbau grafischer Editoren im Web, wie JointJS oder yFiles. Diese Frameworks unterscheiden sich in ihren Funktionen, daher ist es wichtig, eines zu wählen, das die eigenen Anforderungen erfüllt. Sie lassen sich in der Regel auch gut mit bestehenden SPA-Frameworks integrieren.

itemis CREATE als Webanwendung

In unserem Projekt haben wir uns für VueJS mit Vuetify sowie JointJS entschieden. Ich bin jedoch zuversichtlich, dass andere Framework-Kombinationen ebenfalls funktionieren würden. Die neue Webanwendung umfasst ca. 22.000 Lines of Code, die überwiegend in TypeScript und Vue geschrieben sind. Der UI-Code der Eclipse-RCP-Anwendung beläuft sich dagegen auf rund 80.000 Zeilen – fast viermal so viel.

Refactoring der nicht-UI-bezogenen Codebasis

Um den nicht-UI-bezogenen Code wiederverwenden zu können, ist etwas Vorarbeit erforderlich. Die Plugins laufen zunächst in einer Non-OSGi-Umgebung, d. h., alle Registrierungen über die plugin.xml werden ignoriert und müssen programmatisch vorgenommen werden. Für EMF bedeutet das die manuelle Registrierung von Paketen und Factories sowie aller Custom Extension Points und Extensions in der bestehenden Codebasis.

Außerdem steht beim Ausführen des Codes im Web-Backend kein Eclipse-Workspace zur Verfügung. Daher müssen Plugins, die auf org.eclipse.core.filesystem basieren, so angepasst werden, dass sie ohne einen klassischen Workspace funktionieren. Unsere Code-Generatoren beispielsweise, die generierte Artefakte traditionell direkt im Eclipse-Workspace ablegen, müssen das Ergebnis (d. h. die generierten Dateien) jetzt an den Client zurückgeben. Der Client kann dann entscheiden, ob er sie in einem Workspace speichert (im Kontext von Visual Studio Code), sie als Zip-Datei zurückgibt, in einer Datenbank ablegt oder anderweitig damit umgeht. Diese Flexibilität lässt sich jedoch leicht mit einer Kombination aus Indirektionen und Dependency Injection erreichen.

Wenn man die Eclipse-basierte Anwendung weiter unterstützen möchte, sollte man den Code so refaktorieren, dass er in beiden Umgebungen lauffähig ist. Keinesfalls sollte man vom bestehenden Code base abzweigen – das führt direkt in die Maintenance-Hölle.

Die bestehende Codebasis als Web-Backend

Das Web-Backend fungiert als Kommunikationsschicht zwischen den Clients und den bestehenden sowie neuen Services. In unserer Implementierung ist es eine dünne Schicht auf Basis von Spring Boot, die REST-Controller bereitstellt und die vom Client gesendeten Payloads in ein Format umwandelt, das die bestehende Eclipse-Codebasis versteht. Während der Client Payloads typischerweise im JSON-Format sendet, verwendet das bestehende Backend das XMI/EMF-Format zum Laden und Serialisieren von Modellen. Daher führen wir Modell-zu-Modell-Transformationen durch, um zwischen diesen beiden Formaten zu übersetzen. Interessant in diesem Zusammenhang ist auch das Projekt emfjson-jackson, das nützlich sein kann, wenn man beim clientseitigen Format flexibel ist und nur eine JSON-Repräsentation der bestehenden EMF-Modelle benötigt.

Für unsere Custom Domain Specific Languages haben wir die Xtext Language Server-Implementierung verwendet. Damit versteht Xtext das Language Server Protocol und lässt sich nahtlos mit Visual Studio Code und dem Monaco Web Editor integrieren. Für Syntax-Highlighting und Quick Fixes ist etwas Anpassung nötig, aber die meisten Features wie Validierung und Code-Completion funktionieren out of the box.

Man sollte den Aufwand für Build, Packaging und Deployment nicht unterschätzen. Man muss sich mit Technologien auseinandersetzen, die in der klassischen Eclipse-Entwicklung unüblich sind. In unserem Fall haben wir unsere Backend-Services auf AWS deployed, und es gibt eine Menge neuer Tools und Technologien, die man lernen muss, bevor man loslegen kann.

Außerdem benötigt man zusätzliche Services, die vorher nicht erforderlich waren – schließlich ist die Eclipse-Anwendung eine Einzelbenutzer-Anwendung, die auf dem lokalen Desktop läuft. Man sollte robuste Authentifizierungs- und Autorisierungsmechanismen implementieren, um die Backend-Services zu sichern. Dies kann die Integration mit OAuth-Providern oder anderen Identity-Management-Systemen umfassen. Sichere Kommunikation zwischen der Extension und dem Backend sollte über HTTPS und Token-basierte Authentifizierung gewährleistet werden.

Wie bereits erwähnt, benötigt man möglicherweise einen Ersatz für den klassischen Eclipse-Workspace zum Speichern von Modellen als Dateien. In unserem Fall verwenden wir eine Dokumentendatenbank, um Benutzermodelle, Einstellungen und Metadaten als JSON zu speichern.

Bei itemis CREATE haben wir am Ende ~210K/280K Lines of Code wiederverwendet und ~22K Lines of Code für die zusätzlichen Services und das Backend neu geschrieben.

Die Visual Studio Code Extension

Die Visual Studio Code Extension integriert unsere neue webbasierte Anwendung in Visual Studio Code. Die Webview API macht es einfach, bestehenden JavaScript/HTML-Code zu integrieren und ermöglicht es uns, den Großteil der Web-Frontend-Anwendung wiederzuverwenden. Dazu muss man lediglich einen neuen Editor registrieren, ihn mit einer bestimmten Dateiendung verknüpfen und die Hauptanwendung in den Editor-Tab laden.

itemis CREATE in Visual Studio Code

Bei der Integration einer eigenständigen Anwendung in die VSCode-Umgebung ist es entscheidend, eine tiefe Integration mit den VSCode Extension Points sicherzustellen, um ein konsistentes Look and Feel zu gewährleisten. Das bedeutet nicht nur, die Webanwendung im Editor anzuzeigen, sondern auch die Integration mit nativen VSCode-Komponenten wie den Preferences, der Problems View und der Benachrichtigungsinfrastruktur.

Dazu ist eine bidirektionale Kommunikation zwischen der äußeren VSCode-Anwendung und der inneren Webanwendung (z. B. itemis CREATE) erforderlich. Die Webview API ermöglicht diese Kommunikation – wenn auch etwas unhandlich – über webview.postMessage() und window.addEventListener(). Das ähnelt der Kommunikation mit einem iframe in der Webentwicklung.

Wenn man beispielsweise eine Extension für Preferences registriert, benötigt man einen Listener, der die innere Anwendung über Preference-Änderungen informiert und diese entsprechend verarbeitet. Umgekehrt kann die innere Anwendung bei einem Fehler eine Nachricht an die äußere Anwendung (VSCode) senden, um eine Benachrichtigung über das VSCode-Benachrichtigungssystem auszulösen.

Dazu sollte man die Komponenten und Services der Webanwendung so aufbauen, dass sie gegen unterschiedliche Implementierungen ausgetauscht werden können. Zum Beispiel könnte man einen Notification Service für die Webanwendung haben, der bei einem Fehler einen Toast anzeigt, und einen anderen, der an die VSCode-Umgebung delegiert. Auch hier hilft Dependency Injection, zwei Anwendungen – eine für VSCode und eine für das Web – aus derselben Codebasis zu komponieren.

Insgesamt erforderte die VSCode-Integration dank einer gut strukturierten und wiederverwendbaren Webanwendung nur 2.000 Lines of Code!

Zusammenfassung

Die Migration von Plugins aus einer Eclipse-basierten Umgebung in eine webbasierte Architektur erfordert mehrere kritische Überlegungen und erheblichen Aufwand, insbesondere bei den UI-Komponenten. Die folgenden Punkte fassen die Lessons learned zu den Herausforderungen dieses Migrationsprozesses zusammen:

  • Klare Trennung der Zuständigkeiten: Plugins müssen eine klare Trennung zwischen UI- und Nicht-UI-Komponenten aufweisen, um eine reibungslosere Migration zu ermöglichen.
  • Neuimplementierung von UI-Plugins: UI-bezogene Plugins müssen neu implementiert werden, da sie in einer Web-Umgebung nicht direkt wiederverwendet werden können.
  • UI-Migrationsaufwand: Der Großteil des Migrationsaufwands entfällt auf UI-Elemente, da SWT/JFace Dialogs sowie Graphical Model/Editing Frameworks nicht ins Web übertragen werden können.
  • Effizienz mit Web-Technologien: Die Neuimplementierung von UI-Editoren und Dialogen mit Web-Technologien ist deutlich weniger aufwendig als ihre Pflege im Eclipse-Ökosystem.
  • Unterschiede in UX/UI: Web-UX/UI-Designprinzipien unterscheiden sich von denen in Eclipse und erfordern einen neuen Ansatz für die UI-Entwicklung.
  • Wiederverwendbarkeit von Backend-Code: Nicht-UI-bezogener Code kann nahtlos im Backend wiederverwendet werden. Technologien wie EMF funktionieren gut im Backend, Xtext/LSP lässt sich ebenfalls gut integrieren.
  • Neuer Technologie-Stack: Die Einführung eines neuen Technologie-Stacks bringt eine Lernkurve mit sich, unter anderem beim Deployment mit Docker, AWS und Spring Boot.
  • Backend-Refactoring: Backend-Code erfordert einiges Refactoring, um sich an eine Non-OSGi-Umgebung anzupassen, ohne plugin.xml und Eclipse-Workspace.
  • Neue Anforderungen: Die Migration bringt neue Anforderungen mit sich, z. B. Benutzerverwaltung, Sicherheit, Authentifizierung und Autorisierung.
  • Integration mit VSCode: Die Wiederverwendung einer Webanwendung in VSCode ist mit der Webview API unkompliziert und erleichtert die Integration erheblich.

Bei Fragen zu denselben Herausforderungen oder wenn Sie sich zu diesem Thema austauschen möchten, nehmen Sie gerne Kontakt auf.


Legacy Modernisierung bei itemis — Wir helfen Teams dabei, ihre Softwaresysteme Schritt für Schritt zu modernisieren: Legacy Modernisierung →

Ursprünglich veröffentlicht auf Medium. Lizenziert unter CC BY 4.0.

Andreas Mülder

Principal Software Engineer

Andreas Mülder ist Principal Software Engineer bei itemis und als technischer Projektleiter für itemis CREATE verantwortlich. Seit 2007 entwickelt er Werkzeuge für Plattformen wie Eclipse, Visual Studio Code, Cloud und Web – mit Schwerpunkt auf Language Engineering, domänenspezifischen Sprachen, Simulatoren und Codegeneratoren sowie der Integration generativer KI in produktreife Tools. Sein Wissen gibt er in Blog-Beiträgen zu Language Engineering und KI-gestützter Werkzeugentwicklung weiter.