Migration von WebLogic nach WildFly

Dirk Weil

(c) Shutterstock / sakkmesterke

Einer unserer Kunden betreibt eine Reihe von Enterprise-Anwendungen, die vor knapp 15 Jahren entstanden sind. So positiv die Tatsache ist, dass die Anwendungen ihren Zweck immer noch gut erfüllen, so ist damit aber auch ein Problem verbunden: Die Anwendungen sind technisch auf dem Stand von damals. Sie nutzen J2EE 1.4 und laufen auf einem BEA WebLogic 8. Für diesen – damals topaktuellen – Server und die Laufzeitumgebung Java 1.4 gibt es keinen Support mehr. Die Unternehmensstrategie zeigt klar auf Java 7+ und JBoss bzw. WildFly als Application Server. Womit sich die Frage stellt: Sind solche technisch in die Jahre gekommene Anwendungen überhaupt migrierbar und kann man dabei auch noch einen Application-Server-Wechsel wagen?

Auch wenn es uns manchmal nicht schnell genug geht: Java entwickelt sich kontinuierlich weiter und im Bereich der Enterprise Edition haben über die Jahre diverse neue Konzepte Einzug erhalten. Wir empfehlen unseren Kunden daher i. A., ihre Anwendungen in einem gewissen Rahmen aktuell zu halten, Versionswechsel in den genutzten Plattformen und Frameworks also in sinnvollen Abständen „mitzumachen“ und die Anwendungen entsprechend zu aktualisieren, wobei die Wirtschaftlichkeit dieser Strategie immer fallweise zu prüfen ist.

Im konkreten Fall war jedoch keine Anpassung geschehen, sodass diverse große Versionssprünge für die Aktualisierung der Anwendungen vor uns lagen:

  • J2SE 1.4 –> Java 8
  • J2EE 1.4 –> Java EE 7
  • EJB 2.1 –> EJB 3.2 / JPA 2.1
  • BEA WebLogic 8 –> WildFly 8

Der wesentliche Punkt hiervon war sicher die Ablösung der auf Entity Beans der Version 2.1 basierenden Persistenzschicht der Anwendungen. Entity Beans sind im Standard EJB 3.x nicht mehr enthalten. Aktuelle Server müssen sogar die Entity Beans der Version 2.1 nicht mehr unterstützen – dieser Teil der Spezifikation ist mit EJB 3.2 optional geworden.

Nun hätte man das nicht ganz so eng sehen müssen: WildFly 8 unterstützt EJB-2.1-Entity-Beans noch. Es kam aber erschwerend hinzu, dass in den Anwendungen Toplink zur Anreicherung der EJB-Persistenz eingesetzt wurde.

Damals: EJB-2.1-Entity-Beans mit Toplink

Die Persistenz in EJB 2.1 basiert auf abstrakten Klassen, die für die in der Datenbank abzulegenden Attribute jeweils abstrakte Getter und Setter vorsehen:

  public abstract class WerkstoffBean {
  public abstract long getId();
  public abstract int getVariante();
  public abstract String getBezeichnung();
  …

Im Deskriptor ejb-jar.xml sind die Attribute erneut – redundant – aufgeführt:

<entity>
  <ejb-name>WerkstoffBean</ejb-name>
  <home>WerkstoffHome</home>
  <remote>Werkstoff</remote>
  <ejb-class>WerkstoffBean</ejb-class>
  <persistence-type>Container</persistence-type>
  <prim-key-class>WerkstoffPK</prim-key-class>
  <reentrant>False</reentrant>
  <cmp-field>
    <field-name>id</field-name>
  </cmp-field>
  <cmp-field>
    <field-name>variante</field-name>
  </cmp-field>
  <cmp-field>
    <field-name>bezeichnung</field-name>
  </cmp-field>

Im hierin ebenfalls referenzierten sog. Home Interface sind die ebenfalls abstrakten Finder, d. h. Such-Methoden der Bean deklariert:

public interface WerkstoffHome extends EJBHome {
   public Werkstoff findByPrimaryKey(WerkstoffPK key)
     throws RemoteException, FinderException;
   public Werkstoff findByVariante(int variante) 
         throws RemoteException, FinderException;
…

Der Container implementierte die Property-Methoden wie auch die Finder in einer von der abstrakten Klasse abgeleiteten Klasse, wobei der Deskriptor für die Finder die zu nutzenden Query-Ausdrücke vorgab.

Kommt Ihnen das alles recht kompliziert und „sperrig“ vor? Dann haben Sie den richtigen Eindruck erhalten! Dennoch war das Verfahren in seinen Konfigurationsmöglichkeiten eingeschränkt: Es gab bspw. keine Möglichkeit, (technische) Keys generieren zu lassen, besondere Feld-Mappings zu nutzen, Caching-Eigenschaften zu beschreiben oder erweiterte Queries zu formulieren – alles Dinge, die ein früher O/R-Mapper namens Toplink bereits beherrschte.

BEA gelang es damals, Toplink zu akquirieren und als Plug-in für die Container Managed Persistence in den WebLogic Server einzubauen. In einem zusätzlichen Deskriptor konnten nun die über den Standard der EJB-Persistenz hinaus gehenden Eigenschaften von Entity Beans mit Hilfe von Toplink-Parametern beschrieben werden:

<opm:class-mapping-descriptor>
  <opm:class>WerkstoffBean</opm:class>
         <opm:querying>
            <opm:queries>
               <opm:query toplink:name="findByVariante">
                  <arguments>
                     <argument name="1">
                        <type>java.lang.Integer</type>
                     </argument>
                  </arguments>
                  <toplink:call xsi:type="ejbql-call">
                     <toplink:ejbql>SELECT OBJECT(werkstoff)
                                    FROM Werkstoff w 
                                    WHERE w.variante = ?1
                     </toplink:ejbql>
                  </toplink:call>
               </opm:query>               
            </opm:queries>
         </opm:querying>
         <opm:attribute-mappings>
            <opm:attribute-mapping>
               <opm:attribute-name>variante</opm:attribute-name>
               <opm:field table="WERKSTOFF" name="VARIANTE"/>
            </opm:attribute-mapping>
            <opm:attribute-mapping>
               <opm:attribute-name>bezeichnung</opm:attribute-name>
               <opm:field table="WERKSTOFF" name="BEZEICHNUNG"/>
            </opm:attribute-mapping>

Sie finden, dass das jetzt nicht gerade einfacher geworden ist? Stimmt! Fassen wir mal zusammen, was wir jetzt beisammen haben: Eine abstrakte Bean-Klasse, ein Home Interface, ein hier nicht weiter beschriebenes Local Interface sowie zwei recht kryptische XML-Deskriptoren.

Heute: JPA-Entity und CDI-basierte DB-Zugriffsklasse

In der aktuellen Plattform Java EE 7 hat Java Persistence den Platz von Entity Beans übernommen. Diese lassen sich als einfache Klassen formulieren, die um JPA-Annotationen für das Mapping zur Datenank angereichert sind:

@Entity
public class Werkstoff extends StandardEntity<Long> {
    
      @Id
      @Column(name = "ID")
  private Long id;

      @Column(name = "VARIANTE")
      private Integer    variante;

      @Column(name = "BEZEICHNUNG")
      private String     bezeichnung;
      …

Die im Codeausschnitt genannte Basisklasse kapselt einige allgemeine Methoden wie getId, equals und hashCode. Zudem ermöglicht sie die bequeme Formulierung von DB-Zugriffsklassen, wie weiter unten gezeigt wird.

Beim Vergleich der alten Klassen und XML-Deskriptoren mit den neuen JPA-Beans fällt auf, dass die Namen und Typen der Attribute aus der jeweiligen alten Implementierungsklasse entnommen werden können. Weiterhin sind die Namen der Datenbank-Spalten im bisherigen Toplink-Deskriptor „versteckt“.

Den Datenbankzugriff übernimmt künftig eine CDI-Bean:

 
@ApplicationScoped
@Transactional
public class WerkstoffRepository 
      extends StandardRepository<Long, Werkstoff> {
  public Werkstoff findByVariante(Integer variante)
  {
    TypedQuery<Werkstoff> query = this.entityManager.createQuery(
        "SELECT OBJECT(werkstoff) FROM Werkstoff x "
          + "WHERE x.variante = ?1", Werkstoff.class);
    query.setParameter(1, variante);
    return query.getSingleResult();
  }
      …

Auch hier läßt sich geschickt eine Basisklasse passend zur oben genutzten SingleIdEntity<K> nutzen. Sie stellt eine injizierte EntityManager-Instanz zur Verfügung und enthält die üblichen CRUD-Methoden:

public abstract class SingleIdEntityRepository
      <K, E extends SingleIdEntity<K>> {
  @Inject
  protected EntityManager entityManager;

      public void persist(E entity) {
    this.entityManager.persist(entity);
  }
      …

Im Vergleich Alt vs. Neu erkennt man, dass die Query-Texte aus dem Toplink-Deskriptor zur Formulierung der neuen JPA-Queries heragezogen werden können.

Insgesamt waren also die Detaildaten zur Erzeugung der neuen Persistenzschicht im alten Code vorhanden, allerdings verteilt in Java- und XML-Fragmenten.

Codegenerator

Die beschriebenen Parallelitäten zwischen der betagten Software und dem Migrationsziel ließ die Annahme reifen, dass eine zumindest teilweise automatische Umstellung ein gangbarer Weg sein würde. Wir entwickelten daraufhin einen Codegenerator, der mit Hilfe von Reflection die notwendigen Metadaten aus den alten Klassen und Interfaces entnimmt und weitere Daten aus den Deskriptoren mittels XML Parser, DOM, XPath & Co. extrahiert.

Damit gelang es tatsächlich, in recht kurzer Zeit einen ganz wesentlichen Teil der neuen Persistenzschicht zu generieren. Das Ziel war bewußt nicht so gewählt, dass auch sämtliche Spezialfälle vom Generator abgewickelt werden sollten. Diese Sonderfälle ließen sich wirtschaftlich sinnvoller in überschaubarer manueller Nacharbeit behandeln.

(Zwischen-) Ergebnis

Mit dem beschriebenen Verfahren ließ sich eine der betroffenen Anwendungen erfolgreich auf die neue Plattform migrieren – sie läuft nun auf Java 8, Java EE 7 und WildFly 8. In der gleichen Weise setzen wir nun die weiteren Awendungen um, wobei wir von dem zuvor entwickelten Generator erneut und substanziell profitieren.

Dieser Artikel ist zuerst erschienen im GEDOPLAN Aktuell, Ausgabe Frühjahr 2015. GEDOPLAN IT Consulting unterstützt Sie gerne auch bei Ihren Migrationsprojekten.

Aufmacherbild: Big bang of future technologies von Shutterstock / Urheberrecht:  sakkmesterke

Verwandte Themen:

Geschrieben von
Dirk Weil
Dirk Weil
  Dirk Weil ist seit 1998 als Berater im Bereich Java tätig. Als Geschäftsführer der GEDOPLAN GmbH in Bielefeld ist er für die Konzeption und Realisierung von Informationssystemen auf Basis von Java EE verantwortlich. Seine langjährige Erfahrung in der Entwicklung anspruchsvoller Unternehmenslösungen machen ihn zu einem kompetenten Ansprechpartner und anerkannten Experten auf dem Gebiet Java EE. Er ist Autor in Fachmagazinen, hält Vorträge und leitet Seminare und Workshops aus einem eigenen Java-Curriculum.
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu: